From: <rb...@us...> - 2013-06-20 20:17:27
|
Revision: 8351 http://sourceforge.net/p/htmlunit/code/8351 Author: rbri Date: 2013-06-20 20:17:23 +0000 (Thu, 20 Jun 2013) Log Message: ----------- rename the enum members to match the w3c spec naming; remove some error log for cases that are valid from the spec Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/gae/GAELoadPageTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest3Test.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequestTest.java Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java 2013-06-20 15:52:53 UTC (rev 8350) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest.java 2013-06-20 20:17:23 UTC (rev 8351) @@ -86,6 +86,7 @@ * @author Stuart Begg * @author Ronald Brill * + * @see <a href="http://www.w3.org/TR/XMLHttpRequest/">W3C XMLHttpRequest</a> * @see <a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html">Safari documentation</a> */ @JsxClass(browsers = { @WebBrowser(value = IE, minVersion = 7), @WebBrowser(FF), @WebBrowser(CHROME) }) @@ -94,15 +95,15 @@ private static final Log LOG = LogFactory.getLog(XMLHttpRequest.class); /** The object has been created, but not initialized (the open() method has not been called). */ - public static final int STATE_UNINITIALIZED = 0; + public static final int STATE_UNSENT = 0; /** The object has been created, but the send() method has not been called. */ - public static final int STATE_LOADING = 1; + public static final int STATE_OPENED = 1; /** The send() method has been called, but the status and headers are not yet available. */ - public static final int STATE_LOADED = 2; + public static final int STATE_HEADERS_RECEIVED = 2; /** Some data has been received. */ - public static final int STATE_INTERACTIVE = 3; + public static final int STATE_LOADING = 3; /** All the data has been received; the complete data is available in responseBody and responseText. */ - public static final int STATE_COMPLETED = 4; + public static final int STATE_DONE = 4; private static final String[] ALL_PROPERTIES_ = {"onreadystatechange", "readyState", "responseText", "responseXML", "status", "statusText", "abort", "getAllResponseHeaders", "getResponseHeader", "open", "send", @@ -138,7 +139,7 @@ */ public XMLHttpRequest(final boolean caseSensitiveProperties) { caseSensitiveProperties_ = caseSensitiveProperties; - state_ = STATE_UNINITIALIZED; + state_ = STATE_UNSENT; } /** @@ -165,7 +166,7 @@ @JsxSetter public void setOnreadystatechange(final Function stateChangeHandler) { stateChangeHandler_ = stateChangeHandler; - if (state_ == STATE_LOADING) { + if (state_ == STATE_OPENED) { setState(state_, null); } } @@ -183,14 +184,14 @@ // Firefox doesn't trigger onreadystatechange handler for sync requests except for completed for FF10 final boolean noTriggerForSync = browser.hasFeature( XHR_ONREADYSTATECANGE_SYNC_REQUESTS_NOT_TRIGGERED); - final boolean triggerForSyncCompleted = (state == STATE_COMPLETED) + final boolean triggerForSyncCompleted = (state == STATE_DONE) && browser.hasFeature(XHR_ONREADYSTATECANGE_SYNC_REQUESTS_COMPLETED); if (stateChangeHandler_ != null && (async_ || !noTriggerForSync || triggerForSyncCompleted)) { final Scriptable scope = stateChangeHandler_.getParentScope(); final JavaScriptEngine jsEngine = containingPage_.getWebClient().getJavaScriptEngine(); final int nbExecutions; - if (async_ && STATE_LOADING == state) { + if (async_ && STATE_OPENED == state) { // quite strange but IE and FF seem both to fire state loading twice // in async mode (at least with HTML of the unit tests) nbExecutions = 2; @@ -230,7 +231,7 @@ // Firefox has a separate onload handler, too. final boolean triggerOnload = browser.hasFeature(XHR_TRIGGER_ONLOAD_ON_COMPLETED); - if (triggerOnload && loadHandler_ != null && state == STATE_COMPLETED) { + if (triggerOnload && loadHandler_ != null && state == STATE_DONE) { final Scriptable scope = loadHandler_.getParentScope(); final JavaScriptEngine jsEngine = containingPage_.getWebClient().getJavaScriptEngine(); jsEngine.callFunction(containingPage_, loadHandler_, scope, this, ArrayUtils.EMPTY_OBJECT_ARRAY); @@ -376,10 +377,14 @@ */ @JsxGetter public int getStatus() { + if (state_ == STATE_UNSENT || state_ == STATE_OPENED) { + return 0; + } if (webResponse_ != null) { return webResponse_.getStatusCode(); } - LOG.error("XMLHttpRequest.status was retrieved before the response was available."); + + LOG.error("XMLHttpRequest.status was retrieved without a response available."); return 0; } @@ -389,10 +394,14 @@ */ @JsxGetter public String getStatusText() { + if (state_ == STATE_UNSENT || state_ == STATE_OPENED) { + return ""; + } if (webResponse_ != null) { return webResponse_.getStatusMessage(); } - LOG.error("XMLHttpRequest.statusText was retrieved before the response was available."); + + LOG.error("XMLHttpRequest.statusText was retrieved without a response available."); return null; } @@ -410,6 +419,9 @@ */ @JsxFunction public String getAllResponseHeaders() { + if (state_ == STATE_UNSENT || state_ == STATE_OPENED) { + return null; + } if (webResponse_ != null) { final StringBuilder buffer = new StringBuilder(); for (final NameValuePair header : webResponse_.getResponseHeaders()) { @@ -417,7 +429,8 @@ } return buffer.toString(); } - LOG.error("XMLHttpRequest.getAllResponseHeaders() was called before the response was available."); + + LOG.error("XMLHttpRequest.getAllResponseHeaders() was called without a response available."); return null; } @@ -428,10 +441,14 @@ */ @JsxFunction public String getResponseHeader(final String headerName) { + if (state_ == STATE_UNSENT || state_ == STATE_OPENED) { + return null; + } if (webResponse_ != null) { return webResponse_.getResponseHeaderValue(headerName); } + LOG.error("XMLHttpRequest.getAllResponseHeaders(..) was called without a response available."); return null; } @@ -500,7 +517,7 @@ // Async stays a boolean. async_ = async; // Change the state! - setState(STATE_LOADING, null); + setState(STATE_OPENED, null); } /** @@ -611,7 +628,7 @@ private void doSend(final Context context) { final WebClient wc = getWindow().getWebWindow().getWebClient(); try { - setState(STATE_LOADED, context); + setState(STATE_HEADERS_RECEIVED, context); final boolean crossOriginResourceSharing = webRequest_.getAdditionalHeaders().get("Origin") != null; if (crossOriginResourceSharing && isPreflight()) { final WebRequest preflightRequest = new WebRequest(webRequest_.getUrl(), HttpMethod.OPTIONS); @@ -632,8 +649,8 @@ preflightRequest.setAdditionalHeader("Access-Control-Request-Headers", builder.toString()); final WebResponse preflightResponse = wc.loadWebResponse(preflightRequest); if (!isPreflightAuthorized(preflightResponse)) { - setState(STATE_INTERACTIVE, context); - setState(STATE_COMPLETED, context); + setState(STATE_LOADING, context); + setState(STATE_DONE, context); if (LOG.isDebugEnabled()) { LOG.debug("No permitted request for URL " + webRequest_.getUrl()); } @@ -665,8 +682,8 @@ }; } } - setState(STATE_INTERACTIVE, context); - setState(STATE_COMPLETED, context); + setState(STATE_LOADING, context); + setState(STATE_DONE, context); if (!allowOriginResponse) { if (LOG.isDebugEnabled()) { LOG.debug("No permitted \"Access-Control-Allow-Origin\" header for URL " + webRequest_.getUrl()); @@ -679,7 +696,7 @@ LOG.debug("IOException: returning a network error response.", e); } webResponse_ = new NetworkErrorWebResponse(webRequest_); - setState(STATE_COMPLETED, context); + setState(STATE_DONE, context); if (async_) { processError(context); } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/gae/GAELoadPageTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/gae/GAELoadPageTest.java 2013-06-20 15:52:53 UTC (rev 8350) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/gae/GAELoadPageTest.java 2013-06-20 20:17:23 UTC (rev 8351) @@ -113,12 +113,12 @@ client.getPage(FIRST_URL); final int executedJobs = client.getJavaScriptEngine().pumpEventLoop(1000); - final String[] alerts = {String.valueOf(XMLHttpRequest.STATE_UNINITIALIZED), + final String[] alerts = {String.valueOf(XMLHttpRequest.STATE_UNSENT), + String.valueOf(XMLHttpRequest.STATE_OPENED), + String.valueOf(XMLHttpRequest.STATE_OPENED), + String.valueOf(XMLHttpRequest.STATE_HEADERS_RECEIVED), String.valueOf(XMLHttpRequest.STATE_LOADING), - String.valueOf(XMLHttpRequest.STATE_LOADING), - String.valueOf(XMLHttpRequest.STATE_LOADED), - String.valueOf(XMLHttpRequest.STATE_INTERACTIVE), - String.valueOf(XMLHttpRequest.STATE_COMPLETED), xml}; + String.valueOf(XMLHttpRequest.STATE_DONE), xml}; assertEquals(Arrays.asList(alerts).toString(), collectedAlerts.toString()); assertEquals(1, executedJobs); } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest3Test.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest3Test.java 2013-06-20 15:52:53 UTC (rev 8350) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequest3Test.java 2013-06-20 20:17:23 UTC (rev 8351) @@ -64,11 +64,11 @@ private static final String MSG_NO_CONTENT = "no Content"; private static final String MSG_PROCESSING_ERROR = "error processing"; - private static final String UNINITIALIZED = String.valueOf(XMLHttpRequest.STATE_UNINITIALIZED); - private static final String LOADING = String.valueOf(XMLHttpRequest.STATE_LOADING); - private static final String LOADED = String.valueOf(XMLHttpRequest.STATE_LOADED); - private static final String INTERACTIVE = String.valueOf(XMLHttpRequest.STATE_INTERACTIVE); - private static final String COMPLETED = String.valueOf(XMLHttpRequest.STATE_COMPLETED); + private static final String UNINITIALIZED = String.valueOf(XMLHttpRequest.STATE_UNSENT); + private static final String LOADING = String.valueOf(XMLHttpRequest.STATE_OPENED); + private static final String LOADED = String.valueOf(XMLHttpRequest.STATE_HEADERS_RECEIVED); + private static final String INTERACTIVE = String.valueOf(XMLHttpRequest.STATE_LOADING); + private static final String COMPLETED = String.valueOf(XMLHttpRequest.STATE_DONE); /** * Tests asynchronous use of XMLHttpRequest, using Mozilla style object creation. Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequestTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequestTest.java 2013-06-20 15:52:53 UTC (rev 8350) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XMLHttpRequestTest.java 2013-06-20 20:17:23 UTC (rev 8351) @@ -52,9 +52,9 @@ @RunWith(BrowserRunner.class) public class XMLHttpRequestTest extends WebDriverTestCase { - private static final String UNINITIALIZED = String.valueOf(XMLHttpRequest.STATE_UNINITIALIZED); - private static final String LOADING = String.valueOf(XMLHttpRequest.STATE_LOADING); - private static final String COMPLETED = String.valueOf(XMLHttpRequest.STATE_COMPLETED); + private static final String UNINITIALIZED = String.valueOf(XMLHttpRequest.STATE_UNSENT); + private static final String LOADING = String.valueOf(XMLHttpRequest.STATE_OPENED); + private static final String COMPLETED = String.valueOf(XMLHttpRequest.STATE_DONE); /** * Tests synchronous use of XMLHttpRequest. @@ -126,6 +126,60 @@ } /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"0-", "0-" }) + public void statusBeforeSend() throws Exception { + final String html = + "<html>\n" + + " <head>\n" + + " <title>XMLHttpRequest Test</title>\n" + + " <script>\n" + + " var request;\n" + + " if (window.XMLHttpRequest)\n" + + " request = new XMLHttpRequest();\n" + + " else if (window.ActiveXObject)\n" + + " request = new ActiveXObject('Microsoft.XMLHTTP');\n" + + + " alert(request.status + '-' + request.statusText);\n" + + " request.open('GET', '/foo.xml', false);\n" + + " alert(request.status + '-' + request.statusText);\n" + + " </script>\n" + + " </head>\n" + + " <body></body>\n" + + "</html>"; + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"null", "null" }) + public void responseHeaderBeforeSend() throws Exception { + final String html = + "<html>\n" + + " <head>\n" + + " <title>XMLHttpRequest Test</title>\n" + + " <script>\n" + + " var request;\n" + + " if (window.XMLHttpRequest)\n" + + " request = new XMLHttpRequest();\n" + + " else if (window.ActiveXObject)\n" + + " request = new ActiveXObject('Microsoft.XMLHTTP');\n" + + + " alert(request.getResponseHeader('content-length'));\n" + + " request.open('GET', '/foo.xml', false);\n" + + " alert(request.getResponseHeader('content-length'));\n" + + " </script>\n" + + " </head>\n" + + " <body></body>\n" + + "</html>"; + loadPageWithAlerts2(html); + } + + /** * Regression test for http://sourceforge.net/tracker/index.php?func=detail&aid=1209692&group_id=47038&atid=448266. * @throws Exception if the test fails */ |