Changeset 154992 in webkit


Ignore:
Timestamp:
Sep 3, 2013 11:45:51 AM (11 years ago)
Author:
rniwa@webkit.org
Message:

Support the "json" responseType and JSON response entity in XHR
https://bugs.webkit.org/show_bug.cgi?id=73648

Reviewed by Oliver Hunt.

Source/JavaScriptCore:

Based on the patch written by Jarred Nicholls.

Add JSC::JSONParse. This function will be used in XMLHttpRequest.response of type 'json'.

(JSC::JSONParse):

  • runtime/JSONObject.h:

Source/WebCore:

Based on the patch written by Jarred Nicholls.

Implement 'json' type for XMLHttpRequest.response. We cache the result on JSC side as a cached attribute
unlike other response types like 'document' and 'blob' for which the parsed response object is cached
in XMLHttpRequest itself. In the long run, we should do the same for other types of response types.

Also refactored the various code to share the code.

Tests: fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html

fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html
fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html

  • ForwardingHeaders/runtime/JSONObject.h: Added.
  • bindings/js/JSXMLHttpRequestCustom.cpp:

(WebCore::JSXMLHttpRequest::visitChildren):
(WebCore::JSXMLHttpRequest::response): Use JSONParse to parse the response text and cache the result.
Call didCacheResponseJSON to set the cache status and clear the original response buffer.

  • xml/XMLHttpRequest.cpp:

(WebCore::XMLHttpRequest::XMLHttpRequest): Added m_responseCacheIsValid to invalidate the cache of
a json response.
(WebCore::XMLHttpRequest::responseText):
(WebCore::XMLHttpRequest::didCacheResponseJSON): Added; Updates m_responseCacheIsValid and clears the
response buffer to save memory.
(WebCore::XMLHttpRequest::responseXML):
(WebCore::XMLHttpRequest::setResponseType):
(WebCore::XMLHttpRequest::responseType):
(WebCore::XMLHttpRequest::clearResponseBuffers):
(WebCore::XMLHttpRequest::didReceiveData):

  • xml/XMLHttpRequest.h:

(WebCore::XMLHttpRequest::doneWithoutErrors): Extracted from responseXML.
(WebCore::XMLHttpRequest::responseTextIgnoringResponseType): Extracted from responseText.
(WebCore::XMLHttpRequest::responseCacheIsValid): Added.
(WebCore::XMLHttpRequest::shouldDecodeResponse): Extracted from didReceiveData.
Also modified to decode when the response type is ResponseTypeJSON.

  • xml/XMLHttpRequest.idl: Added CachedAttribute IDL extention on response property. This cache is

used when the response type is 'json'.

LayoutTests:

Add regression tests for XMLHttpRequest.response of type 'json'.

Two of these tests (valid & invalid) come from Jarred Nicholls's original patch.

  • fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json-utf-16.json: Added.
  • fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json: Added.
  • fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt: Added.
  • fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html: Added.
  • fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt: Added.
  • fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html: Added.
  • fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt: Added.
  • fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html: Added.
