fe0b5fbfdcc5138888548e9249b22de8821d05a6
[WebKit-https.git] / Source / WebCore / platform / network / soup / ResourceResponseSoup.cpp
1 /*
2  * Copyright (C) 2009 Gustavo Noronha Silva
3  * Copyright (C) 2009 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "ResourceResponse.h"
23
24 #include <wtf/gobject/GOwnPtr.h>
25 #include "HTTPParsers.h"
26 #include "MIMETypeRegistry.h"
27 #include "SoupURIUtils.h"
28 #include <wtf/text/CString.h>
29 #include <wtf/text/StringBuilder.h>
30 #include <wtf/text/WTFString.h>
31
32 using namespace std;
33
34 namespace WebCore {
35
36 SoupMessage* ResourceResponse::toSoupMessage() const
37 {
38     // This GET here is just because SoupMessage wants it, we dn't really know.
39     SoupMessage* soupMessage = soup_message_new("GET", url().string().utf8().data());
40     if (!soupMessage)
41         return 0;
42
43     soupMessage->status_code = httpStatusCode();
44
45     const HTTPHeaderMap& headers = httpHeaderFields();
46     SoupMessageHeaders* soupHeaders = soupMessage->response_headers;
47     if (!headers.isEmpty()) {
48         HTTPHeaderMap::const_iterator end = headers.end();
49         for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
50             soup_message_headers_append(soupHeaders, it->key.string().utf8().data(), it->value.utf8().data());
51     }
52
53     soup_message_set_flags(soupMessage, m_soupFlags);
54
55     g_object_set(G_OBJECT(soupMessage), "tls-certificate", m_certificate.get(), "tls-errors", m_tlsErrors, NULL);
56
57     // Body data is not in the message.
58     return soupMessage;
59 }
60
61 void ResourceResponse::updateFromSoupMessage(SoupMessage* soupMessage)
62 {
63     m_url = soupURIToKURL(soup_message_get_uri(soupMessage));
64
65     m_httpStatusCode = soupMessage->status_code;
66
67     SoupMessageHeadersIter headersIter;
68     const char* headerName;
69     const char* headerValue;
70
71     // updateFromSoupMessage could be called several times for the same ResourceResponse object,
72     // thus, we need to clear old header values and update m_httpHeaderFields from soupMessage headers.
73     m_httpHeaderFields.clear();
74
75     soup_message_headers_iter_init(&headersIter, soupMessage->response_headers);
76     while (soup_message_headers_iter_next(&headersIter, &headerName, &headerValue)) {
77         String headerNameString = String::fromUTF8WithLatin1Fallback(headerName, strlen(headerName));
78         HTTPHeaderMap::const_iterator it = m_httpHeaderFields.find(headerNameString);
79         if (it == m_httpHeaderFields.end() || (it != m_httpHeaderFields.end() && it->value.isEmpty()))
80             m_httpHeaderFields.set(headerNameString, String::fromUTF8WithLatin1Fallback(headerValue, strlen(headerValue)));
81         else {
82             StringBuilder builder;
83             builder.append(it->value);
84             builder.appendLiteral(", ");
85             builder.append(String::fromUTF8WithLatin1Fallback(headerValue, strlen(headerValue)));
86             m_httpHeaderFields.set(headerNameString, builder.toString());
87         }
88     }
89
90     m_soupFlags = soup_message_get_flags(soupMessage);
91
92     String contentType;
93     const char* officialType = soup_message_headers_get_one(soupMessage->response_headers, "Content-Type");
94     if (!m_sniffedContentType.isEmpty() && m_sniffedContentType != officialType)
95         contentType = m_sniffedContentType;
96     else
97         contentType = officialType;
98     setMimeType(extractMIMETypeFromMediaType(contentType));
99     setTextEncodingName(extractCharsetFromMediaType(contentType));
100
101     setExpectedContentLength(soup_message_headers_get_content_length(soupMessage->response_headers));
102     setHTTPStatusText(soupMessage->reason_phrase);
103     setSuggestedFilename(filenameFromHTTPContentDisposition(httpHeaderField("Content-Disposition")));
104
105     GTlsCertificate* certificate = 0;
106     soup_message_get_https_status(soupMessage, &certificate, &m_tlsErrors);
107     m_certificate = certificate;
108 }
109
110 }