summaryrefslogtreecommitdiffstats
path: root/net/server
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 21:29:11 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 21:29:11 +0000
commitc700fd159b4c094530244eb8e482376160823b5e (patch)
tree148e2676f0cf9fd95967757c26a7927c228ae9e2 /net/server
parentf23a4495c988573cd612c6a58627c2eb3743bc23 (diff)
downloadchromium_src-c700fd159b4c094530244eb8e482376160823b5e.zip
chromium_src-c700fd159b4c094530244eb8e482376160823b5e.tar.gz
chromium_src-c700fd159b4c094530244eb8e482376160823b5e.tar.bz2
Allow HttpServer response to include custom headers.
This is done by introducing a simple HttpServerResponseInfo class, and changing the root HttpServer::Send to accept it instead of a status, data, and mime type. BUG=none Review URL: https://chromiumcodereview.appspot.com/19637005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213227 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/server')
-rw-r--r--net/server/http_connection.cc21
-rw-r--r--net/server/http_connection.h5
-rw-r--r--net/server/http_server.cc20
-rw-r--r--net/server/http_server.h2
-rw-r--r--net/server/http_server_response_info.cc67
-rw-r--r--net/server/http_server_response_info.h46
-rw-r--r--net/server/http_server_response_info_unittest.cc51
-rw-r--r--net/server/web_socket.cc22
8 files changed, 195 insertions, 39 deletions
diff --git a/net/server/http_connection.cc b/net/server/http_connection.cc
index 66541fa..d964cb0 100644
--- a/net/server/http_connection.cc
+++ b/net/server/http_connection.cc
@@ -4,9 +4,8 @@
#include "net/server/http_connection.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
#include "net/server/http_server.h"
+#include "net/server/http_server_response_info.h"
#include "net/server/web_socket.h"
#include "net/socket/stream_listen_socket.h"
@@ -26,22 +25,8 @@ void HttpConnection::Send(const char* bytes, int len) {
socket_->Send(bytes, len);
}
-void HttpConnection::Send(HttpStatusCode status_code,
- const std::string& data,
- const std::string& content_type) {
- if (!socket_.get())
- return;
-
- socket_->Send(base::StringPrintf(
- "HTTP/1.1 %d %s\r\n"
- "Content-Type:%s\r\n"
- "Content-Length:%d\r\n"
- "\r\n",
- status_code,
- GetHttpReasonPhrase(status_code),
- content_type.c_str(),
- static_cast<int>(data.length())));
- socket_->Send(data);
+void HttpConnection::Send(const HttpServerResponseInfo& response) {
+ Send(response.Serialize());
}
HttpConnection::HttpConnection(HttpServer* server, StreamListenSocket* sock)
diff --git a/net/server/http_connection.h b/net/server/http_connection.h
index 488d528..b0e3766 100644
--- a/net/server/http_connection.h
+++ b/net/server/http_connection.h
@@ -15,6 +15,7 @@
namespace net {
class HttpServer;
+class HttpServerResponseInfo;
class StreamListenSocket;
class WebSocket;
@@ -24,9 +25,7 @@ class HttpConnection {
void Send(const std::string& data);
void Send(const char* bytes, int len);
- void Send(HttpStatusCode status_code,
- const std::string& data,
- const std::string& content_type);
+ void Send(const HttpServerResponseInfo& response);
void Shift(int num_bytes);
diff --git a/net/server/http_server.cc b/net/server/http_server.cc
index b780739..3d54c40 100644
--- a/net/server/http_server.cc
+++ b/net/server/http_server.cc
@@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "net/server/http_connection.h"
#include "net/server/http_server_request_info.h"
+#include "net/server/http_server_response_info.h"
#include "net/server/web_socket.h"
#include "net/socket/tcp_listen_socket.h"
@@ -45,14 +46,21 @@ void HttpServer::SendOverWebSocket(int connection_id,
connection->web_socket_->Send(data);
}
+void HttpServer::SendResponse(int connection_id,
+ const HttpServerResponseInfo& response) {
+ HttpConnection* connection = FindConnection(connection_id);
+ if (connection == NULL)
+ return;
+ connection->Send(response);
+}
+
void HttpServer::Send(int connection_id,
HttpStatusCode status_code,
const std::string& data,
const std::string& content_type) {
- HttpConnection* connection = FindConnection(connection_id);
- if (connection == NULL)
- return;
- connection->Send(status_code, data, content_type);
+ HttpServerResponseInfo response(status_code);
+ response.SetBody(data, content_type);
+ SendResponse(connection_id, response);
}
void HttpServer::Send200(int connection_id,
@@ -62,11 +70,11 @@ void HttpServer::Send200(int connection_id,
}
void HttpServer::Send404(int connection_id) {
- Send(connection_id, HTTP_NOT_FOUND, std::string(), "text/html");
+ SendResponse(connection_id, HttpServerResponseInfo::CreateFor404());
}
void HttpServer::Send500(int connection_id, const std::string& message) {
- Send(connection_id, HTTP_INTERNAL_SERVER_ERROR, message, "text/html");
+ SendResponse(connection_id, HttpServerResponseInfo::CreateFor500(message));
}
void HttpServer::Close(int connection_id) {
diff --git a/net/server/http_server.h b/net/server/http_server.h
index b5ba037..f434575 100644
--- a/net/server/http_server.h
+++ b/net/server/http_server.h
@@ -17,6 +17,7 @@ namespace net {
class HttpConnection;
class HttpServerRequestInfo;
+class HttpServerResponseInfo;
class IPEndPoint;
class WebSocket;
@@ -46,6 +47,7 @@ class HttpServer : public StreamListenSocket::Delegate,
void AcceptWebSocket(int connection_id,
const HttpServerRequestInfo& request);
void SendOverWebSocket(int connection_id, const std::string& data);
+ void SendResponse(int connection_id, const HttpServerResponseInfo& response);
void Send(int connection_id,
HttpStatusCode status_code,
const std::string& data,
diff --git a/net/server/http_server_response_info.cc b/net/server/http_server_response_info.cc
new file mode 100644
index 0000000..e4c6043
--- /dev/null
+++ b/net/server/http_server_response_info.cc
@@ -0,0 +1,67 @@
+// Copyright 2013 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/server/http_server_response_info.h"
+
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
+#include "net/http/http_request_headers.h"
+
+namespace net {
+
+HttpServerResponseInfo::HttpServerResponseInfo() : status_code_(HTTP_OK) {}
+
+HttpServerResponseInfo::HttpServerResponseInfo(HttpStatusCode status_code)
+ : status_code_(status_code) {}
+
+HttpServerResponseInfo::~HttpServerResponseInfo() {}
+
+// static
+HttpServerResponseInfo HttpServerResponseInfo::CreateFor404() {
+ HttpServerResponseInfo response(HTTP_NOT_FOUND);
+ response.SetBody(std::string(), "text/html");
+ return response;
+}
+
+// static
+HttpServerResponseInfo HttpServerResponseInfo::CreateFor500(
+ const std::string& body) {
+ HttpServerResponseInfo response(HTTP_INTERNAL_SERVER_ERROR);
+ response.SetBody(body, "text/html");
+ return response;
+}
+
+void HttpServerResponseInfo::AddHeader(const std::string& name,
+ const std::string& value) {
+ headers_.push_back(std::make_pair(name, value));
+}
+
+void HttpServerResponseInfo::SetBody(const std::string& body,
+ const std::string& content_type) {
+ DCHECK(body_.empty());
+ body_ = body;
+ AddHeader(HttpRequestHeaders::kContentLength,
+ base::StringPrintf("%" PRIuS, body.length()));
+ AddHeader(HttpRequestHeaders::kContentType, content_type);
+}
+
+std::string HttpServerResponseInfo::Serialize() const {
+ std::string response = base::StringPrintf(
+ "HTTP/1.1 %d %s\r\n", status_code_, GetHttpReasonPhrase(status_code_));
+ Headers::const_iterator header;
+ for (header = headers_.begin(); header != headers_.end(); ++header)
+ response += header->first + ":" + header->second + "\r\n";
+
+ return response + "\r\n" + body_;
+}
+
+HttpStatusCode HttpServerResponseInfo::status_code() const {
+ return status_code_;
+}
+
+const std::string& HttpServerResponseInfo::body() const {
+ return body_;
+}
+
+} // namespace net
diff --git a/net/server/http_server_response_info.h b/net/server/http_server_response_info.h
new file mode 100644
index 0000000..d6cedaa
--- /dev/null
+++ b/net/server/http_server_response_info.h
@@ -0,0 +1,46 @@
+// Copyright 2013 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_SERVER_HTTP_SERVER_RESPONSE_INFO_H_
+#define NET_SERVER_HTTP_SERVER_RESPONSE_INFO_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "net/http/http_status_code.h"
+
+namespace net {
+
+class HttpServerResponseInfo {
+ public:
+ // Creates a 200 OK HttpServerResponseInfo.
+ HttpServerResponseInfo();
+ explicit HttpServerResponseInfo(HttpStatusCode status_code);
+ ~HttpServerResponseInfo();
+
+ static HttpServerResponseInfo CreateFor404();
+ static HttpServerResponseInfo CreateFor500(const std::string& body);
+
+ void AddHeader(const std::string& name, const std::string& value);
+
+ // This also adds an appropriate Content-Length header.
+ void SetBody(const std::string& body, const std::string& content_type);
+
+ std::string Serialize() const;
+
+ HttpStatusCode status_code() const;
+ const std::string& body() const;
+
+ private:
+ typedef std::vector<std::pair<std::string, std::string> > Headers;
+
+ HttpStatusCode status_code_;
+ Headers headers_;
+ std::string body_;
+};
+
+} // namespace net
+
+#endif // NET_SERVER_HTTP_SERVER_RESPONSE_INFO_H_
diff --git a/net/server/http_server_response_info_unittest.cc b/net/server/http_server_response_info_unittest.cc
new file mode 100644
index 0000000..f7b8e25
--- /dev/null
+++ b/net/server/http_server_response_info_unittest.cc
@@ -0,0 +1,51 @@
+// Copyright 2013 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/http/http_status_code.h"
+#include "net/server/http_server_response_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+TEST(HttpServerResponseInfoTest, StatusLine) {
+ HttpServerResponseInfo response;
+ ASSERT_EQ(HTTP_OK, response.status_code());
+ ASSERT_EQ("HTTP/1.1 200 OK\r\n\r\n", response.Serialize());
+}
+
+TEST(HttpServerResponseInfoTest, Headers) {
+ HttpServerResponseInfo response;
+ response.AddHeader("A", "1");
+ response.AddHeader("A", "2");
+ ASSERT_EQ("HTTP/1.1 200 OK\r\nA:1\r\nA:2\r\n\r\n", response.Serialize());
+}
+
+TEST(HttpServerResponseInfoTest, Body) {
+ HttpServerResponseInfo response;
+ ASSERT_EQ(std::string(), response.body());
+ response.SetBody("body", "type");
+ ASSERT_EQ("body", response.body());
+ ASSERT_EQ(
+ "HTTP/1.1 200 OK\r\nContent-Length:4\r\nContent-Type:type\r\n\r\nbody",
+ response.Serialize());
+}
+
+TEST(HttpServerResponseInfoTest, CreateFor404) {
+ HttpServerResponseInfo response = HttpServerResponseInfo::CreateFor404();
+ ASSERT_EQ(
+ "HTTP/1.1 404 Not Found\r\n"
+ "Content-Length:0\r\nContent-Type:text/html\r\n\r\n",
+ response.Serialize());
+}
+
+TEST(HttpServerResponseInfoTest, CreateFor500) {
+ HttpServerResponseInfo response =
+ HttpServerResponseInfo::CreateFor500("mess");
+ ASSERT_EQ(
+ "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length:4\r\nContent-Type:text/html\r\n\r\nmess",
+ response.Serialize());
+}
+
+} // namespace net
diff --git a/net/server/web_socket.cc b/net/server/web_socket.cc
index df5b0ae..7461085 100644
--- a/net/server/web_socket.cc
+++ b/net/server/web_socket.cc
@@ -16,6 +16,7 @@
#include "base/sys_byteorder.h"
#include "net/server/http_connection.h"
#include "net/server/http_server_request_info.h"
+#include "net/server/http_server_response_info.h"
namespace net {
@@ -115,18 +116,16 @@ class WebSocketHixie76 : public net::WebSocket {
std::string key2 = request.GetHeaderValue("Sec-WebSocket-Key2");
if (key1.empty()) {
- connection->Send(net::HTTP_INTERNAL_SERVER_ERROR,
- "Invalid request format. "
- "Sec-WebSocket-Key1 is empty or isn't specified.",
- "text/html");
+ connection->Send(HttpServerResponseInfo::CreateFor500(
+ "Invalid request format. Sec-WebSocket-Key1 is empty or isn't "
+ "specified."));
return;
}
if (key2.empty()) {
- connection->Send(net::HTTP_INTERNAL_SERVER_ERROR,
- "Invalid request format. "
- "Sec-WebSocket-Key2 is empty or isn't specified.",
- "text/html");
+ connection->Send(HttpServerResponseInfo::CreateFor500(
+ "Invalid request format. Sec-WebSocket-Key2 is empty or isn't "
+ "specified."));
return;
}
@@ -179,10 +178,9 @@ class WebSocketHybi17 : public WebSocket {
std::string key = request.GetHeaderValue("Sec-WebSocket-Key");
if (key.empty()) {
- connection->Send(net::HTTP_INTERNAL_SERVER_ERROR,
- "Invalid request format. "
- "Sec-WebSocket-Key is empty or isn't specified.",
- "text/html");
+ connection->Send(HttpServerResponseInfo::CreateFor500(
+ "Invalid request format. Sec-WebSocket-Key is empty or isn't "
+ "specified."));
return NULL;
}
return new WebSocketHybi17(connection, request, pos);