| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "config.h" |  | 
| 6 #include "Response.h" |  | 
| 7 |  | 
| 8 #include "bindings/core/v8/Dictionary.h" |  | 
| 9 #include "bindings/core/v8/ExceptionState.h" |  | 
| 10 #include "core/dom/DOMArrayBuffer.h" |  | 
| 11 #include "core/dom/DOMArrayBufferView.h" |  | 
| 12 #include "core/fileapi/Blob.h" |  | 
| 13 #include "modules/serviceworkers/ResponseInit.h" |  | 
| 14 #include "public/platform/WebServiceWorkerResponse.h" |  | 
| 15 #include "wtf/RefPtr.h" |  | 
| 16 |  | 
| 17 namespace blink { |  | 
| 18 |  | 
| 19 namespace { |  | 
| 20 |  | 
| 21 FetchResponseData* createFetchResponseDataFromWebResponse(const WebServiceWorker
     Response& webResponse) |  | 
| 22 { |  | 
| 23     FetchResponseData* response = 0; |  | 
| 24     if (200 <= webResponse.status() && webResponse.status() < 300) |  | 
| 25         response = FetchResponseData::create(); |  | 
| 26     else |  | 
| 27         response = FetchResponseData::createNetworkErrorResponse(); |  | 
| 28 |  | 
| 29     response->setURL(webResponse.url()); |  | 
| 30     response->setStatus(webResponse.status()); |  | 
| 31     response->setStatusMessage(webResponse.statusText()); |  | 
| 32 |  | 
| 33     for (HTTPHeaderMap::const_iterator i = webResponse.headers().begin(), end = 
     webResponse.headers().end(); i != end; ++i) { |  | 
| 34         response->headerList()->append(i->key, i->value); |  | 
| 35     } |  | 
| 36 |  | 
| 37     response->setBlobDataHandle(webResponse.blobDataHandle()); |  | 
| 38 |  | 
| 39     // Filter the response according to |webResponse|'s ResponseType. |  | 
| 40     switch (webResponse.responseType()) { |  | 
| 41     case WebServiceWorkerResponseTypeBasic: |  | 
| 42         response = response->createBasicFilteredResponse(); |  | 
| 43         break; |  | 
| 44     case WebServiceWorkerResponseTypeCORS: |  | 
| 45         response = response->createCORSFilteredResponse(); |  | 
| 46         break; |  | 
| 47     case WebServiceWorkerResponseTypeOpaque: |  | 
| 48         response = response->createOpaqueFilteredResponse(); |  | 
| 49         break; |  | 
| 50     case WebServiceWorkerResponseTypeDefault: |  | 
| 51         break; |  | 
| 52     case WebServiceWorkerResponseTypeError: |  | 
| 53         ASSERT(response->type() == FetchResponseData::ErrorType); |  | 
| 54         break; |  | 
| 55     } |  | 
| 56 |  | 
| 57     return response; |  | 
| 58 } |  | 
| 59 |  | 
| 60 } |  | 
| 61 |  | 
| 62 Response* Response::create(ExecutionContext* context, ExceptionState& exceptionS
     tate) |  | 
| 63 { |  | 
| 64     return create(context, nullptr, ResponseInit(), exceptionState); |  | 
| 65 } |  | 
| 66 |  | 
| 67 Response* Response::create(ExecutionContext* context, const BodyInit& body, cons
     t Dictionary& responseInit, ExceptionState& exceptionState) |  | 
| 68 { |  | 
| 69     ASSERT(!body.isNull()); |  | 
| 70     if (body.isBlob()) |  | 
| 71         return create(context, body.getAsBlob(), ResponseInit(responseInit, exce
     ptionState), exceptionState); |  | 
| 72     if (body.isUSVString()) { |  | 
| 73         OwnPtr<BlobData> blobData = BlobData::create(); |  | 
| 74         blobData->appendText(body.getAsUSVString(), false); |  | 
| 75         // "Set |Content-Type| to `text/plain;charset=UTF-8`." |  | 
| 76         blobData->setContentType("text/plain;charset=UTF-8"); |  | 
| 77         const long long length = blobData->length(); |  | 
| 78         Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len
     gth)); |  | 
| 79         return create(context, blob, ResponseInit(responseInit, exceptionState),
      exceptionState); |  | 
| 80     } |  | 
| 81     if (body.isArrayBuffer()) { |  | 
| 82         RefPtr<DOMArrayBuffer> arrayBuffer = body.getAsArrayBuffer(); |  | 
| 83         OwnPtr<BlobData> blobData = BlobData::create(); |  | 
| 84         blobData->appendBytes(arrayBuffer->data(), arrayBuffer->byteLength()); |  | 
| 85         const long long length = blobData->length(); |  | 
| 86         Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len
     gth)); |  | 
