| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/spdy_http_utils.h" | 5 #include "net/spdy/spdy_http_utils.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "net/base/escape.h" | 12 #include "net/base/escape.h" |
| 13 #include "net/base/load_flags.h" | 13 #include "net/base/load_flags.h" |
| 14 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 15 #include "net/http/http_request_headers.h" | 15 #include "net/http/http_request_headers.h" |
| 16 #include "net/http/http_request_info.h" | 16 #include "net/http/http_request_info.h" |
| 17 #include "net/http/http_response_headers.h" | 17 #include "net/http/http_response_headers.h" |
| 18 #include "net/http/http_response_info.h" | 18 #include "net/http/http_response_info.h" |
| 19 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
| 20 | 20 |
| 21 namespace net { | 21 namespace net { |
| 22 | 22 |
| 23 namespace { |
| 24 |
| 25 void AddSpdyHeader(const std::string& name, |
| 26 const std::string& value, |
| 27 SpdyHeaderBlock* headers) { |
| 28 if (headers->find(name) == headers->end()) { |
| 29 (*headers)[name] = value; |
| 30 } else { |
| 31 (*headers)[name] += '\0' + value; |
| 32 } |
| 33 } |
| 34 |
| 35 } // namespace |
| 36 |
| 23 bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers, | 37 bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers, |
| 24 SpdyMajorVersion protocol_version, | 38 SpdyMajorVersion protocol_version, |
| 25 HttpResponseInfo* response) { | 39 HttpResponseInfo* response) { |
| 26 std::string status_key = (protocol_version >= SPDY3) ? ":status" : "status"; | 40 std::string status_key = (protocol_version >= SPDY3) ? ":status" : "status"; |
| 27 std::string version_key = | 41 std::string version_key = |
| 28 (protocol_version >= SPDY3) ? ":version" : "version"; | 42 (protocol_version >= SPDY3) ? ":version" : "version"; |
| 29 std::string version; | 43 std::string version; |
| 30 std::string status; | 44 std::string status; |
| 31 | 45 |
| 32 // The "status" header is required. "version" is required below SPDY4. | 46 // The "status" header is required. "version" is required below SPDY4. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } while (end != value.npos); | 92 } while (end != value.npos); |
| 79 } | 93 } |
| 80 | 94 |
| 81 response->headers = new HttpResponseHeaders(raw_headers); | 95 response->headers = new HttpResponseHeaders(raw_headers); |
| 82 response->was_fetched_via_spdy = true; | 96 response->was_fetched_via_spdy = true; |
| 83 return true; | 97 return true; |
| 84 } | 98 } |
| 85 | 99 |
| 86 void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info, | 100 void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info, |
| 87 const HttpRequestHeaders& request_headers, | 101 const HttpRequestHeaders& request_headers, |
| 88 SpdyHeaderBlock* headers, | |
| 89 SpdyMajorVersion protocol_version, | 102 SpdyMajorVersion protocol_version, |
| 90 bool direct) { | 103 bool direct, |
| 104 SpdyHeaderBlock* headers) { |
| 91 | 105 |
| 92 HttpRequestHeaders::Iterator it(request_headers); | 106 HttpRequestHeaders::Iterator it(request_headers); |
| 93 while (it.GetNext()) { | 107 while (it.GetNext()) { |
| 94 std::string name = StringToLowerASCII(it.name()); | 108 std::string name = StringToLowerASCII(it.name()); |
| 95 if (name == "connection" || name == "proxy-connection" || | 109 if (name == "connection" || name == "proxy-connection" || |
| 96 name == "transfer-encoding" || name == "host") { | 110 name == "transfer-encoding" || name == "host") { |
| 97 continue; | 111 continue; |
| 98 } | 112 } |
| 99 if (headers->find(name) == headers->end()) { | 113 AddSpdyHeader(name, it.value(), headers); |
| 100 (*headers)[name] = it.value(); | |
| 101 } else { | |
| 102 std::string new_value = (*headers)[name]; | |
| 103 new_value.append(1, '\0'); // +=() doesn't append 0's | |
| 104 new_value += it.value(); | |
| 105 (*headers)[name] = new_value; | |
| 106 } | |
| 107 } | 114 } |
| 108 static const char kHttpProtocolVersion[] = "HTTP/1.1"; | 115 static const char kHttpProtocolVersion[] = "HTTP/1.1"; |
| 109 | 116 |
| 110 if (protocol_version < SPDY3) { | 117 if (protocol_version < SPDY3) { |
| 111 (*headers)["version"] = kHttpProtocolVersion; | 118 (*headers)["version"] = kHttpProtocolVersion; |
| 112 (*headers)["method"] = info.method; | 119 (*headers)["method"] = info.method; |
| 113 (*headers)["host"] = GetHostAndOptionalPort(info.url); | 120 (*headers)["host"] = GetHostAndOptionalPort(info.url); |
| 114 (*headers)["scheme"] = info.url.scheme(); | 121 (*headers)["scheme"] = info.url.scheme(); |
| 115 if (direct) | 122 if (direct) |
| 116 (*headers)["url"] = HttpUtil::PathForRequest(info.url); | 123 (*headers)["url"] = HttpUtil::PathForRequest(info.url); |
| 117 else | 124 else |
| 118 (*headers)["url"] = HttpUtil::SpecForRequest(info.url); | 125 (*headers)["url"] = HttpUtil::SpecForRequest(info.url); |
| 119 } else { | 126 } else { |
| 120 if (protocol_version < SPDY4) { | 127 if (protocol_version < SPDY4) { |
| 121 (*headers)[":version"] = kHttpProtocolVersion; | 128 (*headers)[":version"] = kHttpProtocolVersion; |
| 122 (*headers)[":host"] = GetHostAndOptionalPort(info.url); | 129 (*headers)[":host"] = GetHostAndOptionalPort(info.url); |
| 123 } else { | 130 } else { |
| 124 (*headers)[":authority"] = GetHostAndOptionalPort(info.url); | 131 (*headers)[":authority"] = GetHostAndOptionalPort(info.url); |
| 125 } | 132 } |
| 126 (*headers)[":method"] = info.method; | 133 (*headers)[":method"] = info.method; |
| 127 (*headers)[":scheme"] = info.url.scheme(); | 134 (*headers)[":scheme"] = info.url.scheme(); |
| 128 (*headers)[":path"] = HttpUtil::PathForRequest(info.url); | 135 (*headers)[":path"] = HttpUtil::PathForRequest(info.url); |
| 129 } | 136 } |
| 130 } | 137 } |
| 131 | 138 |
| 139 void CreateSpdyHeadersFromHttpResponse( |
| 140 const HttpResponseHeaders& response_headers, |
| 141 SpdyMajorVersion protocol_version, |
| 142 SpdyHeaderBlock* headers) { |
| 143 std::string status_key = (protocol_version >= SPDY3) ? ":status" : "status"; |
| 144 std::string version_key = |
| 145 (protocol_version >= SPDY3) ? ":version" : "version"; |
| 146 |
| 147 std::string status_line = response_headers.GetStatusLine(); |
| 148 std::string::const_iterator after_version = |
| 149 std::find(status_line.begin(), status_line.end(), ' '); |
| 150 if (protocol_version < SPDY4) { |
| 151 (*headers)[version_key] = std::string(status_line.cbegin(), after_version); |
| 152 } |
| 153 (*headers)[status_key] = std::string(after_version + 1, status_line.cend()); |
| 154 |
| 155 void* iter = NULL; |
| 156 std::string raw_name, value; |
| 157 while (response_headers.EnumerateHeaderLines(&iter, &raw_name, &value)) { |
| 158 std::string name = StringToLowerASCII(raw_name); |
| 159 AddSpdyHeader(name, value, headers); |
| 160 } |
| 161 } |
| 162 |
| 163 |
| 132 COMPILE_ASSERT(HIGHEST - LOWEST < 4 && | 164 COMPILE_ASSERT(HIGHEST - LOWEST < 4 && |
| 133 HIGHEST - MINIMUM_PRIORITY < 5, | 165 HIGHEST - MINIMUM_PRIORITY < 5, |
| 134 request_priority_incompatible_with_spdy); | 166 request_priority_incompatible_with_spdy); |
| 135 | 167 |
| 136 SpdyPriority ConvertRequestPriorityToSpdyPriority( | 168 SpdyPriority ConvertRequestPriorityToSpdyPriority( |
| 137 const RequestPriority priority, | 169 const RequestPriority priority, |
| 138 SpdyMajorVersion protocol_version) { | 170 SpdyMajorVersion protocol_version) { |
| 139 DCHECK_GE(priority, MINIMUM_PRIORITY); | 171 DCHECK_GE(priority, MINIMUM_PRIORITY); |
| 140 DCHECK_LE(priority, MAXIMUM_PRIORITY); | 172 DCHECK_LE(priority, MAXIMUM_PRIORITY); |
| 141 if (protocol_version == SPDY2) { | 173 if (protocol_version == SPDY2) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 if (it != headers.end()) | 225 if (it != headers.end()) |
| 194 path = it->second; | 226 path = it->second; |
| 195 | 227 |
| 196 std::string url = (scheme.empty() || host_port.empty() || path.empty()) | 228 std::string url = (scheme.empty() || host_port.empty() || path.empty()) |
| 197 ? std::string() | 229 ? std::string() |
| 198 : scheme + "://" + host_port + path; | 230 : scheme + "://" + host_port + path; |
| 199 return GURL(url); | 231 return GURL(url); |
| 200 } | 232 } |
| 201 | 233 |
| 202 } // namespace net | 234 } // namespace net |
| OLD | NEW |