I'm wondering how to do a permanent redirect 301 in Play framework 2.0.x for subdomains.
ex: www.example.com/* redirected to example.com/*. Anyone tried this before ?
The Global object will allow you to intercept the request. For obvious reasons you should do it with GET requests (ie. for SEO purposes), but others, like POST, PUT etc. should be created properly from the beginning in your views.
On the other hand, if it's just some app for serving common HTML pages for life production consider using some HTTP server on front of it - then you can do the trick with some rewriting rule.
import play.GlobalSettings;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
import java.lang.reflect.Method;
public class Global extends GlobalSettings {
#Override
public Action onRequest(final Http.Request request, Method method) {
if ("GET".equals(request.method()) && "www.example.com".equals(request.host())) {
return new Action.Simple() {
public Result call(Http.Context ctx) throws Throwable {
return movedPermanently("http://example.com" + request.path());
}
};
}
return super.onRequest(request, method);
}
}
In conf/routes file
GET / controllers.Application.index(path = "")
GET /*path controllers.Application.index(path)
In apps/controllers/Application.scala
object Application extends Controller {
def index(path: String) = Action {
Redirect("http://example.com/" + path, status = MOVED_PERMANENTLY)
}
}
Related
I have a situation where I have a mobile system that when it's on the road in will connect to symmetricDS via the default sync URL specified in the engines file. But when that device is back at home base, it ends up on the same internal network as the master symmetricDS server. So it cannot resolve the outside hostname from inside the network.
Anyway.... I want to setup an symmetricDS extension so that it can try the default URL and then fallback to a secondary IP of 192.168.0.5 if it doesn't work. This is the code snippet that I think I need to start with. I have never done any java, so I'm a little lost reading this.
import java.net.URI;
import org.jumpmind.symmetric.ISymmetricEngine;
import org.jumpmind.symmetric.transport.ISyncUrlExtension;
import org.jumpmind.symmetric.ext.ISymmetricEngineAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SyncUrlRewrite implements ISymmetricEngineAware, ISyncUrlExtension {
protected Logger log = LoggerFactory.getLogger(getClass());
ISymmetricEngine engine;
#Override
public String resolveUrl(URI url) {
return url.toString();
}
#Override
public void setSymmetricEngine(ISymmetricEngine engine) {
this.engine = engine;
}
}
You might try looking at and implementing the ISyncUrlExtension interface with the resolveUrl() method. To get it to work, configure the sync_url for a node with the protocol of ext://beanName. beanName is the name you give your extension point in the extension xml file.
Then, you can implement logic to have the resolveUrl() method parse, for example, a list of URLs for your mobile client to try in the sync_url string.
public String resolveUrl(URI uri) {
if (uri.toString().startsWith("ext")) {
Map<String, String> params = getParameters(uri);
//Do some logic with your parsed parameters and return a url
} else {
else return uri.toString();
}
}
The HttpBandwidthSelector class can give you an example implementation.
In my java code I call another 3rd party java class.
I want to catch that latter System.exit() exit code
So I use security-manager as suggested in this post
The problem is that I cannot read files now, I get permissions error
as seen in that post.
How can I catch the exit code and still read files?
Published class MyClass {
class MySecurityManager extends SecurityManager {
#Override
public void checkExit(int status) {
throw new SecurityException();
}
}
public void foo() {
MySecurityManager secManager = new MySecurityManager();
System.setSecurityManager(secManager);
try {
ConfigValidator.main(new String[]{"-dirs", SdkServiceConfig.s.PROPERTIES_FILE_PATH});
new FileInputStream(new File("/Users/eladb/WorkspaceQa/sdk-service/src/main/resources/convert_conditions.sh"));
} catch (SecurityException e) {
//Do something if the external code used System.exit()
String a = "1";
}
catch (Exception e) {
logger.error("failed converting properties file to proto", e);
}
}
}
You have two separate problems: Your trusted code cannot read the file, while the untrusted third-party library can still call System#exit unhindered. The former can be easily circumvented by granting further privileges to the trusted code; the latter is a tad trickier to address.
A bit of background
Privilege assignment
Code (the ProtectionDomains encapsulated by a thread's AccessControlContext) generally gets assigned Permissions in two ways: Statically, by the ClassLoader, upon class definition, and/or dynamically, by the Policy in effect. Other, less frequently encountered alternatives, exist as well: DomainCombiners, for instance, can modify AccessControlContexts' domains (and therefore the effective permissions of their respective code that is subject to authorization) on the fly, and custom domain implementations may use their own logic for permission implication, possibly disregarding or altering the semantics of the policy. By default the permission set of a domain is the union of its static and dynamic permissions. As for how exactly classes are mapped to domains, it is, for the most part, up to the loader's implementation. By default, all classes, JAR'ed or otherwise, residing beneath the same class path entry, are grouped under the same domain. More restrictive class loaders may choose to e.g. allocate a domain per class, which could be used to prevent communication even between classes within the same package.
Privilege evaluation
Under the default SecurityManager, for a privileged operation (an invocation of any method having a SecurityManager#checkXXX within its body) to succeed, every domain (of every class of every method) of the effective AccessControlContext must have been assigned, as explained above, the permission being checked. Recall however that the context need not necessarily represent "the truth" (the actual call stack)—system code gets optimized away early on, while AccessController#doPrivileged calls, along with the DomainCombiner potentially coupled to the AccessControlContext can modify the context's domains, and the authorization algorithm in its entirety, consequently.
Problem and workarounds
The issue with System#exit is that the corresponding permission (RuntimePermission("exitVM.*")) is one amongst few that are statically assigned by the default application class loader (sun.misc.Launcher$AppClassLoader) to all domains associated with classes loaded from the class path.
A number of alternatives come to mind:
Installing a custom SecurityManager which denies the particular right based on, e.g., the class attempting to terminate the JVM process.
Loading the third-party library from a "remote" location (a directory outside of the class path), so that it gets treated as "untrusted" code by its class loader.
Authoring and installing a different application class loader, which does not assign the extraneous permission.
Plugging a custom domain combiner into the access control context, which replaces, at the time of an authorization decision, all third-party domains with equivalent ones that do not have the offending permission.
I should, for the sake of completeness, note that at the Policy level, unfortunately, nothing can be done to negate statically assigned permissions.
The first option is overall the most convenient one, but I will not explore it further because:
The default SecurityManager is quite flexible, thanks to the handful of components (AccessController et al.) it interacts with. The background section in the beginning aimed to serve as a reminder of that flexibility, which "quick-n'-dirty" method overrides tend to cripple.
Careless modifications of the default implementation might cause (system) code to misbehave in curious ways.
Frankly, because it's boring―it's the one-size-fits-all solution perpetually advocated, while the fact that the default manager was standardized in 1.2 for a reason has long been forgotten.
The second alternative is easy to implement but impractical, complicating either development or the build process. Assuming you are not planning to invoke the library solely reflectively, or aided by interfaces present on the class path, it would have to be present initially, during development, and relocated before execution.
The third is, at least in the context of a standalone Java SE application, fairly straightforward and should not pose too much of a burden on performance. It is the approach I will favour herein.
The last option is the most novel and least convenient. It is hard to securely implement, has the greatest potential for performance degradation, and burdens client code with ensuring presence of the combiner prior to every delegation to untrusted code.
Proposed solution
The custom ClassLoader
The following is to be used as the replacement of the default application loader, or alternatively as the context class loader, or the loader used to load at least the untrusted classes. There is nothing novel to this implementation—all it does is prevent delegation to the default application class loader when the class in question is assumed to not be a system one. URLClassLoader#findClass, in turn, does not assign RuntimePermission("exitVM.*") to the domains of the classes it defines.
package com.example.trusted;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.regex.Pattern;
public class ClasspathClassLoader extends URLClassLoader {
private static final Pattern SYSTEM_CLASS_PREFIX = Pattern.compile("((java(x)?|sun|oracle)\\.).*");
public ClasspathClassLoader(ClassLoader parent) {
super(new URL[0], parent);
String[] classpath = System.getProperty("java.class.path").split(File.pathSeparator);
for (String classpathEntry : classpath) {
try {
if (!classpathEntry.endsWith(".jar") && !classpathEntry.endsWith("/")) {
// URLClassLoader assumes paths without a trailing '/' to be JARs by default
classpathEntry += "/";
}
addURL(new URL("file:" + classpathEntry));
}
catch (MalformedURLException mue) {
System.err.println(MessageFormat.format("Erroneous class path entry [{0}] skipped.", classpathEntry));
}
}
}
#Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class<?> ret;
synchronized (getClassLoadingLock(name)) {
ret = findLoadedClass(name);
if (ret != null) {
return ret;
}
if (SYSTEM_CLASS_PREFIX.matcher(name).matches()) {
return super.loadClass(name, resolve);
}
ret = findClass(name);
if (resolve) {
resolveClass(ret);
}
}
return ret;
}
}
If you also wish to fine-tune the domains assigned to loaded classes, you will additionally have to override findClass. The following variant of the loader is a very crude attempt at doing so. constructClassDomain therein merely creates one domain per class path entry (which is more or less the default), but can be modified to do something different.
package com.example.trusted;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public final class ClasspathClassLoader extends URLClassLoader {
private static final Pattern SYSTEM_CLASS_PREFIX = Pattern.compile("((java(x)?|sun|oracle)\\.).*");
private static final List<WeakReference<ProtectionDomain>> DOMAIN_CACHE = new ArrayList<>();
// constructor, loadClass same as above
#Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
URL classOrigin = getClassResource(name);
if (classOrigin == null) {
return super.findClass(name);
}
URL classCodeSourceOrigin = getClassCodeSourceResource(classOrigin);
if (classCodeSourceOrigin == null) {
return super.findClass(name);
}
return defineClass(name, readClassData(classOrigin), constructClassDomain(classCodeSourceOrigin));
}
private URL getClassResource(String name) {
return AccessController.doPrivileged((PrivilegedAction<URL>) () -> getResource(name.replace(".", "/") + ".class"));
}
private URL getClassCodeSourceResource(URL classResource) {
for (URL classpathEntry : getURLs()) {
if (classResource.getPath().startsWith(classpathEntry.getPath())) {
return classpathEntry;
}
}
return null;
}
private ByteBuffer readClassData(URL classResource) {
try {
BufferedInputStream in = new BufferedInputStream(classResource.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
int i;
while ((i = in.read()) != -1) {
out.write(i);
}
return ByteBuffer.wrap(out.toByteArray());
}
catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
private ProtectionDomain constructClassDomain(URL classCodeSourceResource) {
ProtectionDomain ret = getCachedDomain(classCodeSourceResource);
if (ret == null) {
CodeSource cs = new CodeSource(classCodeSourceResource, (Certificate[]) null);
DOMAIN_CACHE.add(new WeakReference<>(ret = new ProtectionDomain(cs, getPermissions(cs), this, null)));
}
return ret;
}
private ProtectionDomain getCachedDomain(URL classCodeSourceResource) {
for (WeakReference<ProtectionDomain> domainRef : DOMAIN_CACHE) {
ProtectionDomain domain = domainRef.get();
if (domain == null) {
DOMAIN_CACHE.remove(domainRef);
}
else if (domain.getCodeSource().implies(new CodeSource(classCodeSourceResource, (Certificate[]) null))) {
return domain;
}
}
return null;
}
}
The "unsafe" code
package com.example.untrusted;
public class Test {
public static void testExitVm() {
System.out.println("May I...?!");
System.exit(-1);
}
}
The entry point
package com.example.trusted;
import java.security.AccessControlException;
import java.security.Permission;
import com.example.untrusted.Test;
public class Main {
private static final Permission EXIT_VM_PERM = new RuntimePermission("exitVM.*");
public static void main(String... args) {
System.setSecurityManager(new SecurityManager());
try {
Test.testExitVm();
}
catch (AccessControlException ace) {
Permission deniedPerm = ace.getPermission();
if (EXIT_VM_PERM.implies(deniedPerm)) {
ace.printStackTrace();
handleUnauthorizedVmExitAttempt(Integer.parseInt(deniedPerm.getName().replace("exitVM.", "")));
}
}
}
private static void handleUnauthorizedVmExitAttempt(int exitCode) {
System.out.println("here let me do it for you");
System.exit(exitCode);
}
}
Testing
Packaging
Place the loader and the main class in one JAR (let's call it trusted.jar) and the demo untrusted class in another (untrusted.jar).
Assigning privileges
The default Policy (sun.security.provider.PolicyFile) is backed by the file at <JRE>/lib/security/java.policy, as well as any of the files referenced by the policy.url.n properties in <JRE>/lib/security/java.security. Modify the former (the latter should hopefully be empty by default) as follows:
// Standard extensions get all permissions by default
grant codeBase "file:${{java.ext.dirs}}/*" {
permission java.security.AllPermission;
};
// no default permissions
grant {};
// trusted code
grant codeBase "file:///path/to/trusted.jar" {
permission java.security.AllPermission;
};
// third-party code
grant codeBase "file:///path/to/untrusted.jar" {
permission java.lang.RuntimePermission "exitVM.-1", "";
};
Note that it is virtually impossible to get components extending the security infrastructure (custom class loaders, policy providers, etc.) to work properly without granting them AllPermission.
Running
Run:
java -classpath "/path/to/trusted.jar:/path/to/untrusted.jar" -Djava.system.class.loader=com.example.trusted.ClasspathClassLoader com.example.trusted.Main
The privileged operation should succeed.
Next comment out the RuntimePermission under untrusted.jar, within the policy file, and re-run. The privileged operation should fail.
As a closing note, when debugging AccessControlExceptions, running with -Djava.security.debug=access=domain,access=failure,policy can help track down offending domains and policy configuration issues.
This may be similar to 5660956, but I am doing a GET first...
I think the key here is Selenium, hence the tags.
Just in case it matters: I'm working in Java, using NinjaFramewor, FluentLenium and Firefox. It runs locally, but also on a headless CI box with Xvfb.
I have some FluentLenium tests passing, so the whole thing isn't broken!
I have a web page, with a simple login form that performs a call to JavaScript which does an AJAX POST. The AJAX response is caught by JavaScript and causes some of the body of the page to update, with different results for login, register and fail. I can see this happening when I test by hand, and even when I run these tests locally.
The test looks like this:
import org.fluentlenium.adapter.util.SharedDriver;
import org.fluentlenium.core.annotation.Page;
import org.junit.Test;
#SharedDriver(deleteCookies=true)
public class UserControllerTest extends JSTest {
#Page
HomePage home;
#Page
LoginPage login;
#Test
public void test_cantLoginUntilReg() {
goTo(login);
login.fillOutReg("test_cantLoginUntilReg");
login.chooseLogin(); // script that POSTS and does AJAX update
login.isErrorResult(); // errors
goTo(login);
login.fillOutReg("test_cantLoginUntilReg");
login.chooseRegister(); // script that POSTS and does AJAX update
login.isWelcomeResult(); // errors
login.chooseHome(); // GET on home
home.isLoggedIn(); // this works
}
// more tests
}
And the LoginPage, which is where I'm having trouble looks like (with a super class containing constants folded back in):
public class LoginPage extends FluentPage {
protected static final String HOME_PAGE = "http://localhost:8080";
private static final String PAGE = HOME_PAGE + "/login";
#AjaxElement
FluentWebElement welcomeDiv;
#AjaxElement
FluentWebElement errorDiv;
#Override
public String getUrl() {
return PAGE;
}
#Override
public void isAt() {
assertTrue("url is " + url(), url().contains("login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Register"));
}
public void isErrorResult() {
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Failed"));
assertNull("cookie is " + getCookie(SESSION_COOKIE_NAME), getCookie(SESSION_COOKIE_NAME));
}
public void fillOutReg(String testName) {
fill("#email").with(testName + "#UserControllerJSTests.test.com"); // this passes the minimal validation in place so far
fill("#password").with("reallyBadPassword");
fill("#identName").with(testName);
}
public void chooseLogin() {
executeScript(LOGIN_SCRIPT); // I'd prefer click on the form, but that seemed to be a source of trouble as well
}
// and so on
}
The isErrorResult() method is never satisfied!
The find h1 shows that the h1 text is still as it was when the page was first loaded.
Clearing the session cookie is showing different behaviour on different machines (probably needs to wait for something).
I've also tried testing the contents of welcomeDiv.
I have a feeling I ought to be able to use the #AjaxElement to help here, but I haven't quite worked out how.
I don't want to inspect the JSON coming back. I've got tests which don't involve Selenium that get pretty close to this already.
What I want to do is automate checking that the user will see the right thing at the browser end after a POST. Even if there is a work-around for this code, other functionality will have large enough uploads that GET really isn't sensible; and testable AJAX seems like a reasonable want.
Any ideas, please?
I have a working solution. As ever it a combination of changes got me to the place I want to be. In rough order of importance I think they are:
Only querying the state of a #Page once in any given test. The first test of Ajaxed content won. The subsequent ones found the wrong value.
Making the assert call to test that the ajax element is what it ought to be from the test object rather than within the page object. The broken version is commented out in the code below as this was unexpected.
Using #AjaxElement and then querying the content of those elements.
One web page had a missing id tag on the element I was looking for (wouldn't have accounted for all the problems).
Amongst other little changes along the way I am now testing heading h1 elements and list elements, rather than the div that contains them; and the different versions of the h1 have different id values. Haven't (yet) regression checked how significant this was.
The test code is now:
import org.fluentlenium.adapter.util.SharedDriver;
import org.fluentlenium.core.annotation.Page;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
#SharedDriver(deleteCookies=true)
public class UserControllerTest extends JSTest {
#Page
HomePage home;
#Page
LoginPage login;
#Test
public void test_cantLoginBeforeReg() {
// try to login without being registered
goTo(login);
login.fillOutReg("test_cantLoginUntilReg");
login.chooseLogin();
isErrorResult();
goTo(home);
home.isNotLoggedIn();
}
#Test
public void test_registerLogout() {
goTo(login);
login.fillOutReg("test_registerLogout");
login.chooseRegister();
isWelcomeResult();
login.chooseLogout();
home.isAt();
home.isNotLoggedIn();
}
// tests etc
public void isWelcomeResult() {
assertTrue(login.getWelcomeText(), login.getWelcomeText().contains("Welcome"));
}
public void isErrorResult() {
assertTrue(login.getErrorText(), login.getErrorText().contains("Failed"));
}
}
And the page class:
import org.fluentlenium.core.annotation.AjaxElement;
import org.fluentlenium.core.domain.FluentWebElement;
import static org.junit.Assert.assertTrue;
public class LoginPage extends TripVisPage {
private static final String PAGE = HOME_PAGE + "/login";
#AjaxElement
FluentWebElement welcomeHeading;
#AjaxElement
FluentWebElement errorHeading;
#Override
public String getUrl() {
return PAGE;
}
public String getWelcomeText() {
return welcomeHeading.getText();
}
public String getErrorText() {
return errorHeading.getText();
}
#Override
public void isAt() {
assertTrue("url is " + url(), url().contains("login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Register"));
}
/* calling these from the test is broken
public void isWelcomeResult() {
assertTrue(getWelcomeText(), getWelcomeText().contains("Welcome"));
}
public void isErrorResult() {
assertTrue(getErrorText(), getErrorText().contains("Failed"));
}
*/
public void fillOutReg(String testName) {
fill("#email").with(testName + "#UserControllerJSTests.tripvis.co.uk");
fill("#password").with("reallyBadPassword");
fill("#identName").with(testName);
}
public void chooseAbout() {
click(LINK_ABOUT_ID);
}
public void chooseLegal() {
click(LINK_LEGAL_ID);
}
public void chooseRegister() {
executeScript(REGISTER_SCRIPT);
}
public void chooseLogin() {
executeScript(LOGIN_SCRIPT);
}
public void chooseLogout() {
click(LINK_LOGOUT_ID);
}
}
I am using Play 2.2.1.
In my Global class I have the onError()-method overridden like this:
public Promise<SimpleResult> onError(RequestHeader request, Throwable t) {
Logger.info("onError reached");
return Promise.<SimpleResult>pure(internalServerError(t.getMessage()));
}
Thus my code is only slightly modified compared to the documentation.
After an exception occurs, it appears in the logging and the "onError reached" is also logged. Nevertheless it seems that the Result is never sent to the client as it is still waiting for an answer.
How do I send the internalServerError-Result back to the client if an error occured?
As a workaround I do the following:
public static Result someAction() {
try{
...
} catch (Exception ex) {
Logger.error(ex.getMessage(), ex);
return internalServerError(ex.getMessage());
}
}
I would really like to avoid that, because I think it's ugly, but at least it seems to work. Are there any possible problems (except that it has to be repeated for every Action) with that approach?
Just rechecked and it worked for me.
One minor issue I noticed - your return statement in onError lacks a closing brace, but I suppose it is not the issue since your code compiles.
Here's my working code:
controller:
package controllers;
import play.mvc.*;
public class Application extends Controller {
public static Result index() {
throw new RuntimeException("boom!");
}
}
Global:
import play.GlobalSettings;
import play.Logger;
import play.libs.F.Promise;
import play.mvc.Http.RequestHeader;
import play.mvc.Results;
import play.mvc.SimpleResult;
public class Global extends GlobalSettings {
public Promise<SimpleResult> onError(RequestHeader request, Throwable t) {
Logger.info("onError reached");
return Promise.<SimpleResult> pure(Results.internalServerError(t.getMessage()));
}
}
I have a java we application that is working with velocity. I get two variables in the first page via url that I extract using ureq.getParameter() method. One of the other classes that has a velocity container and I need to send one of the variables from the url to this velocity container. I tried creating an instance of the first class in the second class and using getVariable name method to do that but it did not work. Can someone tell me how I can do this?
Class 1:
package org.olat.dispatcher;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.olat.core.gui.UserRequest;
public class RemoteLoginformDispatcher implements Dispatcher {
private static final String PARAM_newUrl = "ret";
private static String newURL;
#Override
public void execute(
final HttpServletRequest request,
final HttpServletResponse response,
final String uriPrefix) {
UserRequest ureq = null;
try {
ureq = new UserRequest(uriPrefix, request, response);
newURL = ureq.getParameter(PARAM_newUrl);
} catch () {
}
}
public String getURL(){
return newURL;
}
}
Class 2:
public class BaseChiefController extends DefaultChiefController implements ContentableChiefController {
//Velocity container mainvc created here. It interacts with a html file. Removed the code that would not really matter
//mainvc.contextPut("newURL", "something");
//The below statement works. When I try with something, the something appears in the html file.
mainvc.contextPut("newURL", myLogin.getURL());
}
To create an instance of another class, simply create a "public CLASSNAME" method, and inside define all class variables with the "this" modfier. Then, call out the function you wish to use from that method, and when you want to use the class, just do "new CLASSNAME(args);"
Although, I am not really sure I am understanding your question.
Maybe this is your answer. You can use variables from one class to another class by making the variable static, then doing "CLASSNAME.VARIABLENAME = WHATEVER".
EDITED:
Okay, so as far as I can tell, you are using a method to return a static value from the class, which is much slower than just doing "newURL", RemoteLoginformDispatcher.newURL);.
Why not try this, as it is probably faster, and it should always work if newURL is defined. Otherwise, you have a different problem, and newURL is not being defined. If this is the case, try printing the caught Exception.