| Index: chrome/test/webdriver/dispatch.cc
|
| ===================================================================
|
| --- chrome/test/webdriver/dispatch.cc (revision 0)
|
| +++ chrome/test/webdriver/dispatch.cc (revision 0)
|
| @@ -0,0 +1,199 @@
|
| +// 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 "chrome/test/webdriver/dispatch.h"
|
| +
|
| +#include <sstream>
|
| +#include <string>
|
| +
|
| +#include "base/json/json_writer.h"
|
| +#include "chrome/test/webdriver/commands/command.h"
|
| +
|
| +namespace webdriver {
|
| +
|
| +// The standard HTTP Status codes are implemented below. Chrome uses
|
| +// OK, See Other, Not Found, Method Not Allowed, and Internal Error.
|
| +// Internal Error, HTTP 500, is used as a catch all for any issue
|
| +// not covered in the JSON protocol.
|
| +void SendHttpOk(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + const std::string json = response.ToJSON();
|
| + std::ostringstream out;
|
| + out << "HTTP/1.1 200 OK\r\n"
|
| + << "Content-Length: " << strlen(json.c_str()) << "\r\n"
|
| + << "Content-Type: application/json; charset=UTF-8\r\n"
|
| + << "Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept\r\n"
|
| + << "Accept-Ranges: bytes\r\n"
|
| + << "Connection: close\r\n\r\n";
|
| + if (strcmp(request_info->request_method, "HEAD") != 0) {
|
| + out << json << "\r\n";
|
| + }
|
| + LOG(INFO) << out.str() << std::endl;
|
| + mg_printf(connection, "%s", out.str().c_str());
|
| +}
|
| +
|
| +void SendHttpSeeOther(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + const Value* value = response.value();
|
| + CheckValueType(Value::TYPE_STRING, value);
|
| + std::string location;
|
| + if (!value->GetAsString(&location)) {
|
| + NOTREACHED();
|
| + }
|
| +
|
| + std::ostringstream out;
|
| + out << "HTTP/1.1 303 See Other\r\n"
|
| + << "Location: " << location << "\r\n"
|
| + << "Content-Type: text/html\r\n"
|
| + << "Content-Length: 0\r\n\r\n";
|
| + LOG(INFO) << out.str() << std::endl;
|
| + mg_printf(connection, "%s", out.str().c_str());
|
| +}
|
| +
|
| +void SendHttpBadRequest(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + const std::string json = response.ToJSON();
|
| + std::ostringstream out;
|
| + out << "HTTP/1.1 400 Bad Request\r\n"
|
| + << "Content-Length: " << strlen(json.c_str()) << "\r\n"
|
| + << "Content-Type: application/json; charset=UTF-8\r\n"
|
| + << "Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept\r\n"
|
| + << "Accept-Ranges: bytes\r\n"
|
| + << "Connection: close\r\n\r\n";
|
| + if (strcmp(request_info->request_method, "HEAD") != 0) {
|
| + out << json << "\r\n";
|
| + }
|
| + LOG(INFO) << out.str() << std::endl;
|
| + mg_printf(connection, "%s", out.str().c_str());
|
| +}
|
| +
|
| +void SendHttpNotFound(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + const std::string json = response.ToJSON();
|
| + std::ostringstream out;
|
| + out << "HTTP/1.1 404 Not Found\r\n"
|
| + << "Content-Length: " << strlen(json.c_str()) << "\r\n"
|
| + << "Content-Type: application/json; charset=UTF-8\r\n"
|
| + << "Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept\r\n"
|
| + << "Accept-Ranges: bytes\r\n"
|
| + << "Connection: close\r\n\r\n";
|
| + if (strcmp(request_info->request_method, "HEAD") != 0) {
|
| + out << json << "\r\n";
|
| + }
|
| + LOG(INFO) << out.str() << std::endl;
|
| + mg_printf(connection, "%s", out.str().c_str());
|
| +}
|
| +
|
| +void SendHttpMethodNotAllowed(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + const Value* value = response.value();
|
| + CheckValueType(Value::TYPE_LIST, value);
|
| +
|
| + std::vector<std::string> allowed_methods;
|
| + const ListValue* list_value = static_cast<const ListValue*>(value);
|
| + for (size_t i = 0; i < list_value->GetSize(); ++i) {
|
| + std::string method;
|
| + LOG_IF(WARNING, list_value->GetString(i, &method))
|
| + << "Ignoring non-string value at index " << i;
|
| + allowed_methods.push_back(method);
|
| + }
|
| +
|
| + std::ostringstream out;
|
| + out << "HTTP/1.1 405 Method Not Allowed\r\n"
|
| + << "Content-Type: text/html\r\n"
|
| + << "Content-Length: 0\r\n"
|
| + << "Allow: " << JoinString(allowed_methods, ',') << "\r\n\r\n";
|
| + LOG(INFO) << out.str() << std::endl;
|
| + mg_printf(connection, "%s", out.str().c_str());
|
| +}
|
| +
|
| +void SendHttpInternalError(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + const std::string json = response.ToJSON();
|
| + std::ostringstream out;
|
| + out << "HTTP/1.1 500 Internal Server Error\r\n"
|
| + << "Content-Length: " << strlen(json.c_str()) << "\r\n"
|
| + << "Content-Type: application/json; charset=UTF-8\r\n"
|
| + << "Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept\r\n"
|
| + << "Accept-Ranges: bytes\r\n"
|
| + << "Connection: close\r\n\r\n";
|
| + if (strcmp(request_info->request_method, "HEAD") != 0) {
|
| + out << json << "\r\n";
|
| + }
|
| + LOG(INFO) << out.str() << std::endl;
|
| + mg_printf(connection, "%s", out.str().c_str());
|
| +}
|
| +
|
| +// For every HTTP request from the mongoode server DispatchCommand will
|
| +// inspect the HTTP method call requested and execute the proper function
|
| +// mapped from the class Command.
|
| +void DispatchCommand(Command* const command, const std::string& method,
|
| + Response* response) {
|
| + if (command->DoesPost() && method == "POST") {
|
| + if (command->Init(response)) {
|
| + command->ExecutePost(response);
|
| + }
|
| + } else if (command->DoesGet() && method == "GET") {
|
| + if (command->Init(response)) {
|
| + command->ExecuteGet(response);
|
| + }
|
| + } else if (command->DoesDelete() && method == "DELETE") {
|
| + if (command->Init(response)) {
|
| + command->ExecuteDelete(response);
|
| + }
|
| + } else {
|
| + ListValue* methods = new ListValue;
|
| + if (command->DoesPost()) {
|
| + methods->Append(Value::CreateStringValue("POST"));
|
| + }
|
| + if (command->DoesGet()) {
|
| + methods->Append(Value::CreateStringValue("GET"));
|
| + methods->Append(Value::CreateStringValue("HEAD"));
|
| + }
|
| + if (command->DoesDelete()) {
|
| + methods->Append(Value::CreateStringValue("DELETE"));
|
| + }
|
| + response->set_status(kMethodNotAllowed);
|
| + response->set_value(methods); // Assumes ownership.
|
| + }
|
| +}
|
| +
|
| +void SendResponse(struct mg_connection* const connection,
|
| + const struct mg_request_info* const request_info,
|
| + const Response& response) {
|
| + switch (response.status()) {
|
| + case kSuccess:
|
| + SendHttpOk(connection, request_info, response);
|
| + break;
|
| +
|
| + case kSeeOther:
|
| + SendHttpSeeOther(connection, request_info, response);
|
| + break;
|
| +
|
| + case kBadRequest:
|
| + SendHttpBadRequest(connection, request_info, response);
|
| + break;
|
| +
|
| + case kSessionNotFound:
|
| + SendHttpNotFound(connection, request_info, response);
|
| + break;
|
| +
|
| + case kMethodNotAllowed:
|
| + SendHttpMethodNotAllowed(connection, request_info, response);
|
| + break;
|
| +
|
| + // All other errors should be treated as generic 500s. The client will be
|
| + // responsible for inspecting the message body for details.
|
| + default:
|
| + SendHttpInternalError(connection, request_info, response);
|
| + break;
|
| + }
|
| +}
|
| +} // namespace webdriver
|
| +
|
|
|
| Property changes on: chrome/test/webdriver/dispatch.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|