Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "WebResponse.h"
     28 
     29 #include "MIMETypeRegistry.h"
     30 #include "PlatformString.h"
     31 #include "ResourceResponse.h"
     32 #include "ResourceError.h"
     33 
     34 #include <wtf/text/CString.h>
     35 
     36 using namespace std;
     37 
     38 namespace android {
     39 
     40 WebResponse::WebResponse(net::URLRequest* request)
     41     : m_httpStatusCode(0)
     42 {
     43     // The misleadingly-named os_error() is actually a net::Error enum constant.
     44     m_error = net::Error(request->status().os_error());
     45 
     46     m_url = request->url().spec();
     47     m_host = request->url().HostNoBrackets();
     48     request->GetMimeType(&m_mime);
     49 
     50     request->GetCharset(&m_encoding);
     51     m_expectedSize = request->GetExpectedContentSize();
     52 
     53     m_sslInfo = request->ssl_info();
     54 
     55     net::HttpResponseHeaders* responseHeaders = request->response_headers();
     56     if (!responseHeaders)
     57         return;
     58 
     59     m_httpStatusCode = responseHeaders->response_code();
     60     m_httpStatusText = responseHeaders->GetStatusText();
     61 
     62     string value;
     63     string name;
     64     void* iter = 0;
     65     while (responseHeaders->EnumerateHeaderLines(&iter, &name, &value))
     66         m_headerFields[name] = value;
     67 }
     68 
     69 WebResponse::WebResponse(const string &url, const string &mimeType, long long expectedSize, const string &encoding, int httpStatusCode)
     70     : m_error(net::OK)
     71     , m_encoding(encoding)
     72     , m_httpStatusCode(httpStatusCode)
     73     , m_expectedSize(expectedSize)
     74     , m_mime(mimeType)
     75     , m_url(url)
     76 {
     77 }
     78 
     79 WebCore::ResourceResponse WebResponse::createResourceResponse()
     80 {
     81     WebCore::ResourceResponse resourceResponse(createKurl(), getMimeType().c_str(), m_expectedSize, m_encoding.c_str(), "");
     82     resourceResponse.setHTTPStatusCode(m_httpStatusCode);
     83     resourceResponse.setHTTPStatusText(m_httpStatusText.c_str());
     84 
     85     map<string, string>::const_iterator it;
     86     for (it = m_headerFields.begin(); it != m_headerFields.end(); ++it)
     87         resourceResponse.setHTTPHeaderField(it->first.c_str(), it->second.c_str());
     88 
     89     return resourceResponse;
     90 }
     91 
     92 WebCore::ResourceError WebResponse::createResourceError()
     93 {
     94     WebCore::ResourceError error(m_host.c_str(), ToWebViewClientError(m_error), m_url.c_str(), WTF::String());
     95     return error;
     96 }
     97 
     98 
     99 WebCore::KURL WebResponse::createKurl()
    100 {
    101     WebCore::KURL kurl(WebCore::ParsedURLString, m_url.c_str());
    102     return kurl;
    103 }
    104 
    105 const string& WebResponse::getUrl() const
    106 {
    107     return m_url;
    108 }
    109 
    110 void WebResponse::setUrl(const string& url)
    111 {
    112     m_url = url;
    113 }
    114 
    115 // Calls WebCore APIs so should only be called from the WebCore thread.
    116 // TODO: can we return a WTF::String directly? Need to check all callsites.
    117 const string& WebResponse::getMimeType()
    118 {
    119     if (!m_url.length())
    120         return m_mime;
    121 
    122     if (!m_mime.length() || !m_mime.compare("text/plain") || !m_mime.compare("application/octet-stream"))
    123         m_mime = resolveMimeType(m_url, m_mime);
    124 
    125     return m_mime;
    126 }
    127 
    128 const string WebResponse::resolveMimeType(const string& url, const string& old_mime)
    129 {
    130     // Use "text/html" as a default (matching the behaviour of the Apache
    131     // HTTP stack -- see guessMimeType() in LoadListener.java).
    132     string mimeType = old_mime.length() ? old_mime : "text/html";
    133     // Try to guess a better MIME type from the URL. We call
    134     // getMIMETypeForExtension rather than getMIMETypeForPath because the
    135     // latter defaults to "application/octet-stream" on failure.
    136     WebCore::KURL kurl(WebCore::ParsedURLString, url.c_str());
    137     WTF::String path = kurl.path();
    138     size_t extensionPos = path.reverseFind('.');
    139     if (extensionPos != WTF::notFound) {
    140         // We found a file extension.
    141         path.remove(0, extensionPos + 1);
    142         // TODO: Should use content-disposition instead of url if it is there
    143         WTF::String mime = WebCore::MIMETypeRegistry::getMIMETypeForExtension(path);
    144         if (!mime.isEmpty()) {
    145             // Great, we found a MIME type.
    146             mimeType = std::string(mime.utf8().data(), mime.length());
    147         }
    148     }
    149     return mimeType;
    150 }
    151 
    152 bool WebResponse::getHeader(const string& header, string* result) const
    153 {
    154     map<string, string>::const_iterator iter = m_headerFields.find(header);
    155     if (iter == m_headerFields.end())
    156         return false;
    157     if (result)
    158         *result = iter->second;
    159     return true;
    160 }
    161 
    162 long long WebResponse::getExpectedSize() const
    163 {
    164     return m_expectedSize;
    165 }
    166 
    167 } // namespace android
    168