| 87         return create(context, blob, ResponseInit(responseInit, exceptionState),
      exceptionState); |  | 
| 88     } |  | 
| 89     if (body.isArrayBufferView()) { |  | 
| 90         RefPtr<DOMArrayBufferView> arrayBufferView = body.getAsArrayBufferView()
     ; |  | 
| 91         OwnPtr<BlobData> blobData = BlobData::create(); |  | 
| 92         blobData->appendBytes(arrayBufferView->baseAddress(), arrayBufferView->b
     yteLength()); |  | 
| 93         const long long length = blobData->length(); |  | 
| 94         Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), len
     gth)); |  | 
| 95         return create(context, blob, ResponseInit(responseInit, exceptionState),
      exceptionState); |  | 
| 96     } |  | 
| 97     ASSERT_NOT_REACHED(); |  | 
| 98     return nullptr; |  | 
| 99 } |  | 
| 100 |  | 
| 101 Response* Response::create(ExecutionContext* context, Blob* body, const Response
     Init& responseInit, ExceptionState& exceptionState) |  | 
| 102 { |  | 
| 103     // "1. If |init|'s status member is not in the range 200 to 599, throw a |  | 
| 104     // RangeError." |  | 
| 105     if (responseInit.status < 200 || 599 < responseInit.status) { |  | 
| 106         exceptionState.throwRangeError("Invalid status"); |  | 
| 107         return 0; |  | 
| 108     } |  | 
| 109 |  | 
| 110     // FIXME: "2. If |init|'s statusText member does not match the Reason-Phrase |  | 
| 111     //        token production, throw a TypeError." |  | 
| 112 |  | 
| 113     // "3. Let |r| be a new Response object, associated with a new response, |  | 
| 114     // Headers object, and Body object." |  | 
| 115     Response* r = new Response(context); |  | 
| 116     r->suspendIfNeeded(); |  | 
| 117 |  | 
| 118     // "4. Set |r|'s response's status to |init|'s status member." |  | 
| 119     r->m_response->setStatus(responseInit.status); |  | 
| 120 |  | 
| 121     // "5. Set |r|'s response's status message to |init|'s statusText member." |  | 
| 122     r->m_response->setStatusMessage(AtomicString(responseInit.statusText)); |  | 
| 123 |  | 
| 124     // "6. If |init|'s headers member is present, run these substeps:" |  | 
| 125     if (responseInit.headers) { |  | 
| 126         // "1. Empty |r|'s response's header list." |  | 
| 127         r->m_response->headerList()->clearList(); |  | 
| 128         // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow |  | 
| 129         // any exceptions." |  | 
| 130         r->m_headers->fillWith(responseInit.headers.get(), exceptionState); |  | 
| 131         if (exceptionState.hadException()) |  | 
| 132             return 0; |  | 
| 133     } else if (!responseInit.headersDictionary.isUndefinedOrNull()) { |  | 
| 134         // "1. Empty |r|'s response's header list." |  | 
| 135         r->m_response->headerList()->clearList(); |  | 
| 136         // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow |  | 
| 137         // any exceptions." |  | 
| 138         r->m_headers->fillWith(responseInit.headersDictionary, exceptionState); |  | 
| 139         if (exceptionState.hadException()) |  | 
| 140             return 0; |  | 
| 141     } |  | 
| 142     // "7. If body is given, run these substeps:" |  | 
| 143     if (body) { |  | 
| 144         // "1. Let |stream| and |Content-Type| be the result of extracting body.
     " |  | 
| 145         // "2. Set |r|'s response's body to |stream|." |  | 
| 146         // "3. If |Content-Type| is non-null and |r|'s response's header list |  | 
| 147         // contains no header named `Content-Type`, append `Content-Type`/ |  | 
| 148         // |Content-Type| to |r|'s response's header list." |  | 
| 149         r->m_response->setBlobDataHandle(body->blobDataHandle()); |  | 
| 150         if (!body->type().isNull() && !r->m_response->headerList()->has("Content
     -Type")) |  | 
| 151             r->m_response->headerList()->append("Content-Type", body->type()); |  | 
| 152     } |  | 
| 153 |  | 
| 154     // FIXME: "8. Set |r|'s MIME type to the result of extracting a MIME type |  | 
| 155     //        from |r|'s response's header list." |  | 
| 156 |  | 
| 157     // "9. Return |r|." |  | 
| 158     return r; |  | 
| 159 } |  | 
| 160 |  | 
| 161 Response* Response::create(ExecutionContext* context, FetchResponseData* respons
     e) |  | 
| 162 { |  | 
| 163     Response* r = new Response(context, response); |  | 
| 164     r->suspendIfNeeded(); |  | 
| 165     return r; |  | 
| 166 } |  | 
| 167 |  | 
| 168 Response* Response::create(ExecutionContext* context, const WebServiceWorkerResp
     onse& webResponse) |  | 
| 169 { |  | 
| 170     FetchResponseData* responseData = createFetchResponseDataFromWebResponse(web
     Response); |  | 
| 171     Response* r = new Response(context, responseData); |  | 
| 172     r->suspendIfNeeded(); |  | 
| 173     return r; |  | 
| 174 } |  | 
| 175 |  | 
| 176 Response* Response::createClone(const Response& cloneFrom) |  | 
| 177 { |  | 
| 178     Response* r = new Response(cloneFrom); |  | 
| 179     r->suspendIfNeeded(); |  | 
| 180     return r; |  | 
| 181 } |  | 
| 182 |  | 
| 183 String Response::type() const |  | 
| 184 { |  | 
| 185     // "The type attribute's getter must return response's type." |  | 
| 186     switch (m_response->type()) { |  | 
| 187     case FetchResponseData::BasicType: |  | 
| 188         return "basic"; |  | 
| 189     case FetchResponseData::CORSType: |  | 
| 190         return "cors"; |  | 
| 191     case FetchResponseData::DefaultType: |  | 
| 192         return "default"; |  | 
| 193     case FetchResponseData::ErrorType: |  | 
| 194         return "error"; |  | 
| 195     case FetchResponseData::OpaqueType: |  | 
| 196         return "opaque"; |  | 
| 197     } |  | 
| 198     ASSERT_NOT_REACHED(); |  | 
| 199     return ""; |  | 
| 200 } |  | 
| 201 |  | 
| 202 String Response::url() const |  | 
| 203 { |  | 
| 204     // "The url attribute's getter must return the empty string if response's |  | 
| 205     // url is null and response's url, serialized with the exclude fragment |  | 
| 206     // flag set, otherwise." |  | 
| 207     if (!m_response->url().hasFragmentIdentifier()) |  | 
| 208         return m_response->url(); |  | 
| 209     KURL url(m_response->url()); |  | 
| 210     url.removeFragmentIdentifier(); |  | 
| 211     return url; |  | 
| 212 } |  | 
| 213 |  | 
| 214 unsigned short Response::status() const |  | 
| 215 { |  | 
| 216     // "The status attribute's getter must return response's status." |  | 
| 217     return m_response->status(); |  | 
| 218 } |  | 
| 219 |  | 
| 220 String Response::statusText() const |  | 
| 221 { |  | 
| 222     // "The statusText attribute's getter must return response's status message.
     " |  | 
| 223     return m_response->statusMessage(); |  | 
| 224 } |  | 
| 225 |  | 
| 226 Headers* Response::headers() const |  | 
| 227 { |  | 
| 228     // "The headers attribute's getter must return the associated Headers object
     ." |  | 
| 229     return m_headers; |  | 
| 230 } |  | 
| 231 |  | 
| 232 Response* Response::clone(ExceptionState& exceptionState) const |  | 
| 233 { |  | 
| 234     if (bodyUsed()) { |  | 
| 235         exceptionState.throwTypeError("Response body is already used"); |  | 
| 236         return nullptr; |  | 
| 237     } |  | 
| 238     if (streamAccessed()) { |  | 
| 239         // FIXME: Support clone() of the stream accessed Response. |  | 
| 240         exceptionState.throwTypeError("clone() of the Response which .body is ac
     cessed is not supported."); |  | 
| 241         return nullptr; |  | 
| 242     } |  | 
| 243     return Response::createClone(*this); |  | 
| 244 } |  | 
| 245 |  | 
| 246 void Response::populateWebServiceWorkerResponse(WebServiceWorkerResponse& respon
     se) |  | 
| 247 { |  | 
| 248     m_response->populateWebServiceWorkerResponse(response); |  | 
| 249 } |  | 
| 250 |  | 
| 251 Response::Response(ExecutionContext* context) |  | 
| 252     : Body(context) |  | 
| 253     , m_response(FetchResponseData::create()) |  | 
| 254     , m_headers(Headers::create(m_response->headerList())) |  | 
| 255 { |  | 
| 256     m_headers->setGuard(Headers::ResponseGuard); |  | 
| 257 } |  | 
| 258 |  | 
| 259 Response::Response(const Response& clone_from) |  | 
| 260     : Body(clone_from) |  | 
| 261     , m_response(clone_from.m_response->clone()) |  | 
| 262     , m_headers(Headers::create(m_response->headerList())) |  | 
| 263 { |  | 
| 264 } |  | 
| 265 |  | 
| 266 Response::Response(ExecutionContext* context, FetchResponseData* response) |  | 
| 267     : Body(context) |  | 
| 268     , m_response(response) |  | 
| 269     , m_headers(Headers::create(m_response->headerList())) |  | 
| 270 { |  | 
| 271     m_headers->setGuard(Headers::ResponseGuard); |  | 
| 272 } |  | 
| 273 |  | 
| 274 bool Response::hasBody() const |  | 
| 275 { |  | 
| 276     return internalBlobDataHandle() || internalBuffer(); |  | 
| 277 } |  | 
| 278 |  | 
| 279 PassRefPtr<BlobDataHandle> Response::blobDataHandle() const |  | 
| 280 { |  | 
| 281     return m_response->blobDataHandle(); |  | 
| 282 } |  | 
| 283 |  | 
| 284 BodyStreamBuffer* Response::buffer() const |  | 
| 285 { |  | 
| 286     return m_response->buffer(); |  | 
| 287 } |  | 
| 288 |  | 
| 289 String Response::contentTypeForBuffer() const |  | 
| 290 { |  | 
| 291     return m_response->contentTypeForBuffer(); |  | 
| 292 } |  | 
| 293 |  | 
| 294 PassRefPtr<BlobDataHandle> Response::internalBlobDataHandle() const |  | 
| 295 { |  | 
| 296     return m_response->internalBlobDataHandle(); |  | 
| 297 } |  | 
| 298 |  | 
| 299 BodyStreamBuffer* Response::internalBuffer() const |  | 
| 300 { |  | 
| 301     return m_response->internalBuffer(); |  | 
| 302 } |  | 
| 303 |  | 
| 304 String Response::internalContentTypeForBuffer() const |  | 
| 305 { |  | 
| 306     return m_response->internalContentTypeForBuffer(); |  | 
| 307 } |  | 
| 308 |  | 
| 309 void Response::trace(Visitor* visitor) |  | 
| 310 { |  | 
| 311     Body::trace(visitor); |  | 
| 312     visitor->trace(m_response); |  | 
| 313     visitor->trace(m_headers); |  | 
| 314 } |  | 
| 315 |  | 
| 316 } // namespace blink |  | 
| OLD | NEW | 
|---|