Example #1
0
bool CurlCacheEntry::saveResponseHeaders(const ResourceResponse& response)
{
    PlatformFileHandle headerFile = openFile(m_headerFilename, OpenForWrite);
    if (!isHandleValid(headerFile)) {
        LOG(Network, "Cache Error: Could not open %s for write\n", m_headerFilename.latin1().data());
        return false;
    }

    // Headers
    HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin();
    HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end();
    while (it != end) {
        String headerField = it->key;
        headerField.append(": ");
        headerField.append(it->value);
        headerField.append("\n");
        CString headerFieldLatin1 = headerField.latin1();
        writeToFile(headerFile, headerFieldLatin1.data(), headerFieldLatin1.length());
        m_cachedResponse.setHTTPHeaderField(it->key, it->value);
        ++it;
    }

    closeFile(headerFile);
    return true;
}
Example #2
0
String DOMWindowBase64::btoa(const String& stringToEncode, ExceptionState& exceptionState)
{
    if (stringToEncode.isNull())
        return String();

    if (!stringToEncode.containsOnlyLatin1()) {
        exceptionState.throwDOMException(InvalidCharacterError, "The string to be encoded contains characters outside of the Latin1 range.");
        return String();
    }

    return base64Encode(stringToEncode.latin1());
}
Example #3
0
TextCodecBrew::TextCodecBrew(const TextEncoding& encoding)
    : m_charsetConverter(0)
    , m_encoding(encoding)
    , m_numBufferedBytes(0)
{
    String format = String::format("%s>%s", encoding.name(), m_internalEncodingName);

    IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell;
    AEECLSID classID = ISHELL_GetHandler(shell, AEEIID_ICharsetConv, format.latin1().data());
    ISHELL_CreateInstance(shell, classID, reinterpret_cast<void**>(&m_charsetConverter));

    ASSERT(m_charsetConverter);
}
Example #4
0
bool CurlCacheEntry::loadFileToBuffer(const String& filepath, Vector<char>& buffer)
{
    // Open the file
    PlatformFileHandle inputFile = openFile(filepath, OpenForRead);
    if (!isHandleValid(inputFile)) {
        LOG(Network, "Cache Error: Could not open %s for read\n", filepath.latin1().data());
        return false;
    }

    long long filesize = -1;
    if (!getFileSize(filepath, filesize)) {
        LOG(Network, "Cache Error: Could not get file size of %s\n", filepath.latin1().data());
        closeFile(inputFile);
        return false;
    }

    // Load the file content into buffer
    buffer.resize(filesize);
    int bufferPosition = 0;
    int bufferReadSize = 4096;
    int bytesRead = 0;
    while (filesize > bufferPosition) {
        if (filesize - bufferPosition < bufferReadSize)
            bufferReadSize = filesize - bufferPosition;

        bytesRead = readFromFile(inputFile, buffer.data() + bufferPosition, bufferReadSize);
        if (bytesRead != bufferReadSize) {
            LOG(Network, "Cache Error: Could not read from %s\n", filepath.latin1().data());
            closeFile(inputFile);
            return false;
        }

        bufferPosition += bufferReadSize;
    }
    closeFile(inputFile);
    return true;
}
CString openTemporaryFile(const char*, PlatformFileHandle& handle)
{
    handle = INVALID_HANDLE_VALUE;

    wchar_t tempPath[MAX_PATH];
    int tempPathLength = ::GetTempPath(_countof(tempPath), tempPath);
    if (tempPathLength <= 0 || tempPathLength > _countof(tempPath))
        return CString();

    HCRYPTPROV hCryptProv = 0;
    if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        return CString();

    String proposedPath;
    while (1) {

        wchar_t tempFile[] = L"XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names)
        const int randomPartLength = 8;
        if (!CryptGenRandom(hCryptProv, randomPartLength * 2, reinterpret_cast<BYTE*>(tempFile)))
            break;

        // Limit to valid filesystem characters, also excluding others that could be problematic, like punctuation.
        // don't include both upper and lowercase since Windows file systems are typically not case sensitive.
        const char validChars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
        for (int i = 0; i < randomPartLength; ++i)
            tempFile[i] = validChars[tempFile[i] % (sizeof(validChars) - 1)];

        ASSERT(wcslen(tempFile) * 2 == sizeof(tempFile) - 2);

        proposedPath = pathByAppendingComponent(String(tempPath), String(tempFile));

        // use CREATE_NEW to avoid overwriting an existing file with the same name
        handle = CreateFile(proposedPath.charactersWithNullTermination(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
        if (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS)
            continue;

        break;
    }

    CryptReleaseContext(hCryptProv, 0);

    if (!isHandleValid(handle))
        return CString();

    return proposedPath.latin1();
}
Example #6
0
CurlCacheEntry::CurlCacheEntry(const String& url, ResourceHandle* job, const String& cacheDir)
    : m_headerFilename(cacheDir)
    , m_contentFilename(cacheDir)
    , m_contentFile(invalidPlatformFileHandle)
    , m_entrySize(0)
    , m_expireDate(-1)
    , m_headerParsed(false)
    , m_job(job)
{
    generateBaseFilename(url.latin1());

    m_headerFilename.append(m_basename);
    m_headerFilename.append(".header");

    m_contentFilename.append(m_basename);
    m_contentFilename.append(".content");
}
// We can't use String::format for two reasons:
//  1) It doesn't handle non-ASCII characters in the format string.
//  2) It doesn't handle the %2$d syntax.
// Note that because |format| is used as the second parameter to va_start, it cannot be a reference
// type according to section 18.7/3 of the C++ N1905 standard.
static String formatLocalizedString(String format, ...)
{
#if USE(CF)
    va_list arguments;
    va_start(arguments, format);
    RetainPtr<CFStringRef> formatCFString(AdoptCF, format.createCFString());
    RetainPtr<CFStringRef> result(AdoptCF, CFStringCreateWithFormatAndArguments(0, 0, formatCFString.get(), arguments));
    va_end(arguments);
    return result.get();
#elif PLATFORM(QT)
    va_list arguments;
    va_start(arguments, format);
    QString result;
    result.vsprintf(format.latin1().data(), arguments);
    va_end(arguments);
    return result;
#else
    notImplemented();
    return format;
#endif
}
Example #8
0
LanguageManager::LanguageManager()
{
    IEnumCodePage* enumInterface;
    IMultiLanguage* mli = FontCache::getMultiLanguageInterface();
    if (mli && S_OK == mli->EnumCodePages(MIMECONTF_BROWSER, &enumInterface)) {
        MIMECPINFO cpInfo;
        ULONG ccpInfo;
        while (S_OK == enumInterface->Next(1, &cpInfo, &ccpInfo) && ccpInfo) {
            if (!IsValidCodePage(cpInfo.uiCodePage))
                continue;

            HashMap<UINT, CString>::iterator i = codePageCharsets().find(cpInfo.uiCodePage);

            CString name(String(cpInfo.wszWebCharset).latin1());
            if (i == codePageCharsets().end()) {
                CharsetInfo info;
                info.m_codePage = cpInfo.uiCodePage;
                knownCharsets().set(name.data(), info);
                i = codePageCharsets().set(cpInfo.uiCodePage, name).first;
            }
            if (i != codePageCharsets().end()) {
                HashMap<String, CharsetInfo>::iterator j = knownCharsets().find(String(i->second.data(), i->second.length()));
                ASSERT(j != knownCharsets().end());
                CharsetInfo& info = j->second;
                info.m_name = i->second.data();
                info.m_friendlyName = cpInfo.wszDescription;
                info.m_aliases.append(name);
                info.m_aliases.append(String(cpInfo.wszHeaderCharset).latin1());
                info.m_aliases.append(String(cpInfo.wszBodyCharset).latin1());
                String cpName = makeString("cp", String::number(cpInfo.uiCodePage));
                info.m_aliases.append(cpName.latin1());
                supportedCharsets().add(i->second.data());
            }
        }
        enumInterface->Release();
    }
}
void FrameLoaderClientBlackBerry::dispatchDidFinishLoad()
{
    didFinishOrFailLoading(ResourceError());

    if (m_webPagePrivate->m_dumpRenderTree)
        m_webPagePrivate->m_dumpRenderTree->didFinishLoadForFrame(m_frame);

    if (!isMainFrame() || m_webPagePrivate->m_webSettings->isEmailMode()
        || !m_frame->document() || !m_frame->document()->head())
        return;

    HTMLHeadElement* headElement = m_frame->document()->head();
    // FIXME: Handle NOSCRIPT special case?

    // Process document metadata.
    RefPtr<NodeList> nodeList = headElement->getElementsByTagName(HTMLNames::metaTag.localName());
    unsigned int size = nodeList->length();
    ScopeArray<WebString> headers;

    // This may allocate more space than needed since not all meta elements will be http-equiv.
    headers.reset(new WebString[2 * size]);
    unsigned headersLength = 0;

    for (unsigned i = 0; i < size; ++i) {
        HTMLMetaElement* metaElement = static_cast<HTMLMetaElement*>(nodeList->item(i));
        if (WTF::equalIgnoringCase(metaElement->name(), "apple-mobile-web-app-capable")
            && WTF::equalIgnoringCase(metaElement->content().stripWhiteSpace(), "yes"))
            m_webPagePrivate->m_client->setWebAppCapable();
        else {
            String httpEquiv = metaElement->httpEquiv().stripWhiteSpace();
            String content = metaElement->content().stripWhiteSpace();

            if (!httpEquiv.isNull() && !content.isNull()) {
                headers[headersLength++] = httpEquiv;
                headers[headersLength++] = content;
            }
        }
    }

    if (headersLength > 0)
        m_webPagePrivate->m_client->setMetaHeaders(headers, headersLength);

    nodeList = headElement->getElementsByTagName(HTMLNames::linkTag.localName());
    size = nodeList->length();

    for (unsigned i = 0; i < size; ++i) {
        HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(nodeList->item(i));
        String href = linkElement->href().string();
        if (!href.isEmpty()) {
            String title = linkElement->title();

            if (WTF::equalIgnoringCase(linkElement->rel(), "apple-touch-icon"))
                m_webPagePrivate->m_client->setLargeIcon(href.latin1().data());
            else if (WTF::equalIgnoringCase(linkElement->rel(), "search")) {
                if (WTF::equalIgnoringCase(linkElement->type(), "application/opensearchdescription+xml"))
                    m_webPagePrivate->m_client->setSearchProviderDetails(title.utf8().data(), href.utf8().data());
            } else if (WTF::equalIgnoringCase(linkElement->rel(), "alternate")
                && (WTF::equalIgnoringCase(linkElement->type(), "application/rss+xml")
                || WTF::equalIgnoringCase(linkElement->type(), "application/atom+xml")))
                m_webPagePrivate->m_client->setAlternateFeedDetails(title.utf8().data(), href.utf8().data());
        }
    }

#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
    if (!m_webPagePrivate->m_webSettings->isPrivateBrowsingEnabled())
        credentialManager().autofillPasswordForms(m_frame->document()->forms());
#endif
}
Example #10
0
void FormData::appendKeyValuePairItems(const FormDataList& list, const WTF::TextEncoding& encoding, bool isMultiPartForm, Document* document, EncodingType encodingType)
{
    if (isMultiPartForm)
        m_boundary = FormDataBuilder::generateUniqueBoundaryString();

    Vector<char> encodedData;

    const Vector<FormDataList::Item>& items = list.items();
    size_t formDataListSize = items.size();
    ASSERT(!(formDataListSize % 2));
    for (size_t i = 0; i < formDataListSize; i += 2) {
        const FormDataList::Item& key = items[i];
        const FormDataList::Item& value = items[i + 1];
        if (isMultiPartForm) {
            Vector<char> header;
            FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());

            // If the current type is blob, then we also need to include the filename
            if (value.blob()) {
                String name;
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    // For file blob, use the filename (or relative path if it is present) as the name.
                    name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();

                    // If a filename is passed in FormData.append(), use it instead of the file blob's name.
                    if (!value.filename().isNull())
                        name = value.filename();
                } else {
                    // For non-file blob, use the filename if it is passed in FormData.append().
                    if (!value.filename().isNull())
                        name = value.filename();
                    else
                        name = "blob";
                }

                // We have to include the filename=".." part in the header, even if the filename is empty
                FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);

                // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
                String contentType;
                if (value.blob()->type().isEmpty())
                    contentType = "application/octet-stream";
                else
                    contentType = value.blob()->type();
                FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.latin1());
            }

            FormDataBuilder::finishMultiPartHeader(header);

            // Append body
            appendData(header.data(), header.size());
            if (value.blob()) {
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    // Do not add the file if the path is empty.
                    if (!file->path().isEmpty())
                        appendFile(file->path());
                    if (!file->fileSystemURL().isEmpty())
                        appendURL(file->fileSystemURL());
                }
                else
                    appendBlob(value.blob()->url());
            } else
                appendData(value.data().data(), value.data().length());
            appendData("\r\n", 2);
        } else {
            // Omit the name "isindex" if it's the first form data element.
            // FIXME: Why is this a good rule? Is this obsolete now?
            if (encodedData.isEmpty() && key.data() == "isindex")
                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
            else
                FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
        }
    }

    if (isMultiPartForm)
        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);

    appendData(encodedData.data(), encodedData.size());
}
void ResourceHandleManager::add(ResourceHandle* job)
{
    ResourceHandleInternal* d = job->getInternal();
    DeprecatedString url = job->url().url();
    d->m_handle = curl_easy_init();
    curl_easy_setopt(d->m_handle, CURLOPT_PRIVATE, job);
    curl_easy_setopt(d->m_handle, CURLOPT_ERRORBUFFER, m_curlErrorBuffer);
    curl_easy_setopt(d->m_handle, CURLOPT_WRITEFUNCTION, writeCallback);
    curl_easy_setopt(d->m_handle, CURLOPT_WRITEDATA, job);
    curl_easy_setopt(d->m_handle, CURLOPT_HEADERFUNCTION, headerCallback);
    curl_easy_setopt(d->m_handle, CURLOPT_WRITEHEADER, job);
    curl_easy_setopt(d->m_handle, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(d->m_handle, CURLOPT_MAXREDIRS, 10);
    curl_easy_setopt(d->m_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_easy_setopt(d->m_handle, CURLOPT_SHARE, m_curlShareHandle);
    // enable gzip and deflate through Accept-Encoding:
    curl_easy_setopt(d->m_handle, CURLOPT_ENCODING, "");

    // url must remain valid through the request
    ASSERT(!d->m_url);
    d->m_url = strdup(url.ascii());
    curl_easy_setopt(d->m_handle, CURLOPT_URL, d->m_url);

    if (m_cookieJarFileName) {
        curl_easy_setopt(d->m_handle, CURLOPT_COOKIEFILE, m_cookieJarFileName);
        curl_easy_setopt(d->m_handle, CURLOPT_COOKIEJAR, m_cookieJarFileName);
    }

    if (job->requestHeaders().size() > 0) {
        struct curl_slist* headers = 0;
        HTTPHeaderMap customHeaders = job->requestHeaders();
        HTTPHeaderMap::const_iterator end = customHeaders.end();
        for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it) {
            String key = it->first;
            String value = it->second;
            String headerString = key + ": " + value;
            const char* header = headerString.latin1().data();
            headers = curl_slist_append(headers, header);
        }
        curl_easy_setopt(d->m_handle, CURLOPT_HTTPHEADER, headers);
        d->m_customHeaders = headers;
    }

    // default to GET
    curl_easy_setopt(d->m_handle, CURLOPT_HTTPGET, TRUE);

    if ("POST" == job->method())
        setupPOST(job);
    else if ("PUT" == job->method())
        setupPUT(job);
    else if ("HEAD" == job->method())
        curl_easy_setopt(d->m_handle, CURLOPT_NOBODY, TRUE);

    CURLMcode ret = curl_multi_add_handle(m_curlMultiHandle, d->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, job->url().url().ascii());
#endif
        job->cancel();
        return;
    }

    if (!m_downloadTimer.isActive())
        m_downloadTimer.startOneShot(pollTimeSeconds);
}
void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::TextEncoding& encoding, bool isMultiPartForm, FormData::EncodingType encodingType)
{
    if (isMultiPartForm)
        formData->setBoundary(FormDataBuilder::generateUniqueBoundaryString());

    Vector<char> encodedData;

    const WillBeHeapVector<Item>& items = this->items();
    size_t formDataListSize = items.size();
    ASSERT(!(formDataListSize % 2));
    for (size_t i = 0; i < formDataListSize; i += 2) {
        const FormDataList::Item& key = items[i];
        const FormDataList::Item& value = items[i + 1];
        if (isMultiPartForm) {
            Vector<char> header;
            FormDataBuilder::beginMultiPartHeader(header, formData->boundary().data(), key.data());

            // If the current type is blob, then we also need to include the filename
            if (value.blob()) {
                String name;
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    // For file blob, use the filename (or relative path if it is present) as the name.
                    name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();

                    // If a filename is passed in FormData.append(), use it instead of the file blob's name.
                    if (!value.filename().isNull())
                        name = value.filename();
                } else {
                    // For non-file blob, use the filename if it is passed in FormData.append().
                    if (!value.filename().isNull())
                        name = value.filename();
                    else
                        name = "blob";
                }

                // We have to include the filename=".." part in the header, even if the filename is empty
                FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);

                // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
                String contentType;
                if (value.blob()->type().isEmpty())
                    contentType = "application/octet-stream";
                else
                    contentType = value.blob()->type();
                FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.latin1());
            }

            FormDataBuilder::finishMultiPartHeader(header);

            // Append body
            formData->appendData(header.data(), header.size());
            if (value.blob()) {
                if (value.blob()->hasBackingFile()) {
                    File* file = toFile(value.blob());
                    // Do not add the file if the path is empty.
                    if (!file->path().isEmpty())
                        formData->appendFile(file->path());
                    if (!file->fileSystemURL().isEmpty())
                        formData->appendFileSystemURL(file->fileSystemURL());
                } else {
                    formData->appendBlob(value.blob()->uuid(), value.blob()->blobDataHandle());
                }
            } else {
                formData->appendData(value.data().data(), value.data().length());
            }
            formData->appendData("\r\n", 2);
        } else {
            FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
        }
    }

    if (isMultiPartForm)
        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, formData->boundary().data(), true);

    formData->appendData(encodedData.data(), encodedData.size());
}
Example #13
0
void HTMLDocument::determineParseMode()
{
    // FIXME: It's terrible that this code runs separately and isn't just built in to the
    // HTML tokenizer/parser.

    // This code more or less mimics Mozilla's implementation (specifically the
    // doctype parsing implemented by David Baron in Mozilla's nsParser.cpp).
    //
    // There are three possible parse modes:
    // COMPAT - quirks mode emulates WinIE and NS4.  CSS parsing is also relaxed in this mode, e.g., unit types can
    // be omitted from numbers.
    // ALMOST STRICT - This mode is identical to strict mode except for its treatment of line-height in the inline box model.  For
    // now (until the inline box model is re-written), this mode is identical to STANDARDS mode.
    // STRICT - no quirks apply.  Web pages will obey the specifications to the letter.
    bool wasInCompatMode = inCompatMode();
    DocumentType* docType = doctype();
    if (!docType || !equalIgnoringCase(docType->name(), "html"))
        // No doctype found at all or the doctype is not HTML.  Default to quirks mode and Html4.
        setParseMode(Compat);
    else if (!doctype()->systemId().isEmpty() && equalIgnoringCase(docType->systemId(), "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"))
        // Assume quirks mode for this particular system ID.  In the HTML5 spec, this is the only
        // system identifier that is examined.
        setParseMode(Compat);
    else if (docType->publicId().isEmpty())
        // A doctype without a public ID means use strict mode.
        setParseMode(Strict);
    else {
        // We have to check a list of public IDs to see what we
        // should do.
        String lowerPubID = docType->publicId().lower();
        CString pubIDStr = lowerPubID.latin1();
       
#ifdef ANDROID_META_SUPPORT
        if ((!frame()->tree() || !frame()->tree()->parent()) &&
                strstr(pubIDStr.data(), "-//wapforum//dtd xhtml mobile 1.") == pubIDStr.data()) {
            // fit mobile sites directly in the screen
            frame()->settings()->setMetadataSettings("width", "device-width");
        }
#endif
        // Look up the entry in our gperf-generated table.
        const PubIDInfo* doctypeEntry = findDoctypeEntry(pubIDStr.data(), pubIDStr.length());
        if (!doctypeEntry)
            // The DOCTYPE is not in the list.  Assume strict mode.
            setParseMode(Strict);
        else {
            switch (docType->systemId().isEmpty() ?
                    doctypeEntry->mode_if_no_sysid :
                    doctypeEntry->mode_if_sysid) {
                case PubIDInfo::eQuirks3:
                case PubIDInfo::eQuirks:
                    setParseMode(Compat);
                    break;
                case PubIDInfo::eAlmostStandards:
                    setParseMode(AlmostStrict);
                    break;
                 default:
                    ASSERT(false);
            }
        }
    }
    
    if (inCompatMode() != wasInCompatMode)
        updateStyleSelector();
}