API Reference 0.3.24dart_web_toolkit_httpRequest

Request class

An HTTP request that is waiting for a response. Requests can be queried for their pending status or they can be canceled.

Required Module

Modules that use this class should inherit com.google.gwt.http.HTTP.

{@gwt.include com/google/gwt/examples/http/InheritsExample.gwt.xml}

class Request {

 /**
  * Creates a {@link Response} instance for the given JavaScript XmlHttpRequest
  * object.
  *
  * @param xmlHttpRequest xmlHttpRequest object for which we need a response
  * @return a {@link Response} object instance
  */
 static Response createResponse(dart_html.HttpRequest xmlHttpRequest) {
   assert (isResponseReady(xmlHttpRequest));
   Response response = new _Response(xmlHttpRequest);
   return response;
 }

 /**
  * Returns an array of headers built by parsing the string of headers returned
  * by the JavaScript <code>XmlHttpRequest</code> object.
  *
  * @param xmlHttpRequest
  * @return array of Header items
  */
 static List<Header> getHeaders(dart_html.HttpRequest xmlHttp) {
   String allHeaders = xmlHttp.getAllResponseHeaders();
   List<String> unparsedHeaders = allHeaders.split("\n");
   List<Header> parsedHeaders = new List<Header>(unparsedHeaders.length);

   for (int i = 0, n = unparsedHeaders.length; i < n; ++i) {
     String unparsedHeader = unparsedHeaders[i];

     if (unparsedHeader.length == 0) {
       continue;
     }

     int endOfNameIdx = unparsedHeader.indexOf(':');
     if (endOfNameIdx < 0) {
       continue;
     }

     String name = unparsedHeader.substring(0, endOfNameIdx).trim();
     String value = unparsedHeader.substring(endOfNameIdx + 1).trim();
     Header header = new _RequestHeader(name, value);

     parsedHeaders[i] = header;
   }

   return parsedHeaders;
 }

 static bool isResponseReady(dart_html.HttpRequest xhr) {
   return xhr.readyState == dart_html.HttpRequest.DONE;
 }


 /**
  * The number of milliseconds to wait for this HTTP request to complete.
  */
 int _timeoutMillis = 0;

 /*
  * Timer used to force HTTPRequest timeouts. If the user has not requested a
  * timeout then this field is null.
  */
 dart_async.Timer _timer;

 /*
  * JavaScript XmlHttpRequest object that this Java class wraps. This field is
  * not final because we transfer ownership of it to the HTTPResponse object
  * and set this field to null.
  */
 dart_html.HttpRequest _xmlHttpRequest;

 /**
  * Only used for building a
  * {@link com.google.gwt.user.client.rpc.impl.FailedRequest}.
  */
 Request.internal();

 /**
  * Constructs an instance of the Request object.
  *
  * @param xmlHttpRequest JavaScript XmlHttpRequest object instance
  * @param timeoutMillis number of milliseconds to wait for a response
  * @param callback callback interface to use for notification
  *
  * @throws IllegalArgumentException if timeoutMillis &lt; 0
  * @throws NullPointerException if xmlHttpRequest, or callback are null
  */
 Request(dart_html.HttpRequest xmlHttpRequest, int timeoutMillis, RequestCallback callback) {
   if (xmlHttpRequest == null) {
     throw new Exception();
   }

   if (callback == null) {
     throw new Exception();
   }

   if (timeoutMillis < 0) {
     throw new Exception();
   }

   this._timeoutMillis = timeoutMillis;

   this._xmlHttpRequest = xmlHttpRequest;

   if (timeoutMillis > 0) {
     // create and start a Timer
     _timer = new dart_async.Timer(new Duration(milliseconds:timeoutMillis), (){
       _fireOnTimeout(callback);
     });
   } else {
     // no Timer required
     _timer = null;
   }
 }

 /**
  * Cancels a pending request. If the request has already been canceled or if
  * it has timed out no action is taken.
  */
 void cancel() {
   /*
    * There is a strange race condition that occurs on Mozilla when you cancel
    * a request while the response is coming in. It appears that in some cases
    * the onreadystatechange handler is still called after the handler function
    * has been deleted and during the call to XmlHttpRequest.abort(). So we
    * null the xmlHttpRequest here and that will prevent the
    * fireOnResponseReceived method from calling the callback function.
    *
    * Setting the onreadystatechange handler to null gives us the correct
    * behavior in Mozilla but crashes IE. That is why we have chosen to fixed
    * this in Java by nulling out our reference to the XmlHttpRequest object.
    */
   if (_xmlHttpRequest != null) {
     dart_html.HttpRequest xmlHttp = _xmlHttpRequest;
     _xmlHttpRequest = null;

     //xmlHttp.onReadyStateChange. readyStateChangeEvent.addListener(listener); // clearOnReadyStateChange();
     xmlHttp.onReadyStateChange.listen(null, onError:null, onDone:null, cancelOnError:true);
     xmlHttp.abort();

     _cancelTimer();
   }
 }

