OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org> | 3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org> |
4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org> | 4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org> |
5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved. | 5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved. |
6 * Copyright (C) 2012 Intel Corporation | 6 * Copyright (C) 2012 Intel Corporation |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Lesser General Public | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 , m_downloadedBlobLength(0) | 125 , m_downloadedBlobLength(0) |
126 , m_receivedLength(0) | 126 , m_receivedLength(0) |
127 , m_lastSendLineNumber(0) | 127 , m_lastSendLineNumber(0) |
128 , m_exceptionCode(0) | 128 , m_exceptionCode(0) |
129 , m_progressEventThrottle(this) | 129 , m_progressEventThrottle(this) |
130 , m_responseTypeCode(ResponseTypeDefault) | 130 , m_responseTypeCode(ResponseTypeDefault) |
131 , m_securityOrigin(securityOrigin) | 131 , m_securityOrigin(securityOrigin) |
132 , m_previousReadyStateChangeFireTime(0) | 132 , m_previousReadyStateChangeFireTime(0) |
133 , m_async(true) | 133 , m_async(true) |
134 , m_includeCredentials(false) | 134 , m_includeCredentials(false) |
135 , m_createdDocument(false) | 135 , m_parsedResponse(false) |
136 , m_error(false) | 136 , m_error(false) |
137 , m_uploadEventsAllowed(true) | 137 , m_uploadEventsAllowed(true) |
138 , m_uploadComplete(false) | 138 , m_uploadComplete(false) |
139 , m_sameOriginRequest(true) | 139 , m_sameOriginRequest(true) |
140 { | 140 { |
141 #ifndef NDEBUG | 141 #ifndef NDEBUG |
142 xmlHttpRequestCounter.increment(); | 142 xmlHttpRequestCounter.increment(); |
143 #endif | 143 #endif |
144 ScriptWrappable::init(this); | 144 ScriptWrappable::init(this); |
145 } | 145 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 | 180 |
181 ScriptString XMLHttpRequest::responseJSONSource() | 181 ScriptString XMLHttpRequest::responseJSONSource() |
182 { | 182 { |
183 ASSERT(m_responseTypeCode == ResponseTypeJSON); | 183 ASSERT(m_responseTypeCode == ResponseTypeJSON); |
184 | 184 |
185 if (m_error || m_state != DONE) | 185 if (m_error || m_state != DONE) |
186 return ScriptString(); | 186 return ScriptString(); |
187 return m_responseText; | 187 return m_responseText; |
188 } | 188 } |
189 | 189 |
| 190 void XMLHttpRequest::initResponseDocument() |
| 191 { |
| 192 AtomicString mimeType = responseMIMEType(); |
| 193 bool isHTML = equalIgnoringCase(mimeType, "text/html"); |
| 194 |
| 195 // The W3C spec requires the final MIME type to be some valid XML type, or t
ext/html. |
| 196 // If it is text/html, then the responseType of "document" must have been su
pplied explicitly. |
| 197 if ((m_response.isHTTP() && !responseIsXML() && !isHTML) |
| 198 || (isHTML && m_responseTypeCode == ResponseTypeDefault) |
| 199 || executionContext()->isWorkerGlobalScope()) { |
| 200 m_responseDocument = nullptr; |
| 201 return; |
| 202 } |
| 203 |
| 204 DocumentInit init = DocumentInit::fromContext(document()->contextDocument(),
m_url); |
| 205 if (isHTML) |
| 206 m_responseDocument = HTMLDocument::create(init); |
| 207 else |
| 208 m_responseDocument = XMLDocument::create(init); |
| 209 |
| 210 // FIXME: Set Last-Modified. |
| 211 m_responseDocument->setSecurityOrigin(securityOrigin()); |
| 212 m_responseDocument->setContextFeatures(document()->contextFeatures()); |
| 213 m_responseDocument->setMimeType(mimeType); |
| 214 } |
| 215 |
190 Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState) | 216 Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState) |
191 { | 217 { |
192 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo
nseTypeDocument) { | 218 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo
nseTypeDocument) { |
193 exceptionState.throwDOMException(InvalidStateError, "The value is only a
ccessible if the object's 'responseType' is '' or 'document' (was '" + responseT
ype() + "')."); | 219 exceptionState.throwDOMException(InvalidStateError, "The value is only a
ccessible if the object's 'responseType' is '' or 'document' (was '" + responseT
ype() + "')."); |
194 return 0; | 220 return 0; |
195 } | 221 } |
196 | 222 |
197 if (m_error || m_state != DONE) | 223 if (m_error || m_state != DONE) |
198 return 0; | 224 return 0; |
199 | 225 |
200 if (!m_createdDocument) { | 226 if (!m_parsedResponse) { |
201 AtomicString mimeType = responseMIMEType(); | 227 initResponseDocument(); |
202 bool isHTML = equalIgnoringCase(mimeType, "text/html"); | 228 if (!m_responseDocument) |
| 229 return nullptr; |
203 | 230 |
204 // The W3C spec requires the final MIME type to be some valid XML type,
or text/html. | 231 m_responseDocument->setContent(m_responseText.flattenToString()); |
205 // If it is text/html, then the responseType of "document" must have bee
n supplied explicitly. | 232 if (!m_responseDocument->wellFormed()) |
206 if ((m_response.isHTTP() && !responseIsXML() && !isHTML) | |
207 || (isHTML && m_responseTypeCode == ResponseTypeDefault) | |
208 || executionContext()->isWorkerGlobalScope()) { | |
209 m_responseDocument = nullptr; | 233 m_responseDocument = nullptr; |
210 } else { | 234 |
211 DocumentInit init = DocumentInit::fromContext(document()->contextDoc
ument(), m_url); | 235 m_parsedResponse = true; |
212 if (isHTML) | |
213 m_responseDocument = HTMLDocument::create(init); | |
214 else | |
215 m_responseDocument = XMLDocument::create(init); | |
216 // FIXME: Set Last-Modified. | |
217 m_responseDocument->setContent(m_responseText.flattenToString()); | |
218 m_responseDocument->setSecurityOrigin(securityOrigin()); | |
219 m_responseDocument->setContextFeatures(document()->contextFeatures()
); | |
220 m_responseDocument->setMimeType(mimeType); | |
221 if (!m_responseDocument->wellFormed()) | |
222 m_responseDocument = nullptr; | |
223 } | |
224 m_createdDocument = true; | |
225 } | 236 } |
226 | 237 |
227 return m_responseDocument.get(); | 238 return m_responseDocument.get(); |
228 } | 239 } |
229 | 240 |
230 Blob* XMLHttpRequest::responseBlob() | 241 Blob* XMLHttpRequest::responseBlob() |
231 { | 242 { |
232 ASSERT(m_responseTypeCode == ResponseTypeBlob); | 243 ASSERT(m_responseTypeCode == ResponseTypeBlob); |
233 ASSERT(!m_binaryResponseBuilder.get()); | 244 ASSERT(!m_binaryResponseBuilder.get()); |
234 | 245 |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 void XMLHttpRequest::clearResponse() | 919 void XMLHttpRequest::clearResponse() |
909 { | 920 { |
910 // FIXME: when we add the support for multi-part XHR, we will have to | 921 // FIXME: when we add the support for multi-part XHR, we will have to |
911 // be careful with this initialization. | 922 // be careful with this initialization. |
912 m_receivedLength = 0; | 923 m_receivedLength = 0; |
913 | 924 |
914 m_response = ResourceResponse(); | 925 m_response = ResourceResponse(); |
915 | 926 |
916 m_responseText.clear(); | 927 m_responseText.clear(); |
917 | 928 |
918 m_createdDocument = false; | 929 m_parsedResponse = false; |
919 m_responseDocument = nullptr; | 930 m_responseDocument = nullptr; |
920 | 931 |
921 m_responseBlob = nullptr; | 932 m_responseBlob = nullptr; |
922 m_downloadedBlobLength = 0; | 933 m_downloadedBlobLength = 0; |
923 | 934 |
924 m_responseStream = nullptr; | 935 m_responseStream = nullptr; |
925 | 936 |
926 // These variables may referred by the response accessors. So, we can clear | 937 // These variables may referred by the response accessors. So, we can clear |
927 // this only when we clear the response holder variables above. | 938 // this only when we clear the response holder variables above. |
928 m_binaryResponseBuilder.clear(); | 939 m_binaryResponseBuilder.clear(); |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 m_response = response; | 1249 m_response = response; |
1239 if (!m_mimeTypeOverride.isEmpty()) { | 1250 if (!m_mimeTypeOverride.isEmpty()) { |
1240 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); | 1251 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); |
1241 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); | 1252 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); |
1242 } | 1253 } |
1243 | 1254 |
1244 if (m_responseEncoding.isEmpty()) | 1255 if (m_responseEncoding.isEmpty()) |
1245 m_responseEncoding = response.textEncodingName(); | 1256 m_responseEncoding = response.textEncodingName(); |
1246 } | 1257 } |
1247 | 1258 |
| 1259 PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const |
| 1260 { |
| 1261 if (m_responseTypeCode == ResponseTypeJSON) |
| 1262 return TextResourceDecoder::create("application/json", "UTF-8"); |
| 1263 |
| 1264 if (!m_responseEncoding.isEmpty()) |
| 1265 return TextResourceDecoder::create("text/plain", m_responseEncoding); |
| 1266 |
| 1267 // allow TextResourceDecoder to look inside the m_response if it's XML or HT
ML |
| 1268 if (responseIsXML()) { |
| 1269 OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("appli
cation/xml"); |
| 1270 // Don't stop on encoding errors, unlike it is done for other kinds |
| 1271 // of XML resources. This matches the behavior of previous WebKit |
| 1272 // versions, Firefox and Opera. |
| 1273 decoder->useLenientXMLDecoding(); |
| 1274 |
| 1275 return decoder.release(); |
| 1276 } |
| 1277 |
| 1278 if (equalIgnoringCase(responseMIMEType(), "text/html")) |
| 1279 return TextResourceDecoder::create("text/html", "UTF-8"); |
| 1280 |
| 1281 return TextResourceDecoder::create("text/plain", "UTF-8"); |
| 1282 } |
| 1283 |
1248 void XMLHttpRequest::didReceiveData(const char* data, int len) | 1284 void XMLHttpRequest::didReceiveData(const char* data, int len) |
1249 { | 1285 { |
1250 ASSERT(m_responseTypeCode != ResponseTypeBlob); | 1286 ASSERT(m_responseTypeCode != ResponseTypeBlob); |
1251 | 1287 |
1252 if (m_error) | 1288 if (m_error) |
1253 return; | 1289 return; |
1254 | 1290 |
1255 if (m_state < HEADERS_RECEIVED) | 1291 if (m_state < HEADERS_RECEIVED) |
1256 changeState(HEADERS_RECEIVED); | 1292 changeState(HEADERS_RECEIVED); |
1257 | 1293 |
1258 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp
eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons
eTypeCode == ResponseTypeDocument; | |
1259 | |
1260 if (useDecoder && !m_decoder) { | |
1261 if (m_responseTypeCode == ResponseTypeJSON) { | |
1262 m_decoder = TextResourceDecoder::create("application/json", "UTF-8")
; | |
1263 } else if (!m_responseEncoding.isEmpty()) { | |
1264 m_decoder = TextResourceDecoder::create("text/plain", m_responseEnco
ding); | |
1265 // allow TextResourceDecoder to look inside the m_response if it's XML o
r HTML | |
1266 } else if (responseIsXML()) { | |
1267 m_decoder = TextResourceDecoder::create("application/xml"); | |
1268 // Don't stop on encoding errors, unlike it is done for other kinds | |
1269 // of XML resources. This matches the behavior of previous WebKit | |
1270 // versions, Firefox and Opera. | |
1271 m_decoder->useLenientXMLDecoding(); | |
1272 } else if (equalIgnoringCase(responseMIMEType(), "text/html")) { | |
1273 m_decoder = TextResourceDecoder::create("text/html", "UTF-8"); | |
1274 } else { | |
1275 m_decoder = TextResourceDecoder::create("text/plain", "UTF-8"); | |
1276 } | |
1277 } | |
1278 | |
1279 if (!len) | 1294 if (!len) |
1280 return; | 1295 return; |
1281 | 1296 |
1282 if (len == -1) | 1297 if (len == -1) |
1283 len = strlen(data); | 1298 len = strlen(data); |
1284 | 1299 |
| 1300 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp
eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons
eTypeCode == ResponseTypeDocument; |
1285 if (useDecoder) { | 1301 if (useDecoder) { |
| 1302 if (!m_decoder) |
| 1303 m_decoder = createDecoder(); |
| 1304 |
1286 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); | 1305 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); |
1287 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { | 1306 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { |
1288 // Buffer binary data. | 1307 // Buffer binary data. |
1289 if (!m_binaryResponseBuilder) | 1308 if (!m_binaryResponseBuilder) |
1290 m_binaryResponseBuilder = SharedBuffer::create(); | 1309 m_binaryResponseBuilder = SharedBuffer::create(); |
1291 m_binaryResponseBuilder->append(data, len); | 1310 m_binaryResponseBuilder->append(data, len); |
1292 } else if (m_responseTypeCode == ResponseTypeLegacyStream) { | 1311 } else if (m_responseTypeCode == ResponseTypeLegacyStream) { |
1293 if (!m_responseStream) | 1312 if (!m_responseStream) |
1294 m_responseStream = Stream::create(executionContext(), responseMIMETy
pe()); | 1313 m_responseStream = Stream::create(executionContext(), responseMIMETy
pe()); |
1295 m_responseStream->addData(data, len); | 1314 m_responseStream->addData(data, len); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 { | 1401 { |
1383 visitor->trace(m_responseBlob); | 1402 visitor->trace(m_responseBlob); |
1384 visitor->trace(m_responseStream); | 1403 visitor->trace(m_responseStream); |
1385 visitor->trace(m_responseDocument); | 1404 visitor->trace(m_responseDocument); |
1386 visitor->trace(m_progressEventThrottle); | 1405 visitor->trace(m_progressEventThrottle); |
1387 visitor->trace(m_upload); | 1406 visitor->trace(m_upload); |
1388 XMLHttpRequestEventTarget::trace(visitor); | 1407 XMLHttpRequestEventTarget::trace(visitor); |
1389 } | 1408 } |
1390 | 1409 |
1391 } // namespace blink | 1410 } // namespace blink |
OLD | NEW |