summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/net.gyp2
-rw-r--r--net/spdy/spdy_http_stream.cc137
-rw-r--r--net/spdy/spdy_http_utils.cc141
-rw-r--r--net/spdy/spdy_http_utils.h32
4 files changed, 176 insertions, 136 deletions
diff --git a/net/net.gyp b/net/net.gyp
index 2b43f9f..b9e16cc 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -565,6 +565,8 @@
'spdy/spdy_framer.h',
'spdy/spdy_http_stream.cc',
'spdy/spdy_http_stream.h',
+ 'spdy/spdy_http_utils.cc',
+ 'spdy/spdy_http_utils.h',
'spdy/spdy_io_buffer.cc',
'spdy/spdy_io_buffer.h',
'spdy/spdy_protocol.h',
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
index 2880b07..0e3962e 100644
--- a/net/spdy/spdy_http_stream.cc
+++ b/net/spdy/spdy_http_stream.cc
@@ -10,149 +10,14 @@
#include "base/logging.h"
#include "base/message_loop.h"
-#include "base/string_number_conversions.h"
-#include "base/string_util.h"
#include "net/base/load_flags.h"
#include "net/base/net_util.h"
-#include "net/base/ssl_cert_request_info.h"
#include "net/http/http_request_info.h"
-#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_util.h"
+#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session.h"
-namespace {
-
-// Convert a SpdyHeaderBlock into an HttpResponseInfo.
-// |headers| input parameter with the SpdyHeaderBlock.
-// |info| output parameter for the HttpResponseInfo.
-// Returns true if successfully converted. False if there was a failure
-// or if the SpdyHeaderBlock was invalid.
-bool SpdyHeadersToHttpResponse(const spdy::SpdyHeaderBlock& headers,
- net::HttpResponseInfo* response) {
- std::string version;
- std::string status;
-
- // The "status" and "version" headers are required.
- spdy::SpdyHeaderBlock::const_iterator it;
- it = headers.find("status");
- if (it == headers.end()) {
- LOG(ERROR) << "SpdyHeaderBlock without status header.";
- return false;
- }
- status = it->second;
-
- // Grab the version. If not provided by the server,
- it = headers.find("version");
- if (it == headers.end()) {
- LOG(ERROR) << "SpdyHeaderBlock without version header.";
- return false;
- }
- version = it->second;
-
- response->response_time = base::Time::Now();
-
- std::string raw_headers(version);
- raw_headers.push_back(' ');
- raw_headers.append(status);
- raw_headers.push_back('\0');
- for (it = headers.begin(); it != headers.end(); ++it) {
- // For each value, if the server sends a NUL-separated
- // list of values, we separate that back out into
- // individual headers for each value in the list.
- // e.g.
- // Set-Cookie "foo\0bar"
- // becomes
- // Set-Cookie: foo\0
- // Set-Cookie: bar\0
- std::string value = it->second;
- size_t start = 0;
- size_t end = 0;
- do {
- end = value.find('\0', start);
- std::string tval;
- if (end != value.npos)
- tval = value.substr(start, (end - start));
- else
- tval = value.substr(start);
- raw_headers.append(it->first);
- raw_headers.push_back(':');
- raw_headers.append(tval);
- raw_headers.push_back('\0');
- start = end + 1;
- } while (end != value.npos);
- }
-
- response->headers = new net::HttpResponseHeaders(raw_headers);
- response->was_fetched_via_spdy = true;
- return true;
-}
-
-// Create a SpdyHeaderBlock for a Spdy SYN_STREAM Frame from
-// a HttpRequestInfo block.
-void CreateSpdyHeadersFromHttpRequest(
- const net::HttpRequestInfo& info, spdy::SpdyHeaderBlock* headers,
- bool direct) {
- // TODO(willchan): It's not really necessary to convert from
- // HttpRequestHeaders to spdy::SpdyHeaderBlock.
-
- static const char kHttpProtocolVersion[] = "HTTP/1.1";
-
- net::HttpRequestHeaders::Iterator it(info.extra_headers);
-
- while (it.GetNext()) {
- std::string name = StringToLowerASCII(it.name());
- if (headers->find(name) == headers->end()) {
- (*headers)[name] = it.value();
- } else {
- std::string new_value = (*headers)[name];
- new_value.append(1, '\0'); // +=() doesn't append 0's
- new_value += it.value();
- (*headers)[name] = new_value;
- }
- }
-
- // TODO(mbelshe): Add Proxy headers here. (See http_network_transaction.cc)
- // TODO(mbelshe): Add authentication headers here.
-
- (*headers)["method"] = info.method;
-
- // Handle content-length. This is the same as BuildRequestHeader in
- // http_network_transaction.cc.
- // TODO(lzheng): reduce the code duplication between spdy and http here.
- if (info.upload_data) {
- (*headers)["content-length"] =
- base::Int64ToString(info.upload_data->GetContentLength());
- } else if (info.method == "POST" || info.method == "PUT" ||
- info.method == "HEAD") {
- // An empty POST/PUT request still needs a content length. As for HEAD,
- // IE and Safari also add a content length header. Presumably it is to
- // support sending a HEAD request to an URL that only expects to be sent a
- // POST or some other method that normally would have a message body.
- (*headers)["content-length"] = "0";
- }
-
- if (direct)
- (*headers)["url"] = net::HttpUtil::PathForRequest(info.url);
- else
- (*headers)["url"] = net::HttpUtil::SpecForRequest(info.url);
- (*headers)["host"] = net::GetHostAndOptionalPort(info.url);
- (*headers)["scheme"] = info.url.scheme();
- (*headers)["version"] = kHttpProtocolVersion;
- if (!info.referrer.is_empty())
- (*headers)["referer"] = info.referrer.spec();
-
- // Honor load flags that impact proxy caches.
- if (info.load_flags & net::LOAD_BYPASS_CACHE) {
- (*headers)["pragma"] = "no-cache";
- (*headers)["cache-control"] = "no-cache";
- } else if (info.load_flags & net::LOAD_VALIDATE_CACHE) {
- (*headers)["cache-control"] = "max-age=0";
- }
-}
-
-} // anonymous namespace
-
namespace net {
SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session, bool direct)
diff --git a/net/spdy/spdy_http_utils.cc b/net/spdy/spdy_http_utils.cc
new file mode 100644
index 0000000..d2fdd8fa
--- /dev/null
+++ b/net/spdy/spdy_http_utils.cc
@@ -0,0 +1,141 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_http_utils.h"
+
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "base/time.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_util.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
+#include "net/http/http_util.h"
+
+namespace net {
+
+bool SpdyHeadersToHttpResponse(const spdy::SpdyHeaderBlock& headers,
+ HttpResponseInfo* response) {
+ std::string version;
+ std::string status;
+
+ // The "status" and "version" headers are required.
+ spdy::SpdyHeaderBlock::const_iterator it;
+ it = headers.find("status");
+ if (it == headers.end()) {
+ LOG(ERROR) << "SpdyHeaderBlock without status header.";
+ return false;
+ }
+ status = it->second;
+
+ // Grab the version. If not provided by the server,
+ it = headers.find("version");
+ if (it == headers.end()) {
+ LOG(ERROR) << "SpdyHeaderBlock without version header.";
+ return false;
+ }
+ version = it->second;
+
+ response->response_time = base::Time::Now();
+
+ std::string raw_headers(version);
+ raw_headers.push_back(' ');
+ raw_headers.append(status);
+ raw_headers.push_back('\0');
+ for (it = headers.begin(); it != headers.end(); ++it) {
+ // For each value, if the server sends a NUL-separated
+ // list of values, we separate that back out into
+ // individual headers for each value in the list.
+ // e.g.
+ // Set-Cookie "foo\0bar"
+ // becomes
+ // Set-Cookie: foo\0
+ // Set-Cookie: bar\0
+ std::string value = it->second;
+ size_t start = 0;
+ size_t end = 0;
+ do {
+ end = value.find('\0', start);
+ std::string tval;
+ if (end != value.npos)
+ tval = value.substr(start, (end - start));
+ else
+ tval = value.substr(start);
+ raw_headers.append(it->first);
+ raw_headers.push_back(':');
+ raw_headers.append(tval);
+ raw_headers.push_back('\0');
+ start = end + 1;
+ } while (end != value.npos);
+ }
+
+ response->headers = new HttpResponseHeaders(raw_headers);
+ response->was_fetched_via_spdy = true;
+ return true;
+}
+
+void CreateSpdyHeadersFromHttpRequest(
+ const HttpRequestInfo& info, spdy::SpdyHeaderBlock* headers,
+ bool direct) {
+ // TODO(willchan): It's not really necessary to convert from
+ // HttpRequestHeaders to spdy::SpdyHeaderBlock.
+
+ static const char kHttpProtocolVersion[] = "HTTP/1.1";
+
+ HttpRequestHeaders::Iterator it(info.extra_headers);
+
+ while (it.GetNext()) {
+ std::string name = StringToLowerASCII(it.name());
+ if (headers->find(name) == headers->end()) {
+ (*headers)[name] = it.value();
+ } else {
+ std::string new_value = (*headers)[name];
+ new_value.append(1, '\0'); // +=() doesn't append 0's
+ new_value += it.value();
+ (*headers)[name] = new_value;
+ }
+ }
+
+ // TODO(rch): Add Proxy headers here. (See http_network_transaction.cc)
+ // TODO(rch): Add authentication headers here.
+
+ (*headers)["method"] = info.method;
+
+ // Handle content-length. This is the same as BuildRequestHeader in
+ // http_network_transaction.cc.
+ // TODO(lzheng): reduce the code duplication between spdy and http here.
+ if (info.upload_data) {
+ (*headers)["content-length"] =
+ base::Int64ToString(info.upload_data->GetContentLength());
+ } else if (info.method == "POST" || info.method == "PUT" ||
+ info.method == "HEAD") {
+ // An empty POST/PUT request still needs a content length. As for HEAD,
+ // IE and Safari also add a content length header. Presumably it is to
+ // support sending a HEAD request to an URL that only expects to be sent a
+ // POST or some other method that normally would have a message body.
+ (*headers)["content-length"] = "0";
+ }
+
+ if (direct)
+ (*headers)["url"] = HttpUtil::PathForRequest(info.url);
+ else
+ (*headers)["url"] = HttpUtil::SpecForRequest(info.url);
+ (*headers)["host"] = GetHostAndOptionalPort(info.url);
+ (*headers)["scheme"] = info.url.scheme();
+ (*headers)["version"] = kHttpProtocolVersion;
+ if (!info.referrer.is_empty())
+ (*headers)["referer"] = info.referrer.spec();
+
+ // Honor load flags that impact proxy caches.
+ if (info.load_flags & LOAD_BYPASS_CACHE) {
+ (*headers)["pragma"] = "no-cache";
+ (*headers)["cache-control"] = "no-cache";
+ } else if (info.load_flags & LOAD_VALIDATE_CACHE) {
+ (*headers)["cache-control"] = "max-age=0";
+ }
+}
+
+} // namespace net
diff --git a/net/spdy/spdy_http_utils.h b/net/spdy/spdy_http_utils.h
new file mode 100644
index 0000000..0889921
--- /dev/null
+++ b/net/spdy/spdy_http_utils.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SPDY_SPDY_HTTP_UTILS_H_
+#define NET_SPDY_SPDY_HTTP_UTILS_H_
+#pragma once
+
+#include "net/spdy/spdy_framer.h"
+
+namespace net {
+
+class HttpResponseInfo;
+class HttpRequestInfo;
+
+// Convert a SpdyHeaderBlock into an HttpResponseInfo.
+// |headers| input parameter with the SpdyHeaderBlock.
+// |info| output parameter for the HttpResponseInfo.
+// Returns true if successfully converted. False if there was a failure
+// or if the SpdyHeaderBlock was invalid.
+bool SpdyHeadersToHttpResponse(const spdy::SpdyHeaderBlock& headers,
+ HttpResponseInfo* response);
+
+// Create a SpdyHeaderBlock for a Spdy SYN_STREAM Frame from
+// a HttpRequestInfo block.
+void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
+ spdy::SpdyHeaderBlock* headers,
+ bool direct);
+
+} // namespace net
+
+#endif // NET_SPDY_SPDY_HTTP_UTILS_H_