 /**
  * Returns true if this request is waiting for a response.
  *
  * @return true if this request is waiting for a response
  */
 bool isPending() {
   if (_xmlHttpRequest == null) {
     return false;
   }

   int readyState = _xmlHttpRequest.readyState;

   /*
    * Because we are doing asynchronous requests it is possible that we can
    * call XmlHttpRequest.send and still have the XmlHttpRequest.getReadyState
    * method return the state as XmlHttpRequest.OPEN. That is why we include
    * open although it is nottechnically true since open implies that the
    * request has not been sent.
    */
   switch (readyState) {
     case dart_html.HttpRequest.OPENED:
     case dart_html.HttpRequest.HEADERS_RECEIVED:
     case dart_html.HttpRequest.LOADING:
       return true;
   }

   return false;
 }

 /*
  * Method called when the JavaScript XmlHttpRequest object's readyState
  * reaches 4 (LOADED).
  */
 void fireOnResponseReceived(RequestCallback callback) {
   if (_xmlHttpRequest == null) {
     // the request has timed out at this point
     return;
   }

   _cancelTimer();

   /*
    * We cannot use cancel here because it would clear the contents of the
    * JavaScript XmlHttpRequest object so we manually null out our reference to
    * the JavaScriptObject
    */
   dart_html.HttpRequest xhr = _xmlHttpRequest;
   _xmlHttpRequest = null;

   String errorMsg = _getBrowserSpecificFailure(xhr);
   if (errorMsg != null) {
     Exception exception = new Exception(errorMsg);
     callback.onError(this, exception);
   } else {
     Response response = createResponse(xhr);
     callback.onResponseReceived(this, response);
   }
 }

 /*
  * Stops the current HTTPRequest timer if there is one.
  */
 void _cancelTimer() {
   if (_timer != null) {
     _timer.cancel();
   }
 }

 /*
  * Method called when this request times out.
  *
  * NOTE: this method is called from JSNI
  */
 void _fireOnTimeout(RequestCallback callback) {
   if (_xmlHttpRequest == null) {
     // the request has been received at this point
     return;
   }

   cancel();

   callback.onError(this, new Exception()); //this, _timeoutMillis));
 }

 /**
  * Tests if the JavaScript <code>XmlHttpRequest.status</code> property is
  * readable. This can return failure in two different known scenarios:
  *
  * <ol>
  * <li>On Mozilla, after a network error, attempting to read the status code
  * results in an exception being thrown. See <a
  * href="https://bugzilla.mozilla.org/show_bug.cgi?id=238559"
  * >https://bugzilla.mozilla.org/show_bug.cgi?id=238559</a>.</li>
  * <li>On Safari, if the HTTP response does not include any response text. See
  * <a
  * href="http://bugs.webkit.org/show_bug.cgi?id=3810">http://bugs.webkit.org
  * /show_bug.cgi?id=3810</a>.</li>
  * </ol>
  *
  * @param xhr the JavaScript <code>XmlHttpRequest</code> object to test
  * @return a String message containing an error message if the
  *         <code>XmlHttpRequest.status</code> code is unreadable or null if
  *         the status code could be successfully read.
  */
 String _getBrowserSpecificFailure(dart_html.HttpRequest xhr) {
   try {
     if (xhr.status == null) {
       return "XmlHttpRequest.status == undefined, please see Safari bug http://bugs.webkit.org/show_bug.cgi?id=3810 for more details";
     }
     return null;
   } on Exception catch (e) {
     return "Unable to read XmlHttpRequest.status; likely causes are a networking error or bad cross-domain request. Please see https://bugzilla.mozilla.org/show_bug.cgi?id=238559 for more details";
   }
 }
}

Static Methods

Response createResponse(HttpRequest xmlHttpRequest) #

Creates a {@link Response} instance for the given JavaScript XmlHttpRequest object.

@param xmlHttpRequest xmlHttpRequest object for which we need a response @return a {@link Response} object instance

static Response createResponse(dart_html.HttpRequest xmlHttpRequest) {
 assert (isResponseReady(xmlHttpRequest));
 Response response = new _Response(xmlHttpRequest);
 return response;
}

List<Header> getHeaders(HttpRequest xmlHttp) #

Returns an array of headers built by parsing the string of headers returned by the JavaScript <code>XmlHttpRequest</code> object.

@param xmlHttpRequest @return array of Header items

