PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData( String& contentType) const { if (m_additionalData.isURLSearchParams()) { // If |additionalData| is a 'URLSearchParams' object, build a urlencoded // response. URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit()); URLSearchParams* additionalData = m_additionalData.getAsURLSearchParams(); for (const auto& param : additionalData->params()) { const String& name = param.first; if (name != idName() && name != passwordName()) params->append(name, param.second); } params->append(idName(), id()); params->append(passwordName(), password()); contentType = AtomicString("application/x-www-form-urlencoded;charset=UTF-8"); return params->toEncodedFormData(); } // Otherwise, we'll build a multipart response. FormData* formData = FormData::create(nullptr); if (m_additionalData.isFormData()) { FormData* additionalData = m_additionalData.getAsFormData(); for (const FormData::Entry* entry : additionalData->entries()) { const String& name = formData->decode(entry->name()); if (name == idName() || name == passwordName()) continue; if (entry->blob()) formData->append(name, entry->blob(), entry->filename()); else formData->append(name, formData->decode(entry->value())); } } formData->append(idName(), id()); formData->append(passwordName(), password()); RefPtr<EncodedFormData> encodedData = formData->encodeMultiPartFormData(); contentType = AtomicString("multipart/form-data; boundary=") + encodedData->boundary().data(); return encodedData.release(); }
PassRefPtrWillBeRawPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtrWillBeRawPtr<Event> event) { ASSERT(form); HTMLFormControlElement* submitButton = 0; if (event && event->target()) { for (Node* node = event->target()->toNode(); node; node = node->parentOrShadowHostNode()) { if (node->isElementNode() && toElement(node)->isFormControlElement()) { submitButton = toHTMLFormControlElement(node); break; } } } FormSubmission::Attributes copiedAttributes; copiedAttributes.copyFrom(attributes); if (submitButton) { AtomicString attributeValue; if (!(attributeValue = submitButton->fastGetAttribute(formactionAttr)).isNull()) copiedAttributes.parseAction(attributeValue); if (!(attributeValue = submitButton->fastGetAttribute(formenctypeAttr)).isNull()) copiedAttributes.updateEncodingType(attributeValue); if (!(attributeValue = submitButton->fastGetAttribute(formmethodAttr)).isNull()) copiedAttributes.updateMethodType(attributeValue); if (!(attributeValue = submitButton->fastGetAttribute(formtargetAttr)).isNull()) copiedAttributes.setTarget(attributeValue); } if (copiedAttributes.method() == DialogMethod) { if (submitButton) return adoptRefWillBeNoop(new FormSubmission(submitButton->resultForDialogSubmit())); return adoptRefWillBeNoop(new FormSubmission("")); } Document& document = form->document(); KURL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action()); bool isMailtoForm = actionURL.protocolIs("mailto"); bool isMultiPartForm = false; AtomicString encodingType = copiedAttributes.encodingType(); if (copiedAttributes.method() == PostMethod) { isMultiPartForm = copiedAttributes.isMultiPartForm(); if (isMultiPartForm && isMailtoForm) { encodingType = AtomicString("application/x-www-form-urlencoded", AtomicString::ConstructFromLiteral); isMultiPartForm = false; } } WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataEncoder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document.encoding()); FormData* domFormData = FormData::create(dataEncoding.encodingForFormSubmission()); bool containsPasswordData = false; for (unsigned i = 0; i < form->associatedElements().size(); ++i) { FormAssociatedElement* control = form->associatedElements()[i]; ASSERT(control); HTMLElement& element = toHTMLElement(*control); if (!element.isDisabledFormControl()) control->appendToFormData(*domFormData); if (isHTMLInputElement(element)) { HTMLInputElement& input = toHTMLInputElement(element); if (input.type() == InputTypeNames::password && !input.value().isEmpty()) containsPasswordData = true; } } RefPtr<EncodedFormData> formData; String boundary; if (isMultiPartForm) { formData = domFormData->encodeMultiPartFormData(); boundary = formData->boundary().data(); } else { formData = domFormData->encodeFormData(attributes.method() == GetMethod ? EncodedFormData::FormURLEncoded : EncodedFormData::parseEncodingType(encodingType)); if (copiedAttributes.method() == PostMethod && isMailtoForm) { // Convert the form data into a string that we put into the URL. appendMailtoPostFormDataToURL(actionURL, *formData, encodingType); formData = EncodedFormData::create(); } } formData->setIdentifier(generateFormDataIdentifier()); formData->setContainsPasswordData(containsPasswordData); AtomicString targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target(); return adoptRefWillBeNoop(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, form, formData.release(), boundary, event)); }
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)); } }