Location:
trunk
Files:
9 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r154991 r154992  
     12013-09-02  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Support the "json" responseType and JSON response entity in XHR
     4        https://bugs.webkit.org/show_bug.cgi?id=73648
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Add regression tests for XMLHttpRequest.response of type 'json'.
     9
     10        Two of these tests (valid & invalid) come from Jarred Nicholls's original patch.
     11
     12        * fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json-utf-16.json: Added.
     13        * fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json: Added.
     14        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt: Added.
     15        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html: Added.
     16        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt: Added.
     17        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html: Added.
     18        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt: Added.
     19        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html: Added.
     20
    1212013-09-03  Commit Queue  <commit-queue@webkit.org>
    222
  • trunk/Source/JavaScriptCore/ChangeLog

    r154986 r154992  
     12013-09-02  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Support the "json" responseType and JSON response entity in XHR
     4        https://bugs.webkit.org/show_bug.cgi?id=73648
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Based on the patch written by Jarred Nicholls.
     9
     10        Add JSC::JSONParse. This function will be used in XMLHttpRequest.response of type 'json'.
     11
     12        * JavaScriptCore.xcodeproj/project.pbxproj:
     13        * runtime/JSONObject.cpp:
     14        (JSC::JSONParse):
     15        * runtime/JSONObject.h:
     16
    1172013-09-02  Filip Pizlo  <fpizlo@apple.com>
    218
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r154986 r154992  
    958958                A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F2996917A0BB670010417A /* FTLFail.cpp */; };
    959959                A7F2996C17A0BB670010417A /* FTLFail.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F2996A17A0BB670010417A /* FTLFail.h */; settings = {ATTRIBUTES = (Private, ); }; };
    960                 A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
     960                A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
    961961                A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; };
    962962                A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; };
  • trunk/Source/JavaScriptCore/runtime/JSONObject.cpp

    r154797 r154992  
    820820}
    821821
     822JSValue JSONParse(ExecState* exec, const String& json)
     823{
     824    LocalScope scope(exec->vm());
     825
     826    if (json.is8Bit()) {
     827        LiteralParser<LChar> jsonParser(exec, json.characters8(), json.length(), StrictJSON);
     828        return jsonParser.tryLiteralParse();
     829    }
     830
     831    LiteralParser<UChar> jsonParser(exec, json.characters16(), json.length(), StrictJSON);
     832    return jsonParser.tryLiteralParse();
     833}
     834
    822835String JSONStringify(ExecState* exec, JSValue value, unsigned indent)
    823836{
  • trunk/Source/JavaScriptCore/runtime/JSONObject.h

    r154373 r154992  
    6161    };
    6262
     63    JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&);
    6364    String JSONStringify(ExecState*, JSValue, unsigned indent);
    6465
  • trunk/Source/WebCore/ChangeLog

    r154991 r154992  
     12013-09-02  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Support the "json" responseType and JSON response entity in XHR
     4        https://bugs.webkit.org/show_bug.cgi?id=73648
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Based on the patch written by Jarred Nicholls.
     9
     10        Implement 'json' type for XMLHttpRequest.response. We cache the result on JSC side as a cached attribute
     11        unlike other response types like 'document' and 'blob' for which the parsed response object is cached
     12        in XMLHttpRequest itself. In the long run, we should do the same for other types of response types.
     13
     14        Also refactored the various code to share the code.
     15
     16        Tests: fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html
     17               fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html
     18               fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html
     19
     20        * ForwardingHeaders/runtime/JSONObject.h: Added.
     21
     22        * bindings/js/JSXMLHttpRequestCustom.cpp:
     23        (WebCore::JSXMLHttpRequest::visitChildren):
     24        (WebCore::JSXMLHttpRequest::response): Use JSONParse to parse the response text and cache the result.
     25        Call didCacheResponseJSON to set the cache status and clear the original response buffer.
     26
     27        * xml/XMLHttpRequest.cpp:
     28        (WebCore::XMLHttpRequest::XMLHttpRequest): Added m_responseCacheIsValid to invalidate the cache of
     29        a json response.
     30        (WebCore::XMLHttpRequest::responseText):
     31        (WebCore::XMLHttpRequest::didCacheResponseJSON): Added; Updates m_responseCacheIsValid and clears the
     32        response buffer to save memory.
     33        (WebCore::XMLHttpRequest::responseXML):
     34        (WebCore::XMLHttpRequest::setResponseType):
     35        (WebCore::XMLHttpRequest::responseType):
     36        (WebCore::XMLHttpRequest::clearResponseBuffers):
     37        (WebCore::XMLHttpRequest::didReceiveData):
     38
     39        * xml/XMLHttpRequest.h:
     40        (WebCore::XMLHttpRequest::doneWithoutErrors): Extracted from responseXML.
     41        (WebCore::XMLHttpRequest::responseTextIgnoringResponseType): Extracted from responseText.
     42        (WebCore::XMLHttpRequest::responseCacheIsValid): Added.
     43        (WebCore::XMLHttpRequest::shouldDecodeResponse): Extracted from didReceiveData.
     44        Also modified to decode when the response type is ResponseTypeJSON.
     45
     46        * xml/XMLHttpRequest.idl: Added CachedAttribute IDL extention on response property. This cache is
     47        used when the response type is 'json'.
     48
    1492013-09-03  Commit Queue  <commit-queue@webkit.org>
    250
  • trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp

    r154800 r154992  
    5151#include <runtime/JSArrayBuffer.h>
    5252#include <runtime/JSArrayBufferView.h>
     53#include <runtime/JSONObject.h>
    5354
    5455using namespace JSC;
     
    7576    if (Blob* responseBlob = thisObject->m_impl->optionalResponseBlob())
    7677        visitor.addOpaqueRoot(responseBlob);
     78
     79    if (thisObject->m_response)
     80        visitor.append(&thisObject->m_response);
    7781
    7882    thisObject->m_impl->visitJSEventListeners(visitor);
     
    169173        return responseText(exec);
    170174
     175    case XMLHttpRequest::ResponseTypeJSON:
     176        {
     177            // FIXME: Use CachedAttribute for other types as well.
     178            if (m_response && impl()->responseCacheIsValid())
     179                return m_response.get();
     180
     181            if (!impl()->doneWithoutErrors())
     182                return jsNull();
     183
     184            JSValue value = JSONParse(exec, impl()->responseTextIgnoringResponseType());
     185            if (!value)
     186                value = jsNull();
     187            JSXMLHttpRequest* jsRequest = const_cast<JSXMLHttpRequest*>(this);
     188            jsRequest->m_response.set(exec->vm(), jsRequest, value);
     189
     190            impl()->didCacheResponseJSON();
     191
     192            return value;
     193        }
     194
    171195    case XMLHttpRequest::ResponseTypeDocument:
    172196        {
  • trunk/Source/WebCore/xml/XMLHttpRequest.cpp

    r154962 r154992  
    193193    , m_progressEventThrottle(this)
    194194    , m_responseTypeCode(ResponseTypeDefault)
     195    , m_responseCacheIsValid(false)
    195196{
    196197    initializeXMLHttpRequestStaticData();
     
    239240        return "";
    240241    }
    241     return m_responseBuilder.toStringPreserveCapacity();
     242    return responseTextIgnoringResponseType();
     243}
     244
     245void XMLHttpRequest::didCacheResponseJSON()
     246{
     247    ASSERT(m_responseTypeCode == ResponseTypeJSON && doneWithoutErrors());
     248    m_responseCacheIsValid = true;
     249    m_responseBuilder.clear();
    242250}
    243251
     
    249257    }
    250258
    251     if (m_error || m_state != DONE)
     259    if (!doneWithoutErrors())
    252260        return 0;
    253261
     
    363371    else if (responseType == "text")
    364372        m_responseTypeCode = ResponseTypeText;
     373    else if (responseType == "json")
     374        m_responseTypeCode = ResponseTypeJSON;
    365375    else if (responseType == "document")
    366376        m_responseTypeCode = ResponseTypeDocument;
     
    380390    case ResponseTypeText:
    381391        return "text";
     392    case ResponseTypeJSON:
     393        return "json";
    382394    case ResponseTypeDocument:
    383395        return "document";
     
    888900    m_binaryResponseBuilder.clear();
    889901    m_responseArrayBuffer.clear();
     902    m_responseCacheIsValid = false;
    890903}
    891904
     
    11901203        changeState(HEADERS_RECEIVED);
    11911204
    1192     bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode == ResponseTypeText || m_responseTypeCode == ResponseTypeDocument;
     1205    bool useDecoder = shouldDecodeResponse();
    11931206
    11941207    if (useDecoder && !m_decoder) {
  • trunk/Source/WebCore/xml/XMLHttpRequest.h

    r154800 r154992  
    6969    enum ResponseTypeCode {
    7070        ResponseTypeDefault,
    71         ResponseTypeText,
     71        ResponseTypeText,
     72        ResponseTypeJSON,
    7273        ResponseTypeDocument,
     74
     75        // Binary format
    7376        ResponseTypeBlob,
    7477        ResponseTypeArrayBuffer
    7578    };
     79    static const ResponseTypeCode FirstBinaryResponseType = ResponseTypeBlob;
    7680
    7781#if ENABLE(XHR_TIMEOUT)
     
    102106    void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
    103107    void overrideMimeType(const String& override);
     108    bool doneWithoutErrors() const { return !m_error && m_state == DONE; }
    104109    String getAllResponseHeaders(ExceptionCode&) const;
    105110    String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
    106111    String responseText(ExceptionCode&);
     112    String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
    107113    Document* responseXML(ExceptionCode&);
    108114    Document* optionalResponseXML() const { return m_responseDocument.get(); }
     
    113119    void setTimeout(unsigned long timeout, ExceptionCode&);
    114120#endif
     121
     122    bool responseCacheIsValid() const { return m_responseCacheIsValid; }
     123    void didCacheResponseJSON();
    115124
    116125    void sendFromInspector(PassRefPtr<FormData>, ExceptionCode&);
     
    201210    void abortError();
    202211
     212    bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; }
     213
    203214    OwnPtr<XMLHttpRequestUpload> m_upload;
    204215
     
    250261    // An enum corresponding to the allowed string values for the responseType attribute.
    251262    ResponseTypeCode m_responseTypeCode;
     263    bool m_responseCacheIsValid;
    252264};
    253265
  • trunk/Source/WebCore/xml/XMLHttpRequest.idl

    r152100 r154992  
    3232    "blob",
    3333    "document",
    34 //    FIXME: enable once support for json responseText is completed. (bug #73648)
    35 //    "json",
     34    "json",
    3635    "text"
    3736};
     
    8887
    8988    [SetterRaisesException] attribute XMLHttpRequestResponseType responseType;
    90     [GetterRaisesException, CustomGetter] readonly attribute Object response;
     89    [GetterRaisesException, CachedAttribute, CustomGetter] readonly attribute Object response;
    9190
    9291    [GetterRaisesException] readonly attribute unsigned short status;
Note: See TracChangeset for help on using the changeset viewer.