static List<Header> getHeaders(dart_html.HttpRequest xmlHttp) {
 String allHeaders = xmlHttp.getAllResponseHeaders();
 List<String> unparsedHeaders = allHeaders.split("\n");
 List<Header> parsedHeaders = new List<Header>(unparsedHeaders.length);

 for (int i = 0, n = unparsedHeaders.length; i < n; ++i) {
   String unparsedHeader = unparsedHeaders[i];

   if (unparsedHeader.length == 0) {
     continue;
   }

   int endOfNameIdx = unparsedHeader.indexOf(':');
   if (endOfNameIdx < 0) {
     continue;
   }

   String name = unparsedHeader.substring(0, endOfNameIdx).trim();
   String value = unparsedHeader.substring(endOfNameIdx + 1).trim();
   Header header = new _RequestHeader(name, value);

   parsedHeaders[i] = header;
 }

 return parsedHeaders;
}

bool isResponseReady(HttpRequest xhr) #

static bool isResponseReady(dart_html.HttpRequest xhr) {
 return xhr.readyState == dart_html.HttpRequest.DONE;
}

Constructors

new Request(HttpRequest xmlHttpRequest, int timeoutMillis, RequestCallback callback) #

Constructs an instance of the Request object.

@param xmlHttpRequest JavaScript XmlHttpRequest object instance @param timeoutMillis number of milliseconds to wait for a response @param callback callback interface to use for notification

@throws IllegalArgumentException if timeoutMillis < 0 @throws NullPointerException if xmlHttpRequest, or callback are null

Request(dart_html.HttpRequest xmlHttpRequest, int timeoutMillis, RequestCallback callback) {
 if (xmlHttpRequest == null) {
   throw new Exception();
 }

 if (callback == null) {
   throw new Exception();
 }

 if (timeoutMillis < 0) {
   throw new Exception();
 }

 this._timeoutMillis = timeoutMillis;

 this._xmlHttpRequest = xmlHttpRequest;

 if (timeoutMillis > 0) {
   // create and start a Timer
   _timer = new dart_async.Timer(new Duration(milliseconds:timeoutMillis), (){
     _fireOnTimeout(callback);
   });
 } else {
   // no Timer required
   _timer = null;
 }
}

new Request.internal() #

Only used for building a {@link com.google.gwt.user.client.rpc.impl.FailedRequest}.

Request.internal();

Methods

void cancel() #

Cancels a pending request. If the request has already been canceled or if it has timed out no action is taken.

void cancel() {
 /*
  * There is a strange race condition that occurs on Mozilla when you cancel
  * a request while the response is coming in. It appears that in some cases
  * the onreadystatechange handler is still called after the handler function
  * has been deleted and during the call to XmlHttpRequest.abort(). So we
  * null the xmlHttpRequest here and that will prevent the
  * fireOnResponseReceived method from calling the callback function.
  *
  * Setting the onreadystatechange handler to null gives us the correct
  * behavior in Mozilla but crashes IE. That is why we have chosen to fixed
  * this in Java by nulling out our reference to the XmlHttpRequest object.
  */
 if (_xmlHttpRequest != null) {
   dart_html.HttpRequest xmlHttp = _xmlHttpRequest;
   _xmlHttpRequest = null;

   //xmlHttp.onReadyStateChange. readyStateChangeEvent.addListener(listener); // clearOnReadyStateChange();
   xmlHttp.onReadyStateChange.listen(null, onError:null, onDone:null, cancelOnError:true);
   xmlHttp.abort();

   _cancelTimer();
 }
}

void fireOnResponseReceived(RequestCallback callback) #

void fireOnResponseReceived(RequestCallback callback) {
 if (_xmlHttpRequest == null) {
   // the request has timed out at this point
   return;
 }

 _cancelTimer();

 /*
  * We cannot use cancel here because it would clear the contents of the
  * JavaScript XmlHttpRequest object so we manually null out our reference to
  * the JavaScriptObject
  */
 dart_html.HttpRequest xhr = _xmlHttpRequest;
 _xmlHttpRequest = null;

 String errorMsg = _getBrowserSpecificFailure(xhr);
 if (errorMsg != null) {
   Exception exception = new Exception(errorMsg);
   callback.onError(this, exception);
 } else {
   Response response = createResponse(xhr);
   callback.onResponseReceived(this, response);
 }
}

bool isPending() #

Returns true if this request is waiting for a response.

@return true if this request is waiting for a response

bool isPending() {
 if (_xmlHttpRequest == null) {
   return false;
 }

 int readyState = _xmlHttpRequest.readyState;

 /*
  * Because we are doing asynchronous requests it is possible that we can
  * call XmlHttpRequest.send and still have the XmlHttpRequest.getReadyState
  * method return the state as XmlHttpRequest.OPEN. That is why we include
  * open although it is nottechnically true since open implies that the
  * request has not been sent.
  */
 switch (readyState) {
   case dart_html.HttpRequest.OPENED:
   case dart_html.HttpRequest.HEADERS_RECEIVED:
   case dart_html.HttpRequest.LOADING:
     return true;
 }

 return false;
}