summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-11 09:44:41 +0000
committerpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-11 09:44:41 +0000
commite67d2179178b955a07df2c908d8c49a26fb0e71d (patch)
treec7f1113691da747da61a7e76b5574d25ba2afebf
parenta942b8c1ca4b002376306cf399e000d0842c630b (diff)
downloadchromium_src-e67d2179178b955a07df2c908d8c49a26fb0e71d.zip
chromium_src-e67d2179178b955a07df2c908d8c49a26fb0e71d.tar.gz
chromium_src-e67d2179178b955a07df2c908d8c49a26fb0e71d.tar.bz2
DevTools: add /json/activate/ command to the discovery protocol.
This change adds suppot for /activate command and refactors the json commands handling so that all commands supported jsonp properly. For the jsonp support, we always respond with 200 OK and specify the actual code in the jsonp call parameter. For the above purposes, migrates net/server/http_server from Send404() scheme to Send(net::HTTP_NOT_FOUND). BUG=157495 Review URL: https://chromiumcodereview.appspot.com/11499004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172285 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/debugger/devtools_http_handler_impl.cc250
-rw-r--r--content/browser/debugger/devtools_http_handler_impl.h16
-rw-r--r--net/server/http_connection.cc48
-rw-r--r--net/server/http_connection.h7
-rw-r--r--net/server/http_server.cc30
-rw-r--r--net/server/http_server.h8
-rw-r--r--net/server/web_socket.cc18
7 files changed, 212 insertions, 165 deletions
diff --git a/content/browser/debugger/devtools_http_handler_impl.cc b/content/browser/debugger/devtools_http_handler_impl.cc
index 6ea1d3c..377ec1c 100644
--- a/content/browser/debugger/devtools_http_handler_impl.cc
+++ b/content/browser/debugger/devtools_http_handler_impl.cc
@@ -285,44 +285,7 @@ void DevToolsHttpHandlerImpl::Observe(int type,
void DevToolsHttpHandlerImpl::OnHttpRequest(
int connection_id,
const net::HttpServerRequestInfo& info) {
- if (info.path.find("/json/version") == 0) {
- // New page request.
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpHandlerImpl::OnVersionRequestUI,
- this,
- connection_id,
- info));
- return;
- }
-
- if (info.path.find("/json/new") == 0) {
- // New page request.
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpHandlerImpl::OnNewTargetRequestUI,
- this,
- connection_id,
- info));
- return;
- }
-
- if (info.path.find("/json/close/") == 0) {
- // Close page request.
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpHandlerImpl::OnCloseTargetRequestUI,
- this,
- connection_id,
- info));
- return;
- }
-
if (info.path.find("/json") == 0) {
- // Pages discovery json request.
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -479,57 +442,122 @@ std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal(
rvh_id.c_str());
}
-void DevToolsHttpHandlerImpl::OnVersionRequestUI(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- DictionaryValue version;
- version.SetString("Protocol-Version",
- WebKit::WebDevToolsAgent::inspectorProtocolVersion());
- version.SetString("WebKit-Version",
- webkit_glue::GetWebKitVersion());
- version.SetString("User-Agent",
- webkit_glue::GetUserAgent(GURL(chrome::kAboutBlankURL)));
- SendJson(connection_id, info, version);
+static bool ParseJsonPath(
+ const std::string& path,
+ std::string* command,
+ std::string* target_id) {
+
+ // Fall back to list in case of empty query.
+ if (path.empty()) {
+ *command = "list";
+ return true;
+ }
+
+ if (path.find("/") != 0) {
+ // Malformed command.
+ return false;
+ }
+ *command = path.substr(1);
+
+ size_t separator_pos = command->find("/");
+ if (separator_pos != std::string::npos) {
+ *target_id = command->substr(separator_pos + 1);
+ *command = command->substr(0, separator_pos);
+ }
+ return true;
}
void DevToolsHttpHandlerImpl::OnJsonRequestUI(
int connection_id,
const net::HttpServerRequestInfo& info) {
- PageList page_list = GeneratePageList();
- ListValue json_pages_list;
- std::string host = info.headers["Host"];
- for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i)
- json_pages_list.Append(SerializePageInfo(*i, host));
- SendJson(connection_id, info, json_pages_list);
-}
+ // Trim /json and ?jsonp=...
+ std::string path = info.path.substr(5);
+ std::string jsonp;
+ size_t jsonp_pos = path.find("?jsonp=");
+ if (jsonp_pos != std::string::npos) {
+ jsonp = path.substr(jsonp_pos + 7);
+ path = path.substr(0, jsonp_pos);
+ }
+
+ std::string command;
+ std::string target_id;
+ if (!ParseJsonPath(path, &command, &target_id)) {
+ SendJson(connection_id,
+ net::HTTP_NOT_FOUND,
+ NULL,
+ "Malformed query: " + info.path,
+ jsonp);
+ return;
+ }
-void DevToolsHttpHandlerImpl::OnNewTargetRequestUI(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- RenderViewHost* rvh = delegate_->CreateNewTarget();
- if (!rvh) {
- Send500(connection_id, "Could not create new page");
+ if (command == "version") {
+ DictionaryValue version;
+ version.SetString("Protocol-Version",
+ WebKit::WebDevToolsAgent::inspectorProtocolVersion());
+ version.SetString("WebKit-Version",
+ webkit_glue::GetWebKitVersion());
+ version.SetString("User-Agent",
+ webkit_glue::GetUserAgent(GURL(chrome::kAboutBlankURL)));
+ SendJson(connection_id, net::HTTP_OK, &version, "", jsonp);
return;
}
- PageInfo page_info = CreatePageInfo(rvh);
- std::string host = info.headers["Host"];
- scoped_ptr<DictionaryValue> dictionary(SerializePageInfo(page_info, host));
- SendJson(connection_id, info, *dictionary);
-}
-void DevToolsHttpHandlerImpl::OnCloseTargetRequestUI(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- std::string prefix = "/json/close/";
- std::string page_id = info.path.substr(prefix.length());
- RenderViewHost* rvh = binding_->ForIdentifier(page_id);
- if (!rvh) {
- Send500(connection_id, "No such target id: " + page_id);
+ if (command == "list") {
+ PageList page_list = GeneratePageList();
+ ListValue json_pages_list;
+ std::string host = info.headers["Host"];
+ for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i)
+ json_pages_list.Append(SerializePageInfo(*i, host));
+ SendJson(connection_id, net::HTTP_OK, &json_pages_list, "", jsonp);
return;
}
- rvh->ClosePage();
- Send200(connection_id, "Target is closing");
+ if (command == "new") {
+ RenderViewHost* rvh = delegate_->CreateNewTarget();
+ if (!rvh) {
+ SendJson(connection_id,
+ net::HTTP_INTERNAL_SERVER_ERROR,
+ NULL,
+ "Could not create new page",
+ jsonp);
+ return;
+ }
+ PageInfo page_info = CreatePageInfo(rvh);
+ std::string host = info.headers["Host"];
+ scoped_ptr<DictionaryValue> dictionary(SerializePageInfo(page_info, host));
+ SendJson(connection_id, net::HTTP_OK, dictionary.get(), "", jsonp);
+ return;
+ }
+
+ if (command == "activate" || command == "close") {
+ RenderViewHost* rvh = binding_->ForIdentifier(target_id);
+ if (!rvh) {
+ SendJson(connection_id,
+ net::HTTP_NOT_FOUND,
+ NULL,
+ "No such target id: " + target_id,
+ jsonp);
+ return;
+ }
+
+ if (command == "activate") {
+ rvh->GetDelegate()->Activate();
+ SendJson(connection_id, net::HTTP_OK, NULL, "Target activated", jsonp);
+ return;
+ }
+
+ if (command == "close") {
+ rvh->ClosePage();
+ SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing", jsonp);
+ return;
+ }
+ }
+ SendJson(connection_id,
+ net::HTTP_NOT_FOUND,
+ NULL,
+ "Unknown command: " + command,
+ jsonp);
+ return;
}
void DevToolsHttpHandlerImpl::OnThumbnailRequestUI(
@@ -579,8 +607,8 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequestUI(
DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
rvh);
if (manager->GetDevToolsClientHostFor(agent)) {
- Send500(connection_id, "Target with given id is being inspected: " +
- page_id);
+ Send500(connection_id,
+ "Target with given id is being inspected: " + page_id);
return;
}
@@ -663,6 +691,53 @@ void DevToolsHttpHandlerImpl::StopHandlerThread() {
thread_->Stop();
}
+void DevToolsHttpHandlerImpl::SendJson(int connection_id,
+ net::HttpStatusCode status_code,
+ Value* value,
+ const std::string& message,
+ const std::string& jsonp) {
+ if (!thread_.get())
+ return;
+
+ // Serialize value and message.
+ std::string json_value;
+ if (value) {
+ base::JSONWriter::WriteWithOptions(value,
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &json_value);
+ }
+ std::string json_message;
+ scoped_ptr<Value> message_object(Value::CreateStringValue(message));
+ base::JSONWriter::Write(message_object.get(), &json_message);
+
+ std::string response;
+ std::string mime_type = "application/json; charset=UTF-8";
+
+ // Wrap jsonp if necessary.
+ if (!jsonp.empty()) {
+ mime_type = "text/javascript; charset=UTF-8";
+ response = StringPrintf("%s(%s, %d, %s);",
+ jsonp.c_str(),
+ json_value.empty() ? "undefined"
+ : json_value.c_str(),
+ status_code,
+ json_message.c_str());
+ // JSONP always returns 200.
+ status_code = net::HTTP_OK;
+ } else {
+ response = StringPrintf("%s%s", json_value.c_str(), message.c_str());
+ }
+
+ thread_->message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&net::HttpServer::Send,
+ server_.get(),
+ connection_id,
+ status_code,
+ response,
+ mime_type));
+}
+
void DevToolsHttpHandlerImpl::Send200(int connection_id,
const std::string& data,
const std::string& mime_type) {
@@ -677,25 +752,6 @@ void DevToolsHttpHandlerImpl::Send200(int connection_id,
mime_type));
}
-void DevToolsHttpHandlerImpl::SendJson(int connection_id,
- const net::HttpServerRequestInfo& info,
- const Value& value) {
- std::string response;
- base::JSONWriter::WriteWithOptions(&value,
- base::JSONWriter::OPTIONS_PRETTY_PRINT,
- &response);
-
- size_t jsonp_pos = info.path.find("?jsonp=");
- if (jsonp_pos == std::string::npos) {
- Send200(connection_id, response, "application/json; charset=UTF-8");
- return;
- }
-
- std::string jsonp = info.path.substr(jsonp_pos + 7);
- response = StringPrintf("%s(%s);", jsonp.c_str(), response.c_str());
- Send200(connection_id, response, "text/javascript; charset=UTF-8");
-}
-
void DevToolsHttpHandlerImpl::Send404(int connection_id) {
if (!thread_.get())
return;
diff --git a/content/browser/debugger/devtools_http_handler_impl.h b/content/browser/debugger/devtools_http_handler_impl.h
index b51bb1e..c912b92 100644
--- a/content/browser/debugger/devtools_http_handler_impl.h
+++ b/content/browser/debugger/devtools_http_handler_impl.h
@@ -76,14 +76,8 @@ class DevToolsHttpHandlerImpl
const std::string& data) OVERRIDE;
virtual void OnClose(int connection_id) OVERRIDE;
- void OnVersionRequestUI(int connection_id,
- const net::HttpServerRequestInfo& info);
void OnJsonRequestUI(int connection_id,
const net::HttpServerRequestInfo& info);
- void OnNewTargetRequestUI(int connection_id,
- const net::HttpServerRequestInfo& info);
- void OnCloseTargetRequestUI(int connection_id,
- const net::HttpServerRequestInfo& info);
void OnThumbnailRequestUI(int connection_id,
const net::HttpServerRequestInfo& info);
void OnDiscoveryPageRequestUI(int connection_id);
@@ -102,12 +96,14 @@ class DevToolsHttpHandlerImpl
void StartHandlerThread();
void StopHandlerThread();
+ void SendJson(int connection_id,
+ net::HttpStatusCode status_code,
+ base::Value* value,
+ const std::string& message,
+ const std::string& jsonp);
void Send200(int connection_id,
const std::string& data,
- const std::string& mime_type = "text/html");
- void SendJson(int connection_id,
- const net::HttpServerRequestInfo& info,
- const base::Value& value);
+ const std::string& mime_type);
void Send404(int connection_id);
void Send500(int connection_id,
const std::string& message);
diff --git a/net/server/http_connection.cc b/net/server/http_connection.cc
index d601f34..e82c9fe 100644
--- a/net/server/http_connection.cc
+++ b/net/server/http_connection.cc
@@ -26,42 +26,40 @@ void HttpConnection::Send(const char* bytes, int len) {
socket_->Send(bytes, len);
}
-void HttpConnection::Send200(const std::string& data,
- const std::string& content_type) {
+void HttpConnection::Send(HttpStatusCode status_code,
+ const std::string& data,
+ const std::string& content_type) {
if (!socket_)
return;
+
+ std::string status_message;
+ switch (status_code) {
+ case HTTP_OK:
+ status_message = "OK";
+ break;
+ case HTTP_NOT_FOUND:
+ status_message = "Not Found";
+ break;
+ case HTTP_INTERNAL_SERVER_ERROR:
+ status_message = "Internal Error";
+ break;
+ default:
+ status_message = "";
+ break;
+ }
+
socket_->Send(base::StringPrintf(
- "HTTP/1.1 200 OK\r\n"
+ "HTTP/1.1 %d %s\r\n"
"Content-Type:%s\r\n"
"Content-Length:%d\r\n"
"\r\n",
+ status_code,
+ status_message.c_str(),
content_type.c_str(),
static_cast<int>(data.length())));
socket_->Send(data);
}
-void HttpConnection::Send404() {
- if (!socket_)
- return;
- socket_->Send(
- "HTTP/1.1 404 Not Found\r\n"
- "Content-Length: 0\r\n"
- "\r\n");
-}
-
-void HttpConnection::Send500(const std::string& message) {
- if (!socket_)
- return;
- socket_->Send(base::StringPrintf(
- "HTTP/1.1 500 Internal Error\r\n"
- "Content-Type:text/html\r\n"
- "Content-Length:%d\r\n"
- "\r\n"
- "%s",
- static_cast<int>(message.length()),
- message.c_str()));
-}
-
HttpConnection::HttpConnection(HttpServer* server, StreamListenSocket* sock)
: server_(server),
socket_(sock) {
diff --git a/net/server/http_connection.h b/net/server/http_connection.h
index c3c573a..488d528 100644
--- a/net/server/http_connection.h
+++ b/net/server/http_connection.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "net/http/http_status_code.h"
namespace net {
@@ -23,9 +24,9 @@ class HttpConnection {
void Send(const std::string& data);
void Send(const char* bytes, int len);
- void Send200(const std::string& data, const std::string& content_type);
- void Send404();
- void Send500(const std::string& message);
+ void Send(HttpStatusCode status_code,
+ const std::string& data,
+ const std::string& content_type);
void Shift(int num_bytes);
diff --git a/net/server/http_server.cc b/net/server/http_server.cc
index 9582487..b92c211 100644
--- a/net/server/http_server.cc
+++ b/net/server/http_server.cc
@@ -45,42 +45,28 @@ void HttpServer::SendOverWebSocket(int connection_id,
connection->web_socket_->Send(data);
}
-void HttpServer::Send(int connection_id, const std::string& data) {
+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(data);
-}
-
-void HttpServer::Send(int connection_id, const char* bytes, int len) {
- HttpConnection* connection = FindConnection(connection_id);
- if (connection == NULL)
- return;
-
- connection->Send(bytes, len);
+ connection->Send(status_code, data, content_type);
}
void HttpServer::Send200(int connection_id,
const std::string& data,
const std::string& content_type) {
- HttpConnection* connection = FindConnection(connection_id);
- if (connection == NULL)
- return;
- connection->Send200(data, content_type);
+ Send(connection_id, HTTP_OK, data, content_type);
}
void HttpServer::Send404(int connection_id) {
- HttpConnection* connection = FindConnection(connection_id);
- if (connection == NULL)
- return;
- connection->Send404();
+ Send(connection_id, HTTP_NOT_FOUND, "", "text/html");
}
void HttpServer::Send500(int connection_id, const std::string& message) {
- HttpConnection* connection = FindConnection(connection_id);
- if (connection == NULL)
- return;
- connection->Send500(message);
+ Send(connection_id, HTTP_INTERNAL_SERVER_ERROR, message, "text/html");
}
void HttpServer::Close(int connection_id) {
diff --git a/net/server/http_server.h b/net/server/http_server.h
index bc6a290..54773ad 100644
--- a/net/server/http_server.h
+++ b/net/server/http_server.h
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "net/base/stream_listen_socket.h"
+#include "net/http/http_status_code.h"
namespace net {
@@ -45,13 +46,16 @@ class HttpServer : public StreamListenSocket::Delegate,
void AcceptWebSocket(int connection_id,
const HttpServerRequestInfo& request);
void SendOverWebSocket(int connection_id, const std::string& data);
- void Send(int connection_id, const std::string& data);
- void Send(int connection_id, const char* bytes, int len);
+ void Send(int connection_id,
+ HttpStatusCode status_code,
+ const std::string& data,
+ const std::string& mime_type);
void Send200(int connection_id,
const std::string& data,
const std::string& mime_type);
void Send404(int connection_id);
void Send500(int connection_id, const std::string& message);
+
void Close(int connection_id);
// Copies the local address to |address|. Returns a network error code.
diff --git a/net/server/web_socket.cc b/net/server/web_socket.cc
index e2829da..398e4e0 100644
--- a/net/server/web_socket.cc
+++ b/net/server/web_socket.cc
@@ -115,14 +115,18 @@ class WebSocketHixie76 : public net::WebSocket {
std::string key2 = request.GetHeaderValue("Sec-WebSocket-Key2");
if (key1.empty()) {
- connection->Send500("Invalid request format. "
- "Sec-WebSocket-Key1 is empty or isn't specified.");
+ connection->Send(net::HTTP_INTERNAL_SERVER_ERROR,
+ "Invalid request format. "
+ "Sec-WebSocket-Key1 is empty or isn't specified.",
+ "text/html");
return;
}
if (key2.empty()) {
- connection->Send500("Invalid request format. "
- "Sec-WebSocket-Key2 is empty or isn't specified.");
+ connection->Send(net::HTTP_INTERNAL_SERVER_ERROR,
+ "Invalid request format. "
+ "Sec-WebSocket-Key2 is empty or isn't specified.",
+ "text/html");
return;
}
@@ -175,8 +179,10 @@ class WebSocketHybi17 : public WebSocket {
std::string key = request.GetHeaderValue("Sec-WebSocket-Key");
if (key.empty()) {
- connection->Send500("Invalid request format. "
- "Sec-WebSocket-Key is empty or isn't specified.");
+ connection->Send(net::HTTP_INTERNAL_SERVER_ERROR,
+ "Invalid request format. "
+ "Sec-WebSocket-Key is empty or isn't specified.",
+ "text/html");
return NULL;
}
return new WebSocketHybi17(connection, request, pos);