Fixes issue #1345; calling XHR.open() with null arguments for user and password would cause a "null"/"null" login to be sent to the server on Opera. The fix is to only pass exactly as many arguments to open() as matter. I made three different overloads for the JSNI methods because in most cases (no auth) the compiler will be able to optimize out the 4 and 5 arg versions.
Found by: joerg.baumann
Review by: mmendez
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1262 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/http/client/RequestBuilder.java b/user/src/com/google/gwt/http/client/RequestBuilder.java
index 1daefaa..5d57570 100644
--- a/user/src/com/google/gwt/http/client/RequestBuilder.java
+++ b/user/src/com/google/gwt/http/client/RequestBuilder.java
@@ -157,12 +157,26 @@
*/
public Request sendRequest(String requestData, RequestCallback callback)
throws RequestException {
- JavaScriptObject xmlHttpRequest = httpRequest.createXmlHTTPRequest();
- String openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url,
- true, user, password);
+ if (user == null && password != null) {
+ throw new IllegalStateException("A password is set, but no user is set");
+ }
+
+ JavaScriptObject xmlHttpRequest = httpRequest.createXmlHTTPRequest();
+ String openError;
+ if (password != null) {
+ openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true,
+ user, password);
+ } else if (user != null) {
+ openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true,
+ user);
+ } else {
+ openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true);
+ }
if (openError != null) {
- throw new RequestPermissionException(url);
+ RequestPermissionException requestPermissionException = new RequestPermissionException(url);
+ requestPermissionException.initCause(new RequestException(openError));
+ throw requestPermissionException;
}
setHeaders(xmlHttpRequest);
diff --git a/user/src/com/google/gwt/http/client/XMLHTTPRequest.java b/user/src/com/google/gwt/http/client/XMLHTTPRequest.java
index 48e7374..53898e7 100644
--- a/user/src/com/google/gwt/http/client/XMLHTTPRequest.java
+++ b/user/src/com/google/gwt/http/client/XMLHTTPRequest.java
@@ -168,6 +168,49 @@
* @param httpMethod the method to use for open call
* @param url the URL to use for the open call
* @param async true if we should do an asynchronous open
+ * @return error message if an exception is thrown or null if there is none
+ */
+ static native String open(JavaScriptObject xmlHttpRequest, String httpMethod,
+ String url, boolean async) /*-{
+ try {
+ xmlHttpRequest.open(httpMethod, url, async);
+ return null;
+ } catch (e) {
+ return e.message;
+ }
+ }-*/;
+
+ /**
+ * Opens the request and catches any exceptions thrown. If an exception is
+ * caught, its string representation will be returned. This is the only signal
+ * that an error has occurred.
+ *
+ * @param xmlHttpRequest JavaScript <code>XmlHttpRequest</code> object
+ * @param httpMethod the method to use for open call
+ * @param url the URL to use for the open call
+ * @param async true if we should do an asynchronous open
+ * @param user user to use in the URL
+ * @return error message if an exception is thrown or null if there is none
+ */
+ static native String open(JavaScriptObject xmlHttpRequest, String httpMethod,
+ String url, boolean async, String user) /*-{
+ try {
+ xmlHttpRequest.open(httpMethod, url, async, user);
+ return null;
+ } catch (e) {
+ return e.message;
+ }
+ }-*/;
+
+ /**
+ * Opens the request and catches any exceptions thrown. If an exception is
+ * caught, its string representation will be returned. This is the only signal
+ * that an error has occurred.
+ *
+ * @param xmlHttpRequest JavaScript <code>XmlHttpRequest</code> object
+ * @param httpMethod the method to use for open call
+ * @param url the URL to use for the open call
+ * @param async true if we should do an asynchronous open
* @param user user to use in the URL
* @param password password to use in the URL
* @return error message if an exception is thrown or null if there is none
@@ -178,7 +221,7 @@
xmlHttpRequest.open(httpMethod, url, async, user, password);
return null;
} catch (e) {
- return e.toString();
+ return e.message;
}
}-*/;
@@ -199,7 +242,7 @@
return null;
} catch (e) {
xmlHttpRequest.onreadystatechange = @com.google.gwt.user.client.impl.HTTPRequestImpl::nullFunc;
- return e.toString();
+ return e.message;
}
}-*/;
@@ -209,7 +252,7 @@
xmlHttpRequest.setRequestHeader(header, value);
return null;
} catch (e) {
- return e.toString();
+ return e.message;
}
}-*/;
diff --git a/user/test/com/google/gwt/http/client/RequestBuilderTest.java b/user/test/com/google/gwt/http/client/RequestBuilderTest.java
index b8e1ff8..7e42770 100644
--- a/user/test/com/google/gwt/http/client/RequestBuilderTest.java
+++ b/user/test/com/google/gwt/http/client/RequestBuilderTest.java
@@ -19,7 +19,7 @@
import com.google.gwt.junit.client.GWTTestCase;
/**
- * HTTPRequestBuilder tests
+ * HTTPRequestBuilder tests.
*/
public class RequestBuilderTest extends GWTTestCase {
private static final int TEST_FINISH_DELAY = 10000;
@@ -55,9 +55,9 @@
* <li>url == "www.freebsd.org" - violates same source
* </ul>
*/
- public void testRequestBuilderStringString() {
+ public void testRequestBuilderStringString() throws RequestException {
try {
- RequestBuilder builder = new RequestBuilder((RequestBuilder.Method) null,
+ new RequestBuilder((RequestBuilder.Method) null,
null);
fail("NullPointerException should have been thrown for construction with null method.");
} catch (NullPointerException ex) {
@@ -65,14 +65,14 @@
}
try {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, null);
+ new RequestBuilder(RequestBuilder.GET, null);
fail("NullPointerException should have been thrown for construction with null URL.");
} catch (NullPointerException ex) {
// purposely ignored
}
try {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "");
+ new RequestBuilder(RequestBuilder.GET, "");
fail("IllegalArgumentException should have been throw for construction with empty URL.");
} catch (IllegalArgumentException ex) {
// purposely ignored
@@ -96,8 +96,6 @@
// purposely ignored
} catch (RequestPermissionException ex) {
// this is the type of exception that we expect
- } catch (RequestException e) {
- fail(e.getMessage());
}
}
@@ -106,70 +104,58 @@
* {@link com.google.gwt.http.client.RequestBuilder#RequestBuilder(java.lang.String, java.lang.String)}. *
*/
public void testRequestBuilderStringString_HTTPMethodRestrictionOverride() {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "FOO");
+ new RequestBuilder(RequestBuilder.GET, "FOO");
- try {
- class MyRequestBuilder extends RequestBuilder {
- MyRequestBuilder(String httpMethod, String url) {
- super(httpMethod, url);
- }
- };
+ class MyRequestBuilder extends RequestBuilder {
+ MyRequestBuilder(String httpMethod, String url) {
+ super(httpMethod, url);
+ }
+ };
- builder = new MyRequestBuilder("HEAD", "FOO");
- // should reach here without any exceptions being thrown
- } catch (IllegalArgumentException ex) {
- fail(ex.getMessage());
- }
+ new MyRequestBuilder("HEAD", "FOO");
+ // should reach here without any exceptions being thrown
}
/**
* Test method for
* {@link com.google.gwt.http.client.RequestBuilder#sendRequest(java.lang.String, com.google.gwt.http.client.RequestCallback)}.
*/
- public void testSendRequest_GET() {
+ public void testSendRequest_GET() throws RequestException {
delayTestFinish(TEST_FINISH_DELAY);
- try {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- getTestBaseURL() + "sendRequest_GET");
- builder.sendRequest(null, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- fail();
- }
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ getTestBaseURL() + "sendRequest_GET");
+ builder.sendRequest(null, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ fail();
+ }
- public void onResponseReceived(Request request, Response response) {
- assertEquals(200, response.getStatusCode());
- finishTest();
- }
- });
- } catch (RequestException e) {
- fail(e.getMessage());
- }
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ finishTest();
+ }
+ });
}
/**
* Test method for
* {@link com.google.gwt.http.client.RequestBuilder#sendRequest(java.lang.String, com.google.gwt.http.client.RequestCallback)}.
*/
- public void testSendRequest_POST() {
+ public void testSendRequest_POST() throws RequestException {
delayTestFinish(TEST_FINISH_DELAY);
- try {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
- getTestBaseURL() + "sendRequest_POST");
- builder.sendRequest("method=test+request", new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- fail("HTTPRequest timed out");
- }
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
+ getTestBaseURL() + "sendRequest_POST");
+ builder.sendRequest("method=test+request", new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ fail("HTTPRequest timed out");
+ }
- public void onResponseReceived(Request request, Response response) {
- assertEquals(200, response.getStatusCode());
- finishTest();
- }
- });
- } catch (RequestException e) {
- fail(e.getMessage());
- }
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ finishTest();
+ }
+ });
}
public void testSetPassword() {
@@ -201,7 +187,7 @@
* <li>value == ""
* </ul>
*/
- public void testSetRequestHeader() {
+ public void testSetRequestHeader() throws RequestException {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
getTestBaseURL() + "setRequestHeader");
@@ -235,25 +221,21 @@
delayTestFinish(TEST_FINISH_DELAY);
- try {
- builder = new RequestBuilder(RequestBuilder.GET, getTestBaseURL()
- + "setRequestHeader");
- builder.setHeader("Foo", "Bar");
- builder.setHeader("Foo", "Bar1");
+ builder = new RequestBuilder(RequestBuilder.GET, getTestBaseURL()
+ + "setRequestHeader");
+ builder.setHeader("Foo", "Bar");
+ builder.setHeader("Foo", "Bar1");
- builder.sendRequest(null, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- fail("HTTPRequest timed out");
- }
+ builder.sendRequest(null, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ fail("HTTPRequest timed out");
+ }
- public void onResponseReceived(Request request, Response response) {
- assertEquals(200, response.getStatusCode());
- finishTest();
- }
- });
- } catch (RequestException e) {
- fail(e.getMessage());
- }
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ finishTest();
+ }
+ });
}
/**
@@ -267,26 +249,22 @@
* <li>Timeout is less than the server's response time
* </ul>
*/
- public void testSetTimeout_noTimeout() {
+ public void testSetTimeout_noTimeout() throws RequestException {
delayTestFinish(TEST_FINISH_DELAY);
- try {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- getTestBaseURL() + "setTimeout/noTimeout");
- builder.setTimeoutMillis(10000);
- builder.sendRequest(null, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- fail("Test timed out");
- }
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ getTestBaseURL() + "setTimeout/noTimeout");
+ builder.setTimeoutMillis(10000);
+ builder.sendRequest(null, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ fail("Test timed out");
+ }
- public void onResponseReceived(Request request, Response response) {
- assertEquals(200, response.getStatusCode());
- finishTest();
- }
- });
- } catch (RequestException e) {
- fail(e.getMessage());
- }
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ finishTest();
+ }
+ });
}
/**
@@ -300,26 +278,22 @@
* <li>Timeout is less than the server's response time
* </ul>
*/
- public void testSetTimeout_timeout() {
+ public void testSetTimeout_timeout() throws RequestException {
delayTestFinish(TEST_FINISH_DELAY);
- try {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- getTestBaseURL() + "setTimeout/timeout");
- builder.setTimeoutMillis(2000);
- builder.sendRequest(null, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- finishTest();
- }
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ getTestBaseURL() + "setTimeout/timeout");
+ builder.setTimeoutMillis(2000);
+ builder.sendRequest(null, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ finishTest();
+ }
- public void onResponseReceived(Request request, Response response) {
- assertEquals(200, response.getStatusCode());
- fail("Test did not timeout");
- }
- });
- } catch (RequestException e) {
- fail(e.getMessage());
- }
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ fail("Test did not timeout");
+ }
+ });
}
public void testSetUser() {