• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
WebResponse(net::URLRequest * request)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 
WebResponse(const string & url,const string & mimeType,long long expectedSize,const string & encoding,int httpStatusCode)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 
createResourceResponse()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 
createResourceError()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 
createKurl()99 WebCore::KURL WebResponse::createKurl()
100 {
101     WebCore::KURL kurl(WebCore::ParsedURLString, m_url.c_str());
102     return kurl;
103 }
104 
getUrl() const105 const string& WebResponse::getUrl() const
106 {
107     return m_url;
108 }
109 
setUrl(const string & url)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.
getMimeType()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 
resolveMimeType(const string & url,const string & old_mime)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 
getHeader(const string & header,string * result) const152 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 
getExpectedSize() const162 long long WebResponse::getExpectedSize() const
163 {
164     return m_expectedSize;
165 }
166 
167 } // namespace android
168