PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url) { if (shouldTreatAsUniqueOrigin(url)) { RefPtr<SecurityOrigin> origin = adoptRef(new SecurityOrigin()); if (url.protocolIs("file")) { // Unfortunately, we can't represent all unique origins exactly // the same way because we need to produce a quirky database // identifier for file URLs due to persistent storage in some // embedders of WebKit. origin->m_needsDatabaseIdentifierQuirkForFiles = true; } return origin.release(); } if (shouldUseInnerURL(url)) return adoptRef(new SecurityOrigin(extractInnerURL(url))); return adoptRef(new SecurityOrigin(url)); }
void deleteCookie(const Document*, const KURL& url, const String& name) { CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); if (!cookieStorage) return; RetainPtr<CFURLRef> urlCF(AdoptCF, url.createCFURL()); bool sendSecureCookies = url.protocolIs("https"); RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookiesForURL(cookieStorage, urlCF.get(), sendSecureCookies)); CFIndex count = CFArrayGetCount(cookiesCF.get()); for (CFIndex i = 0; i < count; i++) { CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookiesCF.get(), i); String cookieName = CFHTTPCookieGetName(cookie); if (cookieName == name) { CFHTTPCookieStorageDeleteCookie(cookieStorage, cookie); break; } } }
bool DOMFileSystemBase::crackFileSystemURL(const KURL& url, FileSystemType& type, String& filePath) { if (!url.protocolIs("filesystem")) return false; if (!url.innerURL()) return false; String typeString = url.innerURL()->path().substring(1); if (typeString == temporaryPathPrefix) type = FileSystemTypeTemporary; else if (typeString == persistentPathPrefix) type = FileSystemTypePersistent; else if (typeString == externalPathPrefix) type = FileSystemTypeExternal; else return false; filePath = decodeURLEscapeSequences(url.path()); return true; }
void ResourceHandleManager::startJob(ResourceHandle* job) { KURL kurl = job->request().url(); if (kurl.protocolIs("data")) { parseDataUrl(job); return; } initializeHandle(job); m_runningJobs++; CURLMcode ret = curl_multi_add_handle(m_curlMultiHandle, job->getInternal()->m_handle); // don't call perform, because events must be async // timeout will occur and do curl_multi_perform if (ret && ret != CURLM_CALL_MULTI_PERFORM) { #ifndef NDEBUG printf("Error %d starting job %s\n", ret, encodeWithURLEscapeSequences(job->request().url().string()).latin1().data()); #endif job->cancel(); return; } }
void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job) { KURL kurl = job->request().url(); if (kurl.protocolIs("data")) { parseDataUrl(job); return; } initializeHandle(job); ResourceHandleInternal* handle = job->getInternal(); // curl_easy_perform blocks until the transfert is finished. CURLcode ret = curl_easy_perform(handle->m_handle); if (ret != 0) { ResourceError error(String(handle->m_url), ret, String(handle->m_url), String(curl_easy_strerror(ret))); handle->client()->didFail(job, error); } curl_easy_cleanup(handle->m_handle); }
void preconnectHost(const KURL& host, const CrossOriginAttributeValue crossOrigin) const override { m_didPreconnect = true; m_isHTTPS = host.protocolIs("https"); m_isCrossOrigin = (crossOrigin == CrossOriginAttributeAnonymous); }
// We copied the KURL version here on Dec 4, 2009 while doing a WebKit // merge. // // FIXME Somehow share this with KURL? Like we'd theoretically merge with // decodeURLEscapeSequences below? bool portAllowed(const KURL& url) { unsigned short port = url.port(); // Since most URLs don't have a port, return early for the "no port" case. if (!port) return true; // This blocked port list matches the port blocking that Mozilla implements. // See http://www.mozilla.org/projects/netlib/PortBanning.html for more information. static const unsigned short blockedPortList[] = { 1, // tcpmux 7, // echo 9, // discard 11, // systat 13, // daytime 15, // netstat 17, // qotd 19, // chargen 20, // FTP-data 21, // FTP-control 22, // SSH 23, // telnet 25, // SMTP 37, // time 42, // name 43, // nicname 53, // domain 77, // priv-rjs 79, // finger 87, // ttylink 95, // supdup 101, // hostriame 102, // iso-tsap 103, // gppitnp 104, // acr-nema 109, // POP2 110, // POP3 111, // sunrpc 113, // auth 115, // SFTP 117, // uucp-path 119, // nntp 123, // NTP 135, // loc-srv / epmap 139, // netbios 143, // IMAP2 179, // BGP 389, // LDAP 465, // SMTP+SSL 512, // print / exec 513, // login 514, // shell 515, // printer 526, // tempo 530, // courier 531, // Chat 532, // netnews 540, // UUCP 556, // remotefs 563, // NNTP+SSL 587, // ESMTP 601, // syslog-conn 636, // LDAP+SSL 993, // IMAP+SSL 995, // POP3+SSL 2049, // NFS 3659, // apple-sasl / PasswordServer [Apple addition] 4045, // lockd 6000, // X11 6665, // Alternate IRC [Apple addition] 6666, // Alternate IRC [Apple addition] 6667, // Standard IRC [Apple addition] 6668, // Alternate IRC [Apple addition] 6669, // Alternate IRC [Apple addition] invalidPortNumber, // Used to block all invalid port numbers }; const unsigned short* const blockedPortListEnd = blockedPortList + sizeof(blockedPortList) / sizeof(blockedPortList[0]); #ifndef NDEBUG // The port list must be sorted for binary_search to work. static bool checkedPortList = false; if (!checkedPortList) { for (const unsigned short* p = blockedPortList; p != blockedPortListEnd - 1; ++p) ASSERT(*p < *(p + 1)); checkedPortList = true; } #endif // If the port is not in the blocked port list, allow it. if (!binary_search(blockedPortList, blockedPortListEnd, port)) return true; // Allow ports 21 and 22 for FTP URLs, as Mozilla does. if ((port == 21 || port == 22) && url.protocolIs("ftp")) return true; // Allow any port number in a file URL, since the port number is ignored. if (url.protocolIs("file")) return true; return false; }
bool parseManifest(const KURL& manifestURL, const char* data, int length, Manifest& manifest) { ASSERT(manifest.explicitURLs.isEmpty()); ASSERT(manifest.onlineWhitelistedURLs.isEmpty()); ASSERT(manifest.fallbackURLs.isEmpty()); manifest.allowAllNetworkRequests = false; Mode mode = Explicit; RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/cache-manifest", "UTF-8"); String s = decoder->decode(data, length); s += decoder->flush(); // Look for the magic signature: "^\xFEFF?CACHE MANIFEST[ \t]?" (the BOM is removed by TextResourceDecoder). // Example: "CACHE MANIFEST #comment" is a valid signature. // Example: "CACHE MANIFEST;V2" is not. if (!s.startsWith("CACHE MANIFEST")) return false; const UChar* end = s.characters() + s.length(); const UChar* p = s.characters() + 14; // "CACHE MANIFEST" is 14 characters. if (p < end && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r') return false; // Skip to the end of the line. while (p < end && *p != '\r' && *p != '\n') p++; while (1) { // Skip whitespace while (p < end && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t')) p++; if (p == end) break; const UChar* lineStart = p; // Find the end of the line while (p < end && *p != '\r' && *p != '\n') p++; // Check if we have a comment if (*lineStart == '#') continue; // Get rid of trailing whitespace const UChar* tmp = p - 1; while (tmp > lineStart && (*tmp == ' ' || *tmp == '\t')) tmp--; String line(lineStart, tmp - lineStart + 1); if (line == "CACHE:") mode = Explicit; else if (line == "FALLBACK:") mode = Fallback; else if (line == "NETWORK:") mode = OnlineWhitelist; else if (line.endsWith(":")) mode = Unknown; else if (mode == Unknown) continue; else if (mode == Explicit || mode == OnlineWhitelist) { const UChar* p = line.characters(); const UChar* lineEnd = p + line.length(); // Look for whitespace separating the URL from subsequent ignored tokens. while (p < lineEnd && *p != '\t' && *p != ' ') p++; if (mode == OnlineWhitelist && p - line.characters() == 1 && *line.characters() == '*') { // Wildcard was found. manifest.allowAllNetworkRequests = true; continue; } KURL url(manifestURL, String(line.characters(), p - line.characters())); if (!url.isValid()) continue; if (url.hasFragmentIdentifier()) url.removeFragmentIdentifier(); if (!equalIgnoringCase(url.protocol(), manifestURL.protocol())) continue; if (mode == Explicit && manifestURL.protocolIs("https") && !protocolHostAndPortAreEqual(manifestURL, url)) continue; if (mode == Explicit) manifest.explicitURLs.add(url.string()); else manifest.onlineWhitelistedURLs.append(url); } else if (mode == Fallback) { const UChar* p = line.characters(); const UChar* lineEnd = p + line.length(); // Look for whitespace separating the two URLs while (p < lineEnd && *p != '\t' && *p != ' ') p++; if (p == lineEnd) { // There was no whitespace separating the URLs. continue; } KURL namespaceURL(manifestURL, String(line.characters(), p - line.characters())); if (!namespaceURL.isValid()) continue; if (namespaceURL.hasFragmentIdentifier()) namespaceURL.removeFragmentIdentifier(); if (!protocolHostAndPortAreEqual(manifestURL, namespaceURL)) continue; // Skip whitespace separating fallback namespace from URL. while (p < lineEnd && (*p == '\t' || *p == ' ')) p++; // Look for whitespace separating the URL from subsequent ignored tokens. const UChar* fallbackStart = p; while (p < lineEnd && *p != '\t' && *p != ' ') p++; KURL fallbackURL(manifestURL, String(fallbackStart, p - fallbackStart)); if (!fallbackURL.isValid()) continue; if (fallbackURL.hasFragmentIdentifier()) fallbackURL.removeFragmentIdentifier(); if (!protocolHostAndPortAreEqual(manifestURL, fallbackURL)) continue; manifest.fallbackURLs.append(make_pair(namespaceURL, fallbackURL)); } else ASSERT_NOT_REACHED(); } return true; }
PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger) { ASSERT(form); HTMLFormControlElement* submitButton = 0; if (event && event->target()) { for (Node* node = event->target()->toNode(); node; node = node->parentNode()) { if (node->isElementNode() && toElement(node)->isFormControlElement()) { submitButton = static_cast<HTMLFormControlElement*>(node); break; } } } FormSubmission::Attributes copiedAttributes; copiedAttributes.copyFrom(attributes); if (submitButton) { String attributeValue; if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull()) copiedAttributes.parseAction(attributeValue); if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull()) copiedAttributes.updateEncodingType(attributeValue); if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull()) copiedAttributes.updateMethodType(attributeValue); if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull()) copiedAttributes.setTarget(attributeValue); } Document* document = form->document(); KURL actionURL = document->completeURL(copiedAttributes.action().isEmpty() ? document->url().string() : copiedAttributes.action()); bool isMailtoForm = actionURL.protocolIs("mailto"); bool isMultiPartForm = false; String encodingType = copiedAttributes.encodingType(); if (copiedAttributes.method() == PostMethod) { isMultiPartForm = copiedAttributes.isMultiPartForm(); if (isMultiPartForm && isMailtoForm) { encodingType = "application/x-www-form-urlencoded"; isMultiPartForm = false; } } TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document); RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission()); Vector<pair<String, String> > formValues; bool containsPasswordData = false; for (unsigned i = 0; i < form->associatedElements().size(); ++i) { FormAssociatedElement* control = form->associatedElements()[i]; HTMLElement* element = toHTMLElement(control); if (!element->isDisabledFormControl()) control->appendFormData(*domFormData, isMultiPartForm); if (element->hasLocalName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(control); if (input->isTextField()) { formValues.append(pair<String, String>(input->name().string(), input->value())); input->addSearchResult(); } if (input->isPasswordField() && !input->value().isEmpty()) containsPasswordData = true; } } RefPtr<FormData> formData; String boundary; if (isMultiPartForm) { formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), document); boundary = formData->boundary().data(); } else { formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::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 = FormData::create(); } } formData->setIdentifier(generateFormDataIdentifier()); formData->setContainsPasswordData(containsPasswordData); String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document->baseTarget() : copiedAttributes.target(); RefPtr<FormState> formState = FormState::create(form, formValues, document, trigger); return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event)); }
void PageSerializer::serializeFrame(Frame* frame) { Document* document = frame->document(); KURL url = document->url(); if (!url.isValid() || url.protocolIs("about")) { // For blank frames we generate a fake URL so they can be referenced by their containing frame. url = urlForBlankFrame(frame); } if (m_resourceURLs.contains(url)) { // FIXME: We could have 2 frame with the same URL but which were dynamically changed and have now // different content. So we should serialize both and somehow rename the frame src in the containing // frame. Arg! return; } Vector<Node*> nodes; SerializerMarkupAccumulator accumulator(this, document, &nodes); TextEncoding textEncoding(document->charset()); CString data; if (!textEncoding.isValid()) { // FIXME: iframes used as images trigger this. We should deal with them correctly. return; } String text = accumulator.serializeNodes(document->documentElement(), 0, IncludeNode); CString frameHTML = textEncoding.encode(text.characters(), text.length(), EntitiesForUnencodables); m_resources->append(Resource(url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length()))); m_resourceURLs.add(url); for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) { Node* node = *iter; if (!node->isElementNode()) continue; Element* element = toElement(node); // We have to process in-line style as it might contain some resources (typically background images). if (element->isStyledElement()) retrieveResourcesForCSSDeclaration(static_cast<StyledElement*>(element)->inlineStyleDecl(), document); if (element->hasTagName(HTMLNames::imgTag)) { HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(element); KURL url = document->completeURL(imageElement->getAttribute(HTMLNames::srcAttr)); CachedImage* cachedImage = imageElement->cachedImage(); addImageToResources(cachedImage, imageElement->renderer(), url); } else if (element->hasTagName(HTMLNames::linkTag)) { HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(element); if (CSSStyleSheet* sheet = linkElement->sheet()) { KURL url = document->completeURL(linkElement->getAttribute(HTMLNames::hrefAttr)); serializeCSSStyleSheet(sheet, url); ASSERT(m_resourceURLs.contains(url)); } } else if (element->hasTagName(HTMLNames::styleTag)) { HTMLStyleElement* styleElement = static_cast<HTMLStyleElement*>(element); if (CSSStyleSheet* sheet = styleElement->sheet()) serializeCSSStyleSheet(sheet, KURL()); } } for (Frame* childFrame = frame->tree()->firstChild(); childFrame; childFrame = childFrame->tree()->nextSibling()) serializeFrame(childFrame); }
void CookieManager::getRawCookies(Vector<ParsedCookie*> &stackOfCookies, const KURL& requestURL, CookieFilter filter) const { if (!m_syncedWithDatabase && !m_privateMode) { LOG_ERROR("CookieManager is calling getRawCookies before database values are loaded."); return; } CookieLog("CookieManager - getRawCookies - processing url with domain - %s & protocol: %s & path: %s\n", requestURL.host().utf8().data(), requestURL.protocol().utf8().data(), requestURL.path().utf8().data()); const bool invalidScheme = shouldIgnoreScheme(requestURL.protocol()); const bool specialCaseForWebWorks = invalidScheme && m_shouldDumpAllCookies; const bool isConnectionSecure = requestURL.protocolIs("https") || requestURL.protocolIs("wss") || specialCaseForWebWorks; Vector<ParsedCookie*> cookieCandidates; Vector<CookieMap*> protocolsToSearch; // Special Case: If a server sets a "secure" cookie over a non-secure channel and tries to access the cookie // over a secure channel, it will not succeed because the secure protocol isn't mapped to the insecure protocol yet. // Set the map to the non-secure version, so it'll search the mapping for a secure cookie. CookieMap* targetMap = m_managerMap.get(requestURL.protocol()); if (!targetMap && isConnectionSecure) { CookieLog("CookieManager - special case: secure protocol are not linked yet."); if (requestURL.protocolIs("https")) targetMap = m_managerMap.get("http"); else if (requestURL.protocolIs("wss")) targetMap = m_managerMap.get("ws"); } // Decide which scheme tree we should look at. // Return on invalid schemes. cookies are currently disabled on file and local. // We only want to enable them for WebWorks that enabled a special flag. if (specialCaseForWebWorks) copyValuesToVector(m_managerMap, protocolsToSearch); else if (invalidScheme) return; else { protocolsToSearch.append(targetMap); // FIXME: this is a hack for webworks apps; RFC 6265 says "Cookies do not provide isolation by scheme" // so we should not be checking protocols at all. See PR 135595 if (m_shouldDumpAllCookies) { protocolsToSearch.append(m_managerMap.get("file")); protocolsToSearch.append(m_managerMap.get("local")); } } Vector<String> delimitedHost; // IP addresses are stored in a particular format (due to ipv6). Reduce the ip address so we can match // it with the one in memory. string canonicalIP = BlackBerry::Platform::getCanonicalIPFormat(requestURL.host().utf8().data()); if (!canonicalIP.empty()) delimitedHost.append(String(canonicalIP.c_str())); else requestURL.host().lower().split(".", true, delimitedHost); // Go through all the protocol trees that we need to search for // and get all cookies that are valid for this domain for (size_t k = 0; k < protocolsToSearch.size(); k++) { CookieMap* currentMap = protocolsToSearch[k]; // if no cookies exist for this protocol, break right away if (!currentMap) continue; CookieLog("CookieManager - looking at protocol map %s \n", currentMap->getName().utf8().data()); // Special case for local and files - because WebApps expect to get ALL cookies from the backing-store on local protocol if (specialCaseForWebWorks) { CookieLog("CookieManager - special case find in protocol map - %s\n", currentMap->getName().utf8().data()); currentMap->getAllChildCookies(&cookieCandidates); } else { // Get cookies from the null domain map currentMap->getAllCookies(&cookieCandidates); // Get cookies from the valid domain maps int i = delimitedHost.size() - 1; while (i >= 0) { CookieLog("CookieManager - finding %s in currentmap\n", delimitedHost[i].utf8().data()); currentMap = currentMap->getSubdomainMap(delimitedHost[i]); // if this subdomain/domain does not exist in our mapping then we simply exit if (!currentMap) { CookieLog("CookieManager - cannot find next map exiting the while loop.\n"); break; } CookieLog("CookieManager - found the map, grabbing cookies from this map\n"); currentMap->getAllCookies(&cookieCandidates); i--; } } } CookieLog("CookieManager - there are %d cookies in candidate\n", cookieCandidates.size()); for (size_t i = 0; i < cookieCandidates.size(); ++i) { ParsedCookie* cookie = cookieCandidates[i]; // According to the path-matches rules in RFC6265, section 5.1.4, // we should add a '/' at the end of cookie-path for comparison if the cookie-path is not end with '/'. String path = cookie->path(); CookieLog("CookieManager - comparing cookie path %s (len %d) to request path %s (len %d)", path.utf8().data(), path.length(), requestURL.path().utf8().data(), path.length()); if (!equalIgnoringCase(path, requestURL.path()) && !path.endsWith("/", false)) path = path + "/"; // Only secure connections have access to secure cookies. Unless specialCaseForWebWorks is true. // Get the cookies filtering out HttpOnly cookies if requested. if (requestURL.path().startsWith(path, false) && (isConnectionSecure || !cookie->isSecure()) && (filter == WithHttpOnlyCookies || !cookie->isHttpOnly())) { CookieLog("CookieManager - cookie chosen - %s\n", cookie->toString().utf8().data()); cookie->setLastAccessed(currentTime()); stackOfCookies.append(cookie); } } std::stable_sort(stackOfCookies.begin(), stackOfCookies.end(), cookieSorter); }
void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority) { while (!requestsPending.isEmpty()) { Request* request = requestsPending.first(); DocLoader* docLoader = request->docLoader(); bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator(); // If the document is fully parsed and there are no pending stylesheets there won't be any more // resources that we would want to push to the front of the queue. Just hand off the remaining resources // to the networking layer. bool parsedAndStylesheetsKnown = !docLoader->doc()->parsing() && docLoader->doc()->haveStylesheetsLoaded(); if (!parsedAndStylesheetsKnown && !resourceIsCacheValidator && m_requestsLoading.size() >= m_maxRequestsInFlight) { serveLowerPriority = false; return; } requestsPending.removeFirst(); ResourceRequest resourceRequest(request->cachedResource()->url()); if (!request->cachedResource()->accept().isEmpty()) resourceRequest.setHTTPAccept(request->cachedResource()->accept()); KURL referrer = docLoader->doc()->url(); if ((referrer.protocolIs("http") || referrer.protocolIs("https")) && referrer.path().isEmpty()) referrer.setPath("/"); resourceRequest.setHTTPReferrer(referrer.string()); FrameLoader::addHTTPOriginIfNeeded(resourceRequest, docLoader->doc()->securityOrigin()->toString()); if (resourceIsCacheValidator) { CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate(); ASSERT(resourceToRevalidate->canUseCacheValidator()); ASSERT(resourceToRevalidate->isLoaded()); const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified"); const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag"); if (!lastModified.isEmpty() || !eTag.isEmpty()) { ASSERT(docLoader->cachePolicy() != CachePolicyReload); if (docLoader->cachePolicy() == CachePolicyRevalidate) resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0"); if (!lastModified.isEmpty()) resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified); if (!eTag.isEmpty()) resourceRequest.setHTTPHeaderField("If-None-Match", eTag); } } RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(), this, resourceRequest, request->shouldSkipCanLoadCheck(), request->sendResourceLoadCallbacks()); if (loader) { m_requestsLoading.add(loader.release(), request); request->cachedResource()->setRequestedFromNetworkingLayer(); #if REQUEST_DEBUG printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data()); #endif } else { docLoader->decrementRequestCount(); docLoader->setLoadInProgress(true); request->cachedResource()->error(); docLoader->setLoadInProgress(false); delete request; } } }
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)); }
void CookieManager::getRawCookies(Vector<ParsedCookie*> &stackOfCookies, const KURL& requestURL, CookieFilter filter) const { CookieLog("CookieManager - getRawCookies - processing url with domain - %s & protocol: %s & path: %s\n", requestURL.host().utf8().data(), requestURL.protocol().utf8().data(), requestURL.path().utf8().data()); bool specialCaseForLocal = (requestURL.protocolIs("local") || requestURL.protocolIs("file")) && m_shouldDumpAllCookies; bool isConnectionSecure = requestURL.protocolIs("https") || requestURL.protocolIs("wss") || specialCaseForLocal; Vector<ParsedCookie*> cookieCandidates; Vector<CookieMap*> protocolsToSearch; if (specialCaseForLocal) copyValuesToVector(m_managerMap, protocolsToSearch); else { protocolsToSearch.append(m_managerMap.get(requestURL.protocol())); // FIXME: this is a hack for webworks apps; RFC 6265 says "Cookies do not provide isolation by scheme" // so we should not be checking protocols at all. See PR 135595 if (m_shouldDumpAllCookies) { protocolsToSearch.append(m_managerMap.get("file")); protocolsToSearch.append(m_managerMap.get("local")); } } Vector<String> delimitedHost; requestURL.host().lower().split(".", true, delimitedHost); // Go through all the protocol trees that we need to search for // and get all cookies that are valid for this domain for (size_t k = 0; k < protocolsToSearch.size(); k++) { CookieMap* currentMap = protocolsToSearch[k]; // if no cookies exist for this protocol, break right away if (!currentMap) continue; CookieLog("CookieManager - looking at protocol map %s \n", currentMap->getName().utf8().data()); // Special case for local and files - because WebApps expect to get ALL cookies from the backing-store on local protocol if (specialCaseForLocal) { CookieLog("CookieManager - special case find in protocol map - %s\n", currentMap->getName().utf8().data()); currentMap->getAllChildCookies(&cookieCandidates); } else { // Get cookies from the null domain map currentMap->getAllCookies(&cookieCandidates); // Get cookies from the valid domain maps int i = delimitedHost.size() - 1; while (i >= 0) { CookieLog("CookieManager - finding %s in currentmap\n", delimitedHost[i].utf8().data()); currentMap = currentMap->getSubdomainMap(delimitedHost[i]); // if this subdomain/domain does not exist in our mapping then we simply exit if (!currentMap) { CookieLog("CookieManager - cannot find next map exiting the while loop.\n"); break; } CookieLog("CookieManager - found the map, grabbing cookies from this map\n"); currentMap->getAllCookies(&cookieCandidates); i--; } } } CookieLog("CookieManager - there are %d cookies in candidate\n", cookieCandidates.size()); for (size_t i = 0; i < cookieCandidates.size(); ++i) { ParsedCookie* cookie = cookieCandidates[i]; // According to the path-matches rules in RFC6265, section 5.1.4, // we should add a '/' at the end of cookie-path for comparison if the cookie-path is not end with '/'. String path = cookie->path(); CookieLog("CookieManager - comparing cookie path %s (len %d) to request path %s (len %d)", path.utf8().data(), path.length(), requestURL.path().utf8().data(), path.length()); if (!equalIgnoringCase(path, requestURL.path()) && !path.endsWith("/", false)) path += "/"; // Only secure connections have access to secure cookies. Unless specialCaseForLocal is true // Get the cookies filtering out HttpOnly cookies if requested. if (requestURL.path().startsWith(path, false) && (isConnectionSecure || !cookie->isSecure()) && (filter == WithHttpOnlyCookies || !cookie->isHttpOnly())) { CookieLog("CookieManager - cookie chosen - %s\n", cookie->toString().utf8().data()); cookie->setLastAccessed(currentTime()); stackOfCookies.append(cookie); } } std::stable_sort(stackOfCookies.begin(), stackOfCookies.end(), cookieSorter); }
void FrameFetchContext::upgradeInsecureRequest(FetchRequest& fetchRequest) { KURL url = fetchRequest.resourceRequest().url(); // Tack an 'Upgrade-Insecure-Requests' header to outgoing navigational requests, as described in // https://w3c.github.io/webappsec/specs/upgrade/#feature-detect if (fetchRequest.resourceRequest().frameType() != WebURLRequest::FrameTypeNone) fetchRequest.mutableResourceRequest().addHTTPHeaderField("Upgrade-Insecure-Requests", "1"); if (m_document && m_document->insecureRequestsPolicy() == SecurityContext::InsecureRequestsUpgrade && url.protocolIs("http")) { ASSERT(m_document->insecureNavigationsToUpgrade()); // We always upgrade requests that meet any of the following criteria: // // 1. Are for subresources (including nested frames). // 2. Are form submissions. // 3. Whose hosts are contained in the document's InsecureNavigationSet. const ResourceRequest& request = fetchRequest.resourceRequest(); if (request.frameType() == WebURLRequest::FrameTypeNone || request.frameType() == WebURLRequest::FrameTypeNested || request.requestContext() == WebURLRequest::RequestContextForm || (!url.host().isNull() && m_document->insecureNavigationsToUpgrade()->contains(url.host().impl()->hash()))) { UseCounter::count(m_document, UseCounter::UpgradeInsecureRequestsUpgradedRequest); url.setProtocol("https"); if (url.port() == 80) url.setPort(443); fetchRequest.mutableResourceRequest().setURL(url); } } }