Server:
10666 Client: p4web-viewer
Path:
 
Files   Submitted   Branches   Labels   Clients   Users   Jobs   Settings  
Display tree view Display revision history Display revision history Display revision history thumbnails Show branching history View head revision text Cancel operation Show recent activity Show P4 command input Information Help
View File Revision Text:  
//webkit/Dreamweaver-CS4/WebKit/WebKit/win/WebURLResponse.cpp #1
Type: text Client: //p4web-viewer/webkit/Dreamweaver-CS4/WebKit/WebKit/win/WebURLResponse.cpp Size: 16.39 KB
Head: #1

Show line numbers
/*
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "WebKitDLL.h"
#include <initguid.h>
#include "WebURLResponse.h"

#include "HTTPHeaderPropertyBag.h"
#include "MarshallingHelpers.h"
#include "WebLocalizableStrings.h"

#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <wtf/platform.h>
#pragma warning( push, 0 )
#include <WebCore/BString.h>
#include <WebCore/DeprecatedString.h>
#include <WebCore/KURL.h>
#include <WebCore/ResourceHandle.h>
#pragma warning( pop )
#include <shlobj.h>
#include <shlwapi.h>
#include <tchar.h>

using namespace WebCore;

static LPCTSTR CFHTTPMessageCopyLocalizedShortDescriptionForStatusCode(CFIndex statusCode)
{
    LPCTSTR result = 0;
    if (statusCode < 100 || statusCode >= 600)
        result = LPCTSTR_UI_STRING("server error", "HTTP result code string");
    else if (statusCode >= 100 && statusCode <= 199) {
        switch (statusCode) {
            case 100:
                result = LPCTSTR_UI_STRING("continue", "HTTP result code string");
                break;
            case 101:
                result = LPCTSTR_UI_STRING("switching protocols", "HTTP result code string");
                break;
            default:
                result = LPCTSTR_UI_STRING("informational", "HTTP result code string");
                break;
        }
    } else if (statusCode >= 200 && statusCode <= 299) {
        switch (statusCode) {
            case 200:
                result = LPCTSTR_UI_STRING("no error", "HTTP result code string");
                break;
            case 201:
                result = LPCTSTR_UI_STRING("created", "HTTP result code string");
                break;
            case 202:
                result = LPCTSTR_UI_STRING("accepted", "HTTP result code string");
                break;
            case 203:
                result = LPCTSTR_UI_STRING("non-authoritative information", "HTTP result code string");
                break;
            case 204:
                result = LPCTSTR_UI_STRING("no content", "HTTP result code string");
                break;
            case 205:
                result = LPCTSTR_UI_STRING("reset content", "HTTP result code string");
                break;
            case 206:
                result = LPCTSTR_UI_STRING("partial content", "HTTP result code string");
                break;
            default:
                result = LPCTSTR_UI_STRING("success", "HTTP result code string");
                break;
        } 
    } else if (statusCode >= 300 && statusCode <= 399) {
        switch (statusCode) {
            case 300:
                result = LPCTSTR_UI_STRING("multiple choices", "HTTP result code string");
                break;
            case 301:
                result = LPCTSTR_UI_STRING("moved permanently", "HTTP result code string");
                break;
            case 302:
                result = LPCTSTR_UI_STRING("found", "HTTP result code string");
                break;
            case 303:
                result = LPCTSTR_UI_STRING("see other", "HTTP result code string");
                break;
            case 304:
                result = LPCTSTR_UI_STRING("not modified", "HTTP result code string");
                break;
            case 305:
                result = LPCTSTR_UI_STRING("needs proxy", "HTTP result code string");
                break;
            case 307:
                result = LPCTSTR_UI_STRING("temporarily redirected", "HTTP result code string");
                break;
            case 306:   // 306 status code unused in HTTP
            default:
                result = LPCTSTR_UI_STRING("redirected", "HTTP result code string");
                break;
        }
    } else if (statusCode >= 400 && statusCode <= 499) {
        switch (statusCode) {
            case 400:
                result = LPCTSTR_UI_STRING("bad request", "HTTP result code string");
                break;
            case 401:
                result = LPCTSTR_UI_STRING("unauthorized", "HTTP result code string");
                break;
            case 402:
                result = LPCTSTR_UI_STRING("payment required", "HTTP result code string");
                break;
            case 403:
                result = LPCTSTR_UI_STRING("forbidden", "HTTP result code string");
                break;
            case 404:
                result = LPCTSTR_UI_STRING("not found", "HTTP result code string");
                break;
            case 405:
                result = LPCTSTR_UI_STRING("method not allowed", "HTTP result code string");
                break;
            case 406:
                result = LPCTSTR_UI_STRING("unacceptable", "HTTP result code string");
                break;
            case 407:
                result = LPCTSTR_UI_STRING("proxy authentication required", "HTTP result code string");
                break;
            case 408:
                result = LPCTSTR_UI_STRING("request timed out", "HTTP result code string");
                break;
            case 409:
                result = LPCTSTR_UI_STRING("conflict", "HTTP result code string");
                break;
            case 410:
                result = LPCTSTR_UI_STRING("no longer exists", "HTTP result code string");
                break;
            case 411:
                result = LPCTSTR_UI_STRING("length required", "HTTP result code string");
                break;
            case 412:
                result = LPCTSTR_UI_STRING("precondition failed", "HTTP result code string");
                break;
            case 413:
                result = LPCTSTR_UI_STRING("request too large", "HTTP result code string");
                break;
            case 414:
                result = LPCTSTR_UI_STRING("requested URL too long", "HTTP result code string");
                break;
            case 415:
                result = LPCTSTR_UI_STRING("unsupported media type", "HTTP result code string");
                break;
            case 416:
                result = LPCTSTR_UI_STRING("requested range not satisfiable", "HTTP result code string");
                break;
            case 417:
                result = LPCTSTR_UI_STRING("expectation failed", "HTTP result code string");
                break;
            default:
                result = LPCTSTR_UI_STRING("client error", "HTTP result code string");
                break;
        }
    } else if (statusCode >= 500 && statusCode <= 599) {
        switch (statusCode) {
            case 500:
                result = LPCTSTR_UI_STRING("internal server error", "HTTP result code string");
                break;
            case 501:
                result = LPCTSTR_UI_STRING("unimplemented", "HTTP result code string");
                break;
            case 502:
                result = LPCTSTR_UI_STRING("bad gateway", "HTTP result code string");
                break;
            case 503:
                result = LPCTSTR_UI_STRING("service unavailable", "HTTP result code string");
                break;
            case 504:
                result = LPCTSTR_UI_STRING("gateway timed out", "HTTP result code string");
                break;
            case 505:
                result = LPCTSTR_UI_STRING("unsupported version", "HTTP result code string");
                break;
            default:
                result = LPCTSTR_UI_STRING("server error", "HTTP result code string");
                break;
        }
    }
    return result;
}

// IWebURLResponse ----------------------------------------------------------------

WebURLResponse::WebURLResponse()
    :m_refCount(0)
{
    gClassCount++;
}

WebURLResponse::~WebURLResponse()
{
    gClassCount--;
}

WebURLResponse* WebURLResponse::createInstance()
{
    WebURLResponse* instance = new WebURLResponse();
    // fake an http response - so it has the IWebHTTPURLResponse interface
    instance->m_response = ResourceResponse(String("http://").deprecatedString(), String(), 0, String(), String());
    instance->AddRef();
    return instance;
}

WebURLResponse* WebURLResponse::createInstance(const ResourceResponse& response)
{
    if (response.isNull())
        return 0;

    WebURLResponse* instance = new WebURLResponse();
    instance->AddRef();
    instance->m_response = response;

    return instance;
}

// IUnknown -------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebURLResponse::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebURLResponse*>(this);
    else if (IsEqualGUID(riid, IID_WebURLResponse))
        *ppvObject = static_cast<WebURLResponse*>(this);
    else if (IsEqualGUID(riid, IID_IWebURLResponse))
        *ppvObject = static_cast<IWebURLResponse*>(this);
    else if (IsEqualGUID(riid, IID_IWebURLResponsePrivate))
        *ppvObject = static_cast<IWebURLResponsePrivate*>(this);
    else if (m_response.isHTTP() && IsEqualGUID(riid, IID_IWebHTTPURLResponse))
        *ppvObject = static_cast<IWebHTTPURLResponse*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE WebURLResponse::AddRef(void)
{
    return ++m_refCount;
}

ULONG STDMETHODCALLTYPE WebURLResponse::Release(void)
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete(this);

    return newRef;
}

// IWebURLResponse --------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebURLResponse::expectedContentLength( 
    /* [retval][out] */ long long* result)
{
    *result = m_response.expectedContentLength();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::initWithURL( 
    /* [in] */ BSTR url,
    /* [in] */ BSTR mimeType,
    /* [in] */ int expectedContentLength,
    /* [in] */ BSTR textEncodingName)
{
    m_response = ResourceResponse(String(url).deprecatedString(), String(mimeType), expectedContentLength, String(textEncodingName), String());
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::MIMEType( 
    /* [retval][out] */ BSTR* result)
{
    BString mimeType(m_response.mimeType());
    *result = mimeType.release();
    if (!m_response.mimeType().isNull() && !*result)
        return E_OUTOFMEMORY;

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::suggestedFilename( 
    /* [retval][out] */ BSTR* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = 0;

    if (m_response.url().isEmpty())
        return E_FAIL;

    *result = BString(m_response.suggestedFilename()).release();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::textEncodingName( 
    /* [retval][out] */ BSTR* result)
{
    if (!result)
        return E_INVALIDARG;

    BString textEncodingName(m_response.textEncodingName());
    *result = textEncodingName.release();
    if (!m_response.textEncodingName().isNull() && !*result)
        return E_OUTOFMEMORY;

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::URL( 
    /* [retval][out] */ BSTR* result)
{
    if (!result)
        return E_INVALIDARG;

    BString url(m_response.url().url());
    *result = url.release();
    if (!m_response.url().isEmpty() && !*result)
        return E_OUTOFMEMORY;

    return S_OK;
}

// IWebHTTPURLResponse --------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebURLResponse::allHeaderFields( 
    /* [retval][out] */ IPropertyBag** headerFields)
{
    ASSERT(m_response.isHTTP());
    *headerFields = HTTPHeaderPropertyBag::createInstance(this);
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::localizedStringForStatusCode( 
    /* [in] */ int statusCode,
    /* [retval][out] */ BSTR* statusString)
{
    ASSERT(m_response.isHTTP());
    if (statusString)
        *statusString = 0;
    LPCTSTR statusText = CFHTTPMessageCopyLocalizedShortDescriptionForStatusCode(statusCode);
    if (!statusText)
        return E_FAIL;
    if (statusString)
        *statusString = SysAllocString(statusText);
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::statusCode( 
    /* [retval][out] */ int* statusCode)
{
    ASSERT(m_response.isHTTP());
    if (statusCode)
        *statusCode = m_response.httpStatusCode();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebURLResponse::isAttachment( 
    /* [retval][out] */ BOOL *attachment)
{
    *attachment = m_response.isAttachment();
    return S_OK;
}


HRESULT STDMETHODCALLTYPE WebURLResponse::sslPeerCertificate( 
    /* [retval][out] */ OLE_HANDLE* result)
{
    if (!result)
        return E_POINTER;
    *result = 0;
    CFDictionaryRef dict = certificateDictionary();
    if (!dict)
        return E_FAIL;
    void* data = wkGetSSLPeerCertificateData(dict);
    if (!data)
        return E_FAIL;
    *result = (OLE_HANDLE)(ULONG64)data;
    return *result ? S_OK : E_FAIL;
}

// WebURLResponse -------------------------------------------------------------

HRESULT WebURLResponse::suggestedFileExtension(BSTR *result)
{
    if (!result)
        return E_POINTER;

    *result = 0;

    if (m_response.mimeType().isEmpty())
        return E_FAIL;

    BString mimeType(m_response.mimeType());
    HKEY key;
    LONG err = RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("MIME\\Database\\Content Type"), 0, KEY_QUERY_VALUE, &key);
    if (!err) {
        HKEY subKey;
        err = RegOpenKeyEx(key, mimeType, 0, KEY_QUERY_VALUE, &subKey);
        if (!err) {
            DWORD keyType = REG_SZ;
            TCHAR extension[MAX_PATH];
            DWORD keySize = sizeof(extension)/sizeof(extension[0]);
            err = RegQueryValueEx(subKey, TEXT("Extension"), 0, &keyType, (LPBYTE)extension, &keySize);
            if (!err && keyType != REG_SZ)
                err = ERROR_INVALID_DATA;
            if (err) {
                // fallback handlers
                if (!_tcscmp(mimeType, TEXT("text/html"))) {
                    _tcscpy(extension, TEXT(".html"));
                    err = 0;
                } else if (!_tcscmp(mimeType, TEXT("application/xhtml+xml"))) {
                    _tcscpy(extension, TEXT(".xhtml"));
                    err = 0;
                } else if (!_tcscmp(mimeType, TEXT("image/svg+xml"))) {
                    _tcscpy(extension, TEXT(".svg"));
                    err = 0;
                }
            }
            if (!err) {
                *result = SysAllocString(extension);
                if (!*result)
                    err = ERROR_OUTOFMEMORY;
            }
            RegCloseKey(subKey);
        }
        RegCloseKey(key);
    }

    return HRESULT_FROM_WIN32(err);
}

const ResourceResponse& WebURLResponse::resourceResponse() const
{
    return m_response;
}

CFDictionaryRef WebURLResponse::certificateDictionary() const
{
    if (m_SSLCertificateInfo)
        return m_SSLCertificateInfo.get();

    CFURLResponseRef cfResponse = m_response.cfURLResponse();
    if (!cfResponse)
        return 0;
    m_SSLCertificateInfo = wkGetSSLCertificateInfo(cfResponse);
    return m_SSLCertificateInfo.get();
}
Copyright 2008 Perforce Software. All rights reserved.