Chromium Code Reviews| Index: sky/framework/xmlhttprequest.sky |
| diff --git a/sky/framework/xmlhttprequest.sky b/sky/framework/xmlhttprequest.sky |
| index 897ad9773d5500c7f9cbd3926d04e5a3a504b220..ce68eafd94a86cf96ea7190e6ac8e582f216e3f6 100644 |
| --- a/sky/framework/xmlhttprequest.sky |
| +++ b/sky/framework/xmlhttprequest.sky |
| @@ -21,11 +21,24 @@ class Private { |
| } |
| } |
| +// Somewhat hacky, but works. |
| +function stringToUTF8Buffer(string) { |
| + var string = unescape(encodeURIComponent(string)); |
| + var charList = string.split(''); |
| + var uintArray = []; |
| + for (var i = 0; i < charList.length; i++) { |
| + uintArray.push(charList[i].charCodeAt(0)); |
|
esprehn
2014/12/15 21:43:22
This doesn't make sense, the splitting above seems
esprehn
2014/12/15 21:50:56
I think you want:
function stringToUTF8Buffer(str
|
| + } |
| + return new Uint8Array(uintArray); |
| +} |
| + |
| // https://xhr.spec.whatwg.org |
| class XMLHttpRequest { |
| constructor() { |
| this[kPrivate] = new Private; |
| this.responseType = ''; // Only text and arraybuffer support for now. |
| + this.status = null; |
| + this.statusText = null; |
| } |
| onload() { |
| @@ -69,8 +82,29 @@ class XMLHttpRequest { |
| this[kPrivate].headers.set(header, value); |
| } |
| - send() { |
| + send(body) { |
| var priv = this[kPrivate]; |
| + // Handle the body before the headers as it can affect Content-Type. |
| + if (body) { |
| + var bodyAsBufferView = null; |
| + if (typeof(body) === "string") { |
| + this.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); |
| + bodyAsBufferView = stringToUTF8Buffer(body); |
| + } else { |
| + bodyAsBufferView = new Uint8Array(body); |
| + } |
| + var dataPipe = new core.createDataPipe(); |
| + // FIXME: body is currently assumed to be an ArrayBuffer. |
| + var writeResult = core.writeData(dataPipe.producerHandle, |
| + bodyAsBufferView, core.WRITE_DATA_FLAG_ALL_OR_NONE); |
| + core.close(dataPipe.producerHandle); |
| + // FIXME: Much better error handling needed. |
| + console.assert(writeResult.result === core.RESULT_OK); |
| + console.assert(writeResult.numBytes === body.length); |
| + // 'body' is actually an array of body segments. |
| + priv.request.body = [dataPipe.consumerHandle]; |
| + } |
| + |
| var requestHeaders = []; |
| priv.headers.forEach(function(value, key) { |
| requestHeaders.push(key + ': ' + value); |
| @@ -85,14 +119,21 @@ class XMLHttpRequest { |
| var self = this; |
| outstandingRequests.add(this); |
| priv.loader.start(priv.request).then(function(result) { |
| + self.status = result.response.status_code; |
| + self.statusText = result.response.status_line; |
| + if (result.response.error) |
| + throw new Error(result.response.error.description); |
| return core.drainData(result.response.body).then(function(result) { |
| outstandingRequests.delete(self); |
| priv.responseArrayBuffer = result.buffer; |
| - // FIXME: Catch exceptions during onload so they don't trip onerror. |
| - self.onload(); |
| + // Use a setTimeout to avoid exceptions in onload tripping onerror. |
| + window.setTimeout(function() { |
| + self.onload(); |
| + }); |
| }); |
| }).catch(function(error) { |
| outstandingRequests.delete(self); |
| + // Technically this should throw a ProgressEvent. |
| self.onerror(error); |
| }); |
| } |