| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "Request.h" | 6 #include "Request.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/Dictionary.h" | 8 #include "bindings/core/v8/Dictionary.h" |
| 9 #include "core/dom/ExecutionContext.h" | 9 #include "core/dom/ExecutionContext.h" |
| 10 #include "core/fetch/FetchUtils.h" | 10 #include "core/fetch/FetchUtils.h" |
| 11 #include "core/fetch/ResourceLoaderOptions.h" | 11 #include "core/fetch/ResourceLoaderOptions.h" |
| 12 #include "core/loader/ThreadableLoader.h" | 12 #include "core/loader/ThreadableLoader.h" |
| 13 #include "core/xml/XMLHttpRequest.h" | 13 #include "core/xml/XMLHttpRequest.h" |
| 14 #include "modules/serviceworkers/FetchManager.h" | 14 #include "modules/serviceworkers/FetchManager.h" |
| 15 #include "modules/serviceworkers/RequestInit.h" | 15 #include "modules/serviceworkers/RequestInit.h" |
| 16 #include "platform/NotImplemented.h" | 16 #include "platform/NotImplemented.h" |
| 17 #include "platform/network/HTTPParsers.h" | 17 #include "platform/network/HTTPParsers.h" |
| 18 #include "platform/network/ResourceRequest.h" | 18 #include "platform/network/ResourceRequest.h" |
| 19 #include "platform/weborigin/Referrer.h" | 19 #include "platform/weborigin/Referrer.h" |
| 20 #include "public/platform/WebServiceWorkerRequest.h" | 20 #include "public/platform/WebServiceWorkerRequest.h" |
| 21 | 21 |
| 22 namespace blink { | 22 namespace blink { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 PassRefPtrWillBeRawPtr<Request> createRequestWithRequestData(PassRefPtrWillBeRaw
Ptr<FetchRequestData> request, const RequestInit& init, FetchRequestData::Mode m
ode, FetchRequestData::Credentials credentials, ExceptionState& exceptionState) | 26 Request* createRequestWithRequestData(FetchRequestData* request, const RequestIn
it& init, FetchRequestData::Mode mode, FetchRequestData::Credentials credentials
, ExceptionState& exceptionState) |
| 27 { | 27 { |
| 28 // "6. Let |mode| be |init|'s mode member if it is present, and | 28 // "6. Let |mode| be |init|'s mode member if it is present, and |
| 29 // |fallbackMode| otherwise." | 29 // |fallbackMode| otherwise." |
| 30 // "7. If |mode| is non-null, set |request|'s mode to |mode|." | 30 // "7. If |mode| is non-null, set |request|'s mode to |mode|." |
| 31 if (init.mode == "same-origin") { | 31 if (init.mode == "same-origin") { |
| 32 request->setMode(FetchRequestData::SameOriginMode); | 32 request->setMode(FetchRequestData::SameOriginMode); |
| 33 } else if (init.mode == "no-cors") { | 33 } else if (init.mode == "no-cors") { |
| 34 request->setMode(mode = FetchRequestData::NoCORSMode); | 34 request->setMode(mode = FetchRequestData::NoCORSMode); |
| 35 } else if (init.mode == "cors") { | 35 } else if (init.mode == "cors") { |
| 36 request->setMode(FetchRequestData::CORSMode); | 36 request->setMode(FetchRequestData::CORSMode); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 55 // current credentials in Request::create(). So we just set here. | 55 // current credentials in Request::create(). So we just set here. |
| 56 request->setCredentials(credentials); | 56 request->setCredentials(credentials); |
| 57 } | 57 } |
| 58 | 58 |
| 59 // "10. If |init|'s method member is present, let |method| be it and run | 59 // "10. If |init|'s method member is present, let |method| be it and run |
| 60 // these substeps:" | 60 // these substeps:" |
| 61 if (!init.method.isEmpty()) { | 61 if (!init.method.isEmpty()) { |
| 62 // "1. If |method| is not a useful method, throw a TypeError." | 62 // "1. If |method| is not a useful method, throw a TypeError." |
| 63 if (!FetchUtils::isUsefulMethod(init.method)) { | 63 if (!FetchUtils::isUsefulMethod(init.method)) { |
| 64 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); | 64 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); |
| 65 return nullptr; | 65 return 0; |
| 66 } | 66 } |
| 67 if (!isValidHTTPToken(init.method)) { | 67 if (!isValidHTTPToken(init.method)) { |
| 68 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); | 68 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); |
| 69 return nullptr; | 69 return 0; |
| 70 } | 70 } |
| 71 // FIXME: "2. Add case correction as in XMLHttpRequest?" | 71 // FIXME: "2. Add case correction as in XMLHttpRequest?" |
| 72 // "3. Set |request|'s method to |method|." | 72 // "3. Set |request|'s method to |method|." |
| 73 request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString
(init.method))); | 73 request->setMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(AtomicString
(init.method))); |
| 74 } | 74 } |
| 75 // "11. Let |r| be a new Request object associated with |request|, Headers | 75 // "11. Let |r| be a new Request object associated with |request|, Headers |
| 76 // object, and FetchBodyStream object." | 76 // object, and FetchBodyStream object." |
| 77 RefPtrWillBeRawPtr<Request> r = Request::create(request); | 77 Request* r = Request::create(request); |
| 78 | 78 |
| 79 // "12. Let |headers| be a copy of |r|'s Headers object." | 79 // "12. Let |headers| be a copy of |r|'s Headers object." |
| 80 // "13. If |init|'s headers member is present, set |headers| to |init|'s | 80 // "13. If |init|'s headers member is present, set |headers| to |init|'s |
| 81 // headers member." | 81 // headers member." |
| 82 // We don't create a copy of r's Headers object when init's headers member | 82 // We don't create a copy of r's Headers object when init's headers member |
| 83 // is present. | 83 // is present. |
| 84 RefPtrWillBeRawPtr<Headers> headers = nullptr; | 84 Headers* headers = 0; |
| 85 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { | 85 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { |
| 86 headers = r->headers()->createCopy(); | 86 headers = r->headers()->createCopy(); |
| 87 } | 87 } |
| 88 // "14. Empty |r|'s request's header list." | 88 // "14. Empty |r|'s request's header list." |
| 89 r->request()->headerList()->clearList(); | 89 r->request()->headerList()->clearList(); |
| 90 | 90 |
| 91 // "15. If |r|'s request's mode is no CORS, run these substeps: | 91 // "15. If |r|'s request's mode is no CORS, run these substeps: |
| 92 if (r->request()->mode() == FetchRequestData::NoCORSMode) { | 92 if (r->request()->mode() == FetchRequestData::NoCORSMode) { |
| 93 // "1. If |r|'s request's method is not a simple method, throw a | 93 // "1. If |r|'s request's method is not a simple method, throw a |
| 94 // TypeError." | 94 // TypeError." |
| 95 if (!FetchUtils::isSimpleMethod(r->request()->method())) { | 95 if (!FetchUtils::isSimpleMethod(r->request()->method())) { |
| 96 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); | 96 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); |
| 97 return nullptr; | 97 return 0; |
| 98 } | 98 } |
| 99 // "Set |r|'s Headers object's guard to |request-no-CORS|. | 99 // "Set |r|'s Headers object's guard to |request-no-CORS|. |
| 100 r->headers()->setGuard(Headers::RequestNoCORSGuard); | 100 r->headers()->setGuard(Headers::RequestNoCORSGuard); |
| 101 } | 101 } |
| 102 | 102 |
| 103 // "16. Fill |r|'s Headers object with |headers|. Rethrow any exceptions." | 103 // "16. Fill |r|'s Headers object with |headers|. Rethrow any exceptions." |
| 104 if (init.headers) { | 104 if (init.headers) { |
| 105 ASSERT(init.headersDictionary.isUndefinedOrNull()); | 105 ASSERT(init.headersDictionary.isUndefinedOrNull()); |
| 106 r->headers()->fillWith(init.headers.get(), exceptionState); | 106 r->headers()->fillWith(init.headers.get(), exceptionState); |
| 107 } else if (!init.headersDictionary.isUndefinedOrNull()) { | 107 } else if (!init.headersDictionary.isUndefinedOrNull()) { |
| 108 r->headers()->fillWith(init.headersDictionary, exceptionState); | 108 r->headers()->fillWith(init.headersDictionary, exceptionState); |
| 109 } else { | 109 } else { |
| 110 ASSERT(headers); | 110 ASSERT(headers); |
| 111 r->headers()->fillWith(headers.get(), exceptionState); | 111 r->headers()->fillWith(headers, exceptionState); |
| 112 } | 112 } |
| 113 if (exceptionState.hadException()) | 113 if (exceptionState.hadException()) |
| 114 return nullptr; | 114 return 0; |
| 115 // "17. If |init|'s body member is present, run these substeps:" | 115 // "17. If |init|'s body member is present, run these substeps:" |
| 116 if (init.bodyBlobHandle) { | 116 if (init.bodyBlobHandle) { |
| 117 // "1. Let |stream| and |Content-Type| be the result of extracting | 117 // "1. Let |stream| and |Content-Type| be the result of extracting |
| 118 // |init|'s body member." | 118 // |init|'s body member." |
| 119 // "2. Set |r|'s request's body to |stream|." | 119 // "2. Set |r|'s request's body to |stream|." |
| 120 // "3.If |Content-Type| is non-null and |r|'s request's header list | 120 // "3.If |Content-Type| is non-null and |r|'s request's header list |
| 121 // contains no header named `Content-Type`, append | 121 // contains no header named `Content-Type`, append |
| 122 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any | 122 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any |
| 123 // exception." | 123 // exception." |
| 124 r->setBodyBlobHandle(init.bodyBlobHandle); | 124 r->setBodyBlobHandle(init.bodyBlobHandle); |
| 125 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten
t-Type", exceptionState)) { | 125 if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Conten
t-Type", exceptionState)) { |
| 126 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex
ceptionState); | 126 r->headers()->append("Content-Type", init.bodyBlobHandle->type(), ex
ceptionState); |
| 127 } | 127 } |
| 128 if (exceptionState.hadException()) | 128 if (exceptionState.hadException()) |
| 129 return nullptr; | 129 return 0; |
| 130 } | 130 } |
| 131 // "18. Set |r|'s FetchBodyStream object's MIME type to the result of | 131 // "18. Set |r|'s FetchBodyStream object's MIME type to the result of |
| 132 // extracting a MIME type from |r|'s request's header list." | 132 // extracting a MIME type from |r|'s request's header list." |
| 133 // FIXME: We don't have MIME type in FetchBodyStream object yet. | 133 // FIXME: We don't have MIME type in FetchBodyStream object yet. |
| 134 | 134 |
| 135 // "19. Return |r|." | 135 // "19. Return |r|." |
| 136 return r.release(); | 136 return r; |
| 137 } | 137 } |
| 138 | 138 |
| 139 | |
| 140 } // namespace | 139 } // namespace |
| 141 | 140 |
| 142 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(Request); | 141 Request* Request::create(ExecutionContext* context, const String& input, Excepti
onState& exceptionState) |
| 143 | |
| 144 PassRefPtrWillBeRawPtr<Request> Request::create(ExecutionContext* context, const
String& input, ExceptionState& exceptionState) | |
| 145 { | 142 { |
| 146 return create(context, input, Dictionary(), exceptionState); | 143 return create(context, input, Dictionary(), exceptionState); |
| 147 } | 144 } |
| 148 | 145 |
| 149 PassRefPtrWillBeRawPtr<Request> Request::create(ExecutionContext* context, const
String& input, const Dictionary& init, ExceptionState& exceptionState) | 146 Request* Request::create(ExecutionContext* context, const String& input, const D
ictionary& init, ExceptionState& exceptionState) |
| 150 { | 147 { |
| 151 // "1. Let |request| be |input|'s associated request, if |input| is a | 148 // "1. Let |request| be |input|'s associated request, if |input| is a |
| 152 // Request object, and a new request otherwise." | 149 // Request object, and a new request otherwise." |
| 153 RefPtrWillBeRawPtr<FetchRequestData> request(FetchRequestData::create(contex
t)); | 150 FetchRequestData* request(FetchRequestData::create(context)); |
| 154 // "2. Set |request| to a restricted copy of itself." | 151 // "2. Set |request| to a restricted copy of itself." |
| 155 request = request->createRestrictedCopy(context, SecurityOrigin::create(cont
ext->url())); | 152 request = request->createRestrictedCopy(context, SecurityOrigin::create(cont
ext->url())); |
| 156 // "5. If |input| is a string, run these substeps:" | 153 // "5. If |input| is a string, run these substeps:" |
| 157 // "1. Let |parsedURL| be the result of parsing |input| with entry settings | 154 // "1. Let |parsedURL| be the result of parsing |input| with entry settings |
| 158 // object's API base URL." | 155 // object's API base URL." |
| 159 KURL parsedURL = context->completeURL(input); | 156 KURL parsedURL = context->completeURL(input); |
| 160 // "2. If |parsedURL| is failure, throw a TypeError." | 157 // "2. If |parsedURL| is failure, throw a TypeError." |
| 161 if (!parsedURL.isValid()) { | 158 if (!parsedURL.isValid()) { |
| 162 exceptionState.throwTypeError("Invalid URL"); | 159 exceptionState.throwTypeError("Invalid URL"); |
| 163 return nullptr; | 160 return 0; |
| 164 } | 161 } |
| 165 // "3. Set |request|'s url to |parsedURL|." | 162 // "3. Set |request|'s url to |parsedURL|." |
| 166 request->setURL(parsedURL); | 163 request->setURL(parsedURL); |
| 167 // "4. Set |fallbackMode| to CORS." | 164 // "4. Set |fallbackMode| to CORS." |
| 168 // "5. Set |fallbackCredentials| to omit." | 165 // "5. Set |fallbackCredentials| to omit." |
| 169 return createRequestWithRequestData(request.release(), RequestInit(context,
init, exceptionState), FetchRequestData::CORSMode, FetchRequestData::OmitCredent
ials, exceptionState); | 166 return createRequestWithRequestData(request, RequestInit(context, init, exce
ptionState), FetchRequestData::CORSMode, FetchRequestData::OmitCredentials, exce
ptionState); |
| 170 } | 167 } |
| 171 | 168 |
| 172 PassRefPtrWillBeRawPtr<Request> Request::create(ExecutionContext* context, Reque
st* input, ExceptionState& exceptionState) | 169 Request* Request::create(ExecutionContext* context, Request* input, ExceptionSta
te& exceptionState) |
| 173 { | 170 { |
| 174 return create(context, input, Dictionary(), exceptionState); | 171 return create(context, input, Dictionary(), exceptionState); |
| 175 } | 172 } |
| 176 | 173 |
| 177 PassRefPtrWillBeRawPtr<Request> Request::create(ExecutionContext* context, Reque
st* input, const Dictionary& init, ExceptionState& exceptionState) | 174 Request* Request::create(ExecutionContext* context, Request* input, const Dictio
nary& init, ExceptionState& exceptionState) |
| 178 { | 175 { |
| 179 // "1. Let |request| be |input|'s associated request, if |input| is a | 176 // "1. Let |request| be |input|'s associated request, if |input| is a |
| 180 // Request object, and a new request otherwise." | 177 // Request object, and a new request otherwise." |
| 181 // "2. Set |request| to a restricted copy of itself." | 178 // "2. Set |request| to a restricted copy of itself." |
| 182 RefPtrWillBeRawPtr<FetchRequestData> request(input->request()->createRestric
tedCopy(context, SecurityOrigin::create(context->url()))); | 179 FetchRequestData* request(input->request()->createRestrictedCopy(context, Se
curityOrigin::create(context->url()))); |
| 183 // "3. Let |fallbackMode| be null." | 180 // "3. Let |fallbackMode| be null." |
| 184 // "4. Let |fallbackCredentials| be null." | 181 // "4. Let |fallbackCredentials| be null." |
| 185 // Instead of using null as a special fallback value, just pass the current | 182 // Instead of using null as a special fallback value, just pass the current |
| 186 // mode and credentials; it has the same effect. | 183 // mode and credentials; it has the same effect. |
| 187 const FetchRequestData::Mode currentMode = request->mode(); | 184 const FetchRequestData::Mode currentMode = request->mode(); |
| 188 const FetchRequestData::Credentials currentCredentials = request->credential
s(); | 185 const FetchRequestData::Credentials currentCredentials = request->credential
s(); |
| 189 return createRequestWithRequestData(request.release(), RequestInit(context,
init, exceptionState), currentMode, currentCredentials, exceptionState); | 186 return createRequestWithRequestData(request, RequestInit(context, init, exce
ptionState), currentMode, currentCredentials, exceptionState); |
| 190 } | 187 } |
| 191 | 188 |
| 192 PassRefPtrWillBeRawPtr<Request> Request::create(PassRefPtrWillBeRawPtr<FetchRequ
estData> request) | 189 Request* Request::create(FetchRequestData* request) |
| 193 { | 190 { |
| 194 return adoptRefWillBeNoop(new Request(request)); | 191 return new Request(request); |
| 195 } | 192 } |
| 196 | 193 |
| 197 Request::Request(PassRefPtrWillBeRawPtr<FetchRequestData> request) | 194 Request::Request(FetchRequestData* request) |
| 198 : m_request(request) | 195 : m_request(request) |
| 199 , m_headers(Headers::create(m_request->headerList())) | 196 , m_headers(Headers::create(m_request->headerList())) |
| 200 { | 197 { |
| 201 m_headers->setGuard(Headers::RequestGuard); | 198 m_headers->setGuard(Headers::RequestGuard); |
| 202 ScriptWrappable::init(this); | 199 ScriptWrappable::init(this); |
| 203 } | 200 } |
| 204 | 201 |
| 205 PassRefPtrWillBeRawPtr<Request> Request::create(const WebServiceWorkerRequest& w
ebRequest) | 202 Request* Request::create(const WebServiceWorkerRequest& webRequest) |
| 206 { | 203 { |
| 207 return adoptRefWillBeNoop(new Request(webRequest)); | 204 return new Request(webRequest); |
| 208 } | 205 } |
| 209 | 206 |
| 210 Request::Request(const WebServiceWorkerRequest& webRequest) | 207 Request::Request(const WebServiceWorkerRequest& webRequest) |
| 211 : m_request(FetchRequestData::create(webRequest)) | 208 : m_request(FetchRequestData::create(webRequest)) |
| 212 , m_headers(Headers::create(m_request->headerList())) | 209 , m_headers(Headers::create(m_request->headerList())) |
| 213 { | 210 { |
| 214 m_headers->setGuard(Headers::RequestGuard); | 211 m_headers->setGuard(Headers::RequestGuard); |
| 215 ScriptWrappable::init(this); | 212 ScriptWrappable::init(this); |
| 216 } | 213 } |
| 217 | 214 |
| 218 String Request::method() const | 215 String Request::method() const |
| 219 { | 216 { |
| 220 // "The method attribute's getter must return request's method." | 217 // "The method attribute's getter must return request's method." |
| 221 return m_request->method(); | 218 return m_request->method(); |
| 222 } | 219 } |
| 223 | 220 |
| 224 String Request::url() const | 221 String Request::url() const |
| 225 { | 222 { |
| 226 // The url attribute's getter must return request's url, serialized with the
exclude fragment flag set. | 223 // The url attribute's getter must return request's url, serialized with the
exclude fragment flag set. |
| 227 if (!m_request->url().hasFragmentIdentifier()) | 224 if (!m_request->url().hasFragmentIdentifier()) |
| 228 return m_request->url(); | 225 return m_request->url(); |
| 229 KURL url(m_request->url()); | 226 KURL url(m_request->url()); |
| 230 url.removeFragmentIdentifier(); | 227 url.removeFragmentIdentifier(); |
| 231 return url; | 228 return url; |
| 232 } | 229 } |
| 233 | 230 |
| 234 PassRefPtrWillBeRawPtr<FetchBodyStream> Request::body(ExecutionContext* context) | 231 FetchBodyStream* Request::body(ExecutionContext* context) |
| 235 { | 232 { |
| 236 if (!m_request->blobDataHandle()) | 233 if (!m_request->blobDataHandle()) |
| 237 return nullptr; | 234 return 0; |
| 238 if (!m_fetchBodyStream) | 235 if (!m_fetchBodyStream) |
| 239 m_fetchBodyStream = FetchBodyStream::create(context, m_request->blobData
Handle()); | 236 m_fetchBodyStream = FetchBodyStream::create(context, m_request->blobData
Handle()); |
| 240 return m_fetchBodyStream; | 237 return m_fetchBodyStream; |
| 241 } | 238 } |
| 242 | 239 |
| 243 | 240 |
| 244 String Request::referrer() const | 241 String Request::referrer() const |
| 245 { | 242 { |
| 246 // "The referrer attribute's getter must return the empty string if | 243 // "The referrer attribute's getter must return the empty string if |
| 247 // request's referrer is none, and request's referrer, serialized, | 244 // request's referrer is none, and request's referrer, serialized, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 } | 286 } |
| 290 | 287 |
| 291 void Request::trace(Visitor* visitor) | 288 void Request::trace(Visitor* visitor) |
| 292 { | 289 { |
| 293 visitor->trace(m_request); | 290 visitor->trace(m_request); |
| 294 visitor->trace(m_headers); | 291 visitor->trace(m_headers); |
| 295 visitor->trace(m_fetchBodyStream); | 292 visitor->trace(m_fetchBodyStream); |
| 296 } | 293 } |
| 297 | 294 |
| 298 } // namespace blink | 295 } // namespace blink |
| OLD | NEW |