Response* Response::create(ScriptState* scriptState, ScriptValue bodyValue, const Dictionary& init, ExceptionState& exceptionState) { v8::Local<v8::Value> body = bodyValue.v8Value(); ScriptValue reader; v8::Isolate* isolate = scriptState->isolate(); ExecutionContext* executionContext = scriptState->executionContext(); OwnPtr<FetchDataConsumerHandle> bodyHandle; String contentType; if (bodyValue.isUndefined() || bodyValue.isNull()) { // Note: The IDL processor cannot handle this situation. See // https://crbug.com/335871. } else if (V8Blob::hasInstance(body, isolate)) { Blob* blob = V8Blob::toImpl(body.As<v8::Object>()); bodyHandle = FetchBlobDataConsumerHandle::create(executionContext, blob->blobDataHandle()); contentType = blob->type(); } else if (V8ArrayBuffer::hasInstance(body, isolate)) { bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBuffer::toImpl(body.As<v8::Object>())); } else if (V8ArrayBufferView::hasInstance(body, isolate)) { bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBufferView::toImpl(body.As<v8::Object>())); } else if (V8FormData::hasInstance(body, isolate)) { RefPtr<EncodedFormData> formData = V8FormData::toImpl(body.As<v8::Object>())->encodeMultiPartFormData(); // Here we handle formData->boundary() as a C-style string. See // FormDataEncoder::generateUniqueBoundaryString. contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + formData->boundary().data(); bodyHandle = FetchFormDataConsumerHandle::create(executionContext, formData.release()); } else if (RuntimeEnabledFeatures::responseConstructedWithReadableStreamEnabled() && ReadableStreamOperations::isReadableStream(scriptState, bodyValue)) { bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, bodyValue); reader = ReadableStreamOperations::getReader(scriptState, bodyValue, exceptionState); if (exceptionState.hadException()) { reader = ScriptValue(); bodyHandle = createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle()); exceptionState.clearException(); } else { bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, reader); } } else { String string = toUSVString(isolate, body, exceptionState); if (exceptionState.hadException()) return nullptr; bodyHandle = FetchFormDataConsumerHandle::create(string); contentType = "text/plain;charset=UTF-8"; } // TODO(yhirano): Add the URLSearchParams case. Response* response = create(executionContext, bodyHandle.release(), contentType, ResponseInit(init, exceptionState), exceptionState); if (!exceptionState.hadException() && !reader.isEmpty()) { // Add a hidden reference so that the weak persistent in the // ReadableStreamDataConsumerHandle will be valid as long as the // Response is valid. v8::Local<v8::Value> wrapper = toV8(response, scriptState); if (wrapper.IsEmpty()) { exceptionState.throwTypeError("Cannot create a Response wrapper"); return nullptr; } ASSERT(wrapper->IsObject()); V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8HiddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Value()); } return response; }
static void constructor2(const v8::FunctionCallbackInfo<v8::Value>& info) { ExceptionState exceptionState(ExceptionState::ConstructionContext, "TestInterfaceConstructor4", info.Holder(), info.GetIsolate()); V8StringResource<> usvStringArg; { usvStringArg = toUSVString(info.GetIsolate(), info[0], exceptionState); if (exceptionState.throwIfNeeded()) return; } RefPtr<TestInterfaceConstructor4> impl = TestInterfaceConstructor4::create(usvStringArg); v8::Local<v8::Object> wrapper = info.Holder(); wrapper = impl->associateWithWrapper(info.GetIsolate(), &V8TestInterfaceConstructor4::wrapperTypeInfo, wrapper); v8SetReturnValue(info, wrapper); }
RequestInit::RequestInit(ExecutionContext* context, const Dictionary& options, ExceptionState& exceptionState) { DictionaryHelper::get(options, "method", method); DictionaryHelper::get(options, "headers", headers); if (!headers) { Vector<Vector<String>> headersVector; if (DictionaryHelper::get(options, "headers", headersVector, exceptionState)) headers = Headers::create(headersVector, exceptionState); else DictionaryHelper::get(options, "headers", headersDictionary); } DictionaryHelper::get(options, "mode", mode); DictionaryHelper::get(options, "credentials", credentials); v8::Local<v8::Value> body; if (!DictionaryHelper::get(options, "body", body) || body->IsUndefined() || body->IsNull()) return; OwnPtr<BlobData> blobData = BlobData::create(); v8::Isolate* isolate = toIsolate(context); if (body->IsArrayBuffer()) { DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(v8::Local<v8::Object>::Cast(body)); ASSERT(arrayBuffer); blobData->appendBytes(arrayBuffer->data(), arrayBuffer->byteLength()); } else if (body->IsArrayBufferView()) { DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(v8::Local<v8::Object>::Cast(body)); ASSERT(arrayBufferView); blobData->appendBytes(arrayBufferView->baseAddress(), arrayBufferView->byteLength()); } else if (V8Blob::hasInstance(body, isolate)) { Blob* blob = V8Blob::toImpl(v8::Local<v8::Object>::Cast(body)); ASSERT(blob); blob->appendTo(*blobData); blobData->setContentType(blob->type()); } else if (V8FormData::hasInstance(body, isolate)) { DOMFormData* domFormData = V8FormData::toImpl(v8::Local<v8::Object>::Cast(body)); ASSERT(domFormData); RefPtr<FormData> httpBody = domFormData->createMultiPartFormData(); for (size_t i = 0; i < httpBody->elements().size(); ++i) { const FormDataElement& element = httpBody->elements()[i]; switch (element.m_type) { case FormDataElement::data: { blobData->appendBytes(element.m_data.data(), element.m_data.size()); break; } case FormDataElement::encodedFile: blobData->appendFile(element.m_filename, element.m_fileStart, element.m_fileLength, element.m_expectedFileModificationTime); break; case FormDataElement::encodedBlob: if (element.m_optionalBlobDataHandle) blobData->appendBlob(element.m_optionalBlobDataHandle, 0, element.m_optionalBlobDataHandle->size()); break; case FormDataElement::encodedFileSystemURL: blobData->appendFileSystemURL(element.m_fileSystemURL, element.m_fileStart, element.m_fileLength, element.m_expectedFileModificationTime); break; default: ASSERT_NOT_REACHED(); } } blobData->setContentType(AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + httpBody->boundary().data()); } else if (body->IsString()) { String stringValue(toUSVString(isolate, body, exceptionState)); blobData->appendText(stringValue, false); blobData->setContentType("text/plain;charset=UTF-8"); } else { return; } const long long blobSize = blobData->length(); bodyBlobHandle = BlobDataHandle::create(blobData.release(), blobSize); }
RequestInit::RequestInit(ExecutionContext* context, const Dictionary& options, ExceptionState& exceptionState) : opaque(false), isReferrerSet(false) { bool areAnyMembersSet = false; areAnyMembersSet = DictionaryHelper::get(options, "method", method) || areAnyMembersSet; areAnyMembersSet = DictionaryHelper::get(options, "headers", headers) || areAnyMembersSet; if (!headers) { Vector<Vector<String>> headersVector; if (DictionaryHelper::get(options, "headers", headersVector, exceptionState)) { headers = Headers::create(headersVector, exceptionState); areAnyMembersSet = true; } else { areAnyMembersSet = DictionaryHelper::get(options, "headers", headersDictionary) || areAnyMembersSet; } } areAnyMembersSet = DictionaryHelper::get(options, "mode", mode) || areAnyMembersSet; areAnyMembersSet = DictionaryHelper::get(options, "credentials", credentials) || areAnyMembersSet; areAnyMembersSet = DictionaryHelper::get(options, "redirect", redirect) || areAnyMembersSet; AtomicString referrerString; bool isReferrerStringSet = DictionaryHelper::get(options, "referrer", referrerString); areAnyMembersSet = areAnyMembersSet || isReferrerStringSet; areAnyMembersSet = DictionaryHelper::get(options, "integrity", integrity) || areAnyMembersSet; v8::Local<v8::Value> v8Body; bool isBodySet = DictionaryHelper::get(options, "body", v8Body); areAnyMembersSet = areAnyMembersSet || isBodySet; if (areAnyMembersSet) { // If any of init's members are present, unset request's // omit-Origin-header flag, set request's referrer to "client", // and request's referrer policy to the empty string. // // We need to use "about:client" instead of |clientReferrerString|, // because "about:client" => |clientReferrerString| conversion is done // in Request::createRequestWithRequestOrString. referrer = Referrer("about:client", ReferrerPolicyDefault); if (isReferrerStringSet) referrer.referrer = referrerString; isReferrerSet = true; } if (!isBodySet || v8Body->IsUndefined() || v8Body->IsNull()) return; v8::Isolate* isolate = toIsolate(context); if (v8Body->IsArrayBuffer()) { body = FetchFormDataConsumerHandle::create(V8ArrayBuffer::toImpl(v8::Local<v8::Object>::Cast(v8Body))); } else if (v8Body->IsArrayBufferView()) { body = FetchFormDataConsumerHandle::create(V8ArrayBufferView::toImpl(v8::Local<v8::Object>::Cast(v8Body))); } else if (V8Blob::hasInstance(v8Body, isolate)) { RefPtr<BlobDataHandle> blobDataHandle = V8Blob::toImpl(v8::Local<v8::Object>::Cast(v8Body))->blobDataHandle(); contentType = blobDataHandle->type(); body = FetchBlobDataConsumerHandle::create(context, blobDataHandle.release()); } else if (V8FormData::hasInstance(v8Body, isolate)) { FormData* domFormData = V8FormData::toImpl(v8::Local<v8::Object>::Cast(v8Body)); opaque = domFormData->opaque(); RefPtr<EncodedFormData> formData = domFormData->encodeMultiPartFormData(); // Here we handle formData->boundary() as a C-style string. See // FormDataEncoder::generateUniqueBoundaryString. contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + formData->boundary().data(); body = FetchFormDataConsumerHandle::create(context, formData.release()); } else if (v8Body->IsString()) { contentType = "text/plain;charset=UTF-8"; body = FetchFormDataConsumerHandle::create(toUSVString(isolate, v8Body, exceptionState)); } }