12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/server/http_handler.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h"  // For CHECK macros.
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/message_loop/message_loop_proxy.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/sys_info.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/test/chromedriver/alert_commands.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/test/chromedriver/chrome/adb_impl.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/test/chromedriver/chrome/device_manager.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h"
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/test/chromedriver/net/port_server.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/test/chromedriver/net/url_request_context_getter.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/test/chromedriver/session.h"
27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/test/chromedriver/session_thread_map.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/util.h"
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/test/chromedriver/version.h"
30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/server/http_server_request_info.h"
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/server/http_server_response_info.h"
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX)
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/mac/scoped_nsautorelease_pool.h"
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kLocalStorage[] = "localStorage";
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kSessionStorage[] = "sessionStorage";
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kShutdownPath[] = "shutdown";
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid UnimplementedCommand(
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::DictionaryValue& params,
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& session_id,
46a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const CommandCallback& callback) {
47a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  callback.Run(Status(kUnknownCommand), scoped_ptr<base::Value>(), session_id);
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CommandMapping::CommandMapping(HttpMethod method,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const std::string& path_pattern,
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               const Command& command)
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : method(method), path_pattern(path_pattern), command(command) {}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CommandMapping::~CommandMapping() {}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)HttpHandler::HttpHandler(const std::string& url_base)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : url_base_(url_base),
61a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      received_shutdown_(false),
62a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      command_map_(new CommandMap()),
63a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      weak_ptr_factory_(this) {}
64a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
65a3f7b4e666c476898878fa745f637129375cd889Ben MurdochHttpHandler::HttpHandler(
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::Closure& quit_func,
67a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& url_base,
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int adb_port,
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    scoped_ptr<PortServer> port_server)
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : quit_func_(quit_func),
72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      url_base_(url_base),
73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      received_shutdown_(false),
74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      weak_ptr_factory_(this) {
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_MACOSX)
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::mac::ScopedNSAutoreleasePool autorelease_pool;
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  context_getter_ = new URLRequestContextGetter(io_task_runner);
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  socket_factory_ = CreateSyncWebSocketFactory(context_getter_.get());
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  adb_.reset(new AdbImpl(io_task_runner, adb_port));
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  device_manager_.reset(new DeviceManager(adb_.get()));
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  port_server_ = port_server.Pass();
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  port_manager_.reset(new PortManager(12000, 13000));
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandMapping commands[] = {
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          internal::kNewSessionPathPattern,
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ExecuteCreateSession,
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     &session_thread_map_,
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     WrapToCommand(
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         "InitSession",
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         base::Bind(&ExecuteInitSession,
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                    InitSessionParams(context_getter_,
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      socket_factory_,
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      device_manager_.get(),
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                      port_server_.get(),
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                      port_manager_.get()))))),
99a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
100a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId",
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetSessionCapabilities",
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetSessionCapabilities))),
103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
104a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId",
105a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     base::Bind(&ExecuteSessionCommand,
106a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                &session_thread_map_,
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                "Quit",
108a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                base::Bind(&ExecuteQuit, false),
109a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                true)),
110a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
111a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window_handle",
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetWindow",
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetCurrentWindowHandle))),
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window_handles",
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetWindows", base::Bind(&ExecuteGetWindowHandles))),
118a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
119a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/url",
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Navigate", base::Bind(&ExecuteGet))),
121a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
122a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/alert",
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsAlertOpen",
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteAlertCommand,
125a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                              base::Bind(&ExecuteGetAlert)))),
126a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
127a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
128a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/dismiss_alert",
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("DismissAlert",
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
131a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteDismissAlert)))),
132a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
133a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
134a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/accept_alert",
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("AcceptAlert",
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
137a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteAcceptAlert)))),
138a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
139a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
140a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/alert_text",
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetAlertMessage",
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
143a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteGetAlertText)))),
144a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
145a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
146a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/alert_text",
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetAlertPrompt",
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
149a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteSetAlertValue)))),
150a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
151a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/forward",
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GoForward", base::Bind(&ExecuteGoForward))),
153a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
154a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/back",
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GoBack", base::Bind(&ExecuteGoBack))),
156a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
157a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/refresh",
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Refresh", base::Bind(&ExecuteRefresh))),
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/execute",
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ExecuteScript", base::Bind(&ExecuteExecuteScript))),
163a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
164a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/execute_async",
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("ExecuteAsyncScript",
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteExecuteAsyncScript))),
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/url",
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetUrl", base::Bind(&ExecuteGetCurrentUrl))),
171a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
172a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/title",
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetTitle", base::Bind(&ExecuteGetTitle))),
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/source",
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSource", base::Bind(&ExecuteGetPageSource))),
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/screenshot",
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("Screenshot", base::Bind(&ExecuteScreenshot))),
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CommandMapping(
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          kGet,
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "session/:sessionId/chromium/heap_snapshot",
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          WrapToCommand("HeapSnapshot", base::Bind(&ExecuteTakeHeapSnapshot))),
186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
187a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/visible",
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/visible",
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element",
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("FindElement", base::Bind(&ExecuteFindElement, 50))),
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/elements",
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("FindElements", base::Bind(&ExecuteFindElements, 50))),
200a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
201a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/active",
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetActiveElement",
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetActiveElement))),
204a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
205a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/element",
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("FindChildElement",
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteFindChildElement, 50))),
208a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
209a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/elements",
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("FindChildElements",
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteFindChildElements, 50))),
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/click",
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClickElement", base::Bind(&ExecuteClickElement))),
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/clear",
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClearElement", base::Bind(&ExecuteClearElement))),
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/submit",
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SubmitElement", base::Bind(&ExecuteSubmitElement))),
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/text",
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetElementText", base::Bind(&ExecuteGetElementText))),
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/value",
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("TypeElement", base::Bind(&ExecuteSendKeysToElement))),
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/file",
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("UploadFile", base::Bind(&ExecuteUploadFile))),
236a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
237a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/value",
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementValue",
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementValue))),
240a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
241a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/name",
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementTagName",
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementTagName))),
244a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
245a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/selected",
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsElementSelected",
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteIsElementSelected))),
248a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
249a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/enabled",
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsElementEnabled",
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteIsElementEnabled))),
252a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
253a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/displayed",
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsElementDisplayed",
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteIsElementDisplayed))),
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/hover",
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("HoverElement", base::Bind(&ExecuteHoverOverElement))),
260a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
261a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/location",
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementLocation",
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementLocation))),
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/location_in_view",
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand(
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              "GetElementLocationInView",
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              base::Bind(&ExecuteGetElementLocationOnceScrolledIntoView))),
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/size",
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetElementSize", base::Bind(&ExecuteGetElementSize))),
274a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
275a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/attribute/:name",
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementAttribute",
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementAttribute))),
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/equals/:other",
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("IsElementEqual", base::Bind(&ExecuteElementEquals))),
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/cookie",
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetCookies", base::Bind(&ExecuteGetCookies))),
286a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
287a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/cookie",
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("AddCookie", base::Bind(&ExecuteAddCookie))),
289a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
290a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/cookie",
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("DeleteAllCookies",
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteDeleteAllCookies))),
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kDelete,
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/cookie/:name",
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("DeleteCookie", base::Bind(&ExecuteDeleteCookie))),
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/frame",
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SwitchToFrame", base::Bind(&ExecuteSwitchToFrame))),
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window",
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SwitchToWindow", base::Bind(&ExecuteSwitchToWindow))),
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window/:windowHandle/size",
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetWindowSize", base::Bind(&ExecuteGetWindowSize))),
309a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
310a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window/:windowHandle/position",
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetWindowPosition",
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetWindowPosition))),
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window/:windowHandle/size",
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetWindowSize", base::Bind(&ExecuteSetWindowSize))),
317a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
318a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window/:windowHandle/position",
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("SetWindowPosition",
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteSetWindowPosition))),
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window/:windowHandle/maximize",
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MaximizeWindow", base::Bind(&ExecuteMaximizeWindow))),
325a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
326a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window",
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("CloseWindow", base::Bind(&ExecuteClose))),
328a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
329a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/drag",
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
331a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
332a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
333a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/element/:id/css/:propertyName",
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetElementCSSProperty",
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetElementValueOfCSSProperty))),
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/timeouts/implicit_wait",
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetImplicitWait", base::Bind(&ExecuteImplicitlyWait))),
340a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
341a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/timeouts/async_script",
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("SetScriptTimeout",
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteSetScriptTimeout))),
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/timeouts",
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetTimeout", base::Bind(&ExecuteSetTimeout))),
348a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
349a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/execute_sql",
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/location",
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetGeolocation", base::Bind(&ExecuteGetLocation))),
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/location",
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetGeolocation", base::Bind(&ExecuteSetLocation))),
359a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
360a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/application_cache/status",
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&ExecuteGetStatus)),
362a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
363a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/browser_connection",
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
365a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
366a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/browser_connection",
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
368a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
369a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
370a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage/key/:key",
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetLocalStorageItem",
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageItem, kLocalStorage))),
373a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
374a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kDelete,
375a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage/key/:key",
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("RemoveLocalStorageItem",
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteRemoveStorageItem, kLocalStorage))),
378a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
379a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
380a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage",
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetLocalStorageKeys",
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageKeys, kLocalStorage))),
383a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
384a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
385a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage",
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetLocalStorageKeys",
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteSetStorageItem, kLocalStorage))),
388a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
389a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kDelete,
390a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage",
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClearLocalStorage",
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteClearStorage, kLocalStorage))),
393a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
394a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
395a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage/size",
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetLocalStorageSize",
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageSize, kLocalStorage))),
398a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
399a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
400a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage/key/:key",
40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSessionStorageItem",
40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageItem, kSessionStorage))),
403a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
404a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/session_storage/key/:key",
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("RemoveSessionStorageItem",
40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteRemoveStorageItem,
407a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                              kSessionStorage))),
408a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
409a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
410a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage",
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSessionStorageKeys",
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageKeys, kSessionStorage))),
413a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
414a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
415a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage",
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetSessionStorageItem",
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteSetStorageItem, kSessionStorage))),
418a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
419a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kDelete,
420a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage",
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClearSessionStorage",
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteClearStorage, kSessionStorage))),
423a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
424a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
425a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage/size",
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSessionStorageSize",
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageSize, kSessionStorage))),
428a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
429a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/orientation",
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
431a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
432a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/orientation",
433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
434a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
435a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/click",
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Click", base::Bind(&ExecuteMouseClick))),
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/doubleclick",
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("DoubleClick", base::Bind(&ExecuteMouseDoubleClick))),
44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/buttondown",
44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MouseDown", base::Bind(&ExecuteMouseButtonDown))),
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/buttonup",
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MouseUp", base::Bind(&ExecuteMouseButtonUp))),
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/moveto",
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MouseMove", base::Bind(&ExecuteMouseMoveTo))),
453a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
454a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
455a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/keys",
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("Type", base::Bind(&ExecuteSendKeysToActiveElement))),
457a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
458a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/available_engines",
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
460a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
461a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/active_engine",
462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
463a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
464a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/activated",
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
466a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
467a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/deactivate",
468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
469a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
470a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/activate",
471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
472a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
473a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/click",
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Tap", base::Bind(&ExecuteTouchSingleTap))),
475a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
476a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/down",
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("TouchDown", base::Bind(&ExecuteTouchDown))),
478a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
479a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/up",
48058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("TouchUp", base::Bind(&ExecuteTouchUp))),
481a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
482a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/move",
48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("TouchMove", base::Bind(&ExecuteTouchMove))),
484a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
485a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/scroll",
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
487a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
488a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/doubleclick",
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
490a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
491a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/longclick",
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
493a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
494a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/flick",
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
496a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
497a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/log",
49858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetLog", base::Bind(&ExecuteGetLog))),
499a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
500a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/log/types",
50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetLogTypes",
50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetAvailableLogTypes))),
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kPost, "logs", base::Bind(&UnimplementedCommand)),
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kGet, "status", base::Bind(&ExecuteGetStatus)),
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Custom Chrome commands:
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Allow quit all to be called with GET or POST.
50858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
50958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
51058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kShutdownPath,
51158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ExecuteQuitAll,
51258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("QuitAll", base::Bind(&ExecuteQuit, true)),
51358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     &session_thread_map_)),
51458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
51558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
51658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kShutdownPath,
51758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ExecuteQuitAll,
51858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("QuitAll", base::Bind(&ExecuteQuit, true)),
51958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     &session_thread_map_)),
520a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
521a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/is_loading",
52258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsLoading", base::Bind(&ExecuteIsLoading))),
52358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
524a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  command_map_.reset(
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new CommandMap(commands, commands + arraysize(commands)));
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpHandler::~HttpHandler() {}
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
530ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid HttpHandler::Handle(const net::HttpServerRequestInfo& request,
531a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                         const HttpResponseSenderFunc& send_response_func) {
532a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  CHECK(thread_checker_.CalledOnValidThread());
533a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
534a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (received_shutdown_)
535a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
536a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
537a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  std::string path = request.path;
538a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (!StartsWithASCII(path, url_base_, true)) {
539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<net::HttpServerResponseInfo> response(
540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new net::HttpServerResponseInfo(net::HTTP_BAD_REQUEST));
541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    response->SetBody("unhandled request", "text/plain");
542a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    send_response_func.Run(response.Pass());
543a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
544a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
545a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
546a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  path.erase(0, url_base_.length());
547a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
548a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  HandleCommand(request, path, send_response_func);
54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (path == kShutdownPath)
551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    received_shutdown_ = true;
55290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCommand HttpHandler::WrapToCommand(
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const char* name,
556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const SessionCommand& session_command) {
55758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return base::Bind(&ExecuteSessionCommand,
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    &session_thread_map_,
55958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    name,
56058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    session_command,
56158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    false);
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCommand HttpHandler::WrapToCommand(
56558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const char* name,
566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const WindowCommand& window_command) {
56758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return WrapToCommand(name, base::Bind(&ExecuteWindowCommand, window_command));
568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCommand HttpHandler::WrapToCommand(
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const char* name,
572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const ElementCommand& element_command) {
57358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return WrapToCommand(name,
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       base::Bind(&ExecuteElementCommand, element_command));
575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
577a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid HttpHandler::HandleCommand(
578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const net::HttpServerRequestInfo& request,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& trimmed_path,
580a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const HttpResponseSenderFunc& send_response_func) {
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string session_id;
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandMap::const_iterator iter = command_map_->begin();
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (true) {
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter == command_map_->end()) {
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      scoped_ptr<net::HttpServerResponseInfo> response(
587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          new net::HttpServerResponseInfo(net::HTTP_NOT_FOUND));
588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      response->SetBody("unknown command: " + trimmed_path, "text/plain");
589a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      send_response_func.Run(response.Pass());
590a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      return;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (internal::MatchesCommand(
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            request.method, trimmed_path, *iter, &session_id, &params)) {
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++iter;
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (request.data.length()) {
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue* body_params;
601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    scoped_ptr<base::Value> parsed_body(base::JSONReader::Read(request.data));
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!parsed_body || !parsed_body->GetAsDictionary(&body_params)) {
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      scoped_ptr<net::HttpServerResponseInfo> response(
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          new net::HttpServerResponseInfo(net::HTTP_BAD_REQUEST));
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      response->SetBody("missing command parameters", "test/plain");
606a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      send_response_func.Run(response.Pass());
607a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      return;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.MergeDictionary(body_params);
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  iter->command.Run(params,
613a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                    session_id,
614a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                    base::Bind(&HttpHandler::PrepareResponse,
615a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                               weak_ptr_factory_.GetWeakPtr(),
616a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                               trimmed_path,
617a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                               send_response_func));
618a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
620a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid HttpHandler::PrepareResponse(
621a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& trimmed_path,
622a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const HttpResponseSenderFunc& send_response_func,
623a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const Status& status,
624a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    scoped_ptr<base::Value> value,
625a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& session_id) {
626a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  CHECK(thread_checker_.CalledOnValidThread());
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<net::HttpServerResponseInfo> response =
628a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      PrepareResponseHelper(trimmed_path, status, value.Pass(), session_id);
629a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  send_response_func.Run(response.Pass());
630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (trimmed_path == kShutdownPath)
631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    quit_func_.Run();
632a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
633a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<net::HttpServerResponseInfo> HttpHandler::PrepareResponseHelper(
635a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& trimmed_path,
636a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const Status& status,
637a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    scoped_ptr<base::Value> value,
638a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& session_id) {
639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (status.code() == kUnknownCommand) {
640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<net::HttpServerResponseInfo> response(
641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new net::HttpServerResponseInfo(net::HTTP_NOT_IMPLEMENTED));
642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    response->SetBody("unimplemented command: " + trimmed_path, "text/plain");
643a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return response.Pass();
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (status.IsError()) {
647a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    Status full_status(status);
648a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    full_status.AddDetails(base::StringPrintf(
649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "Driver info: chromedriver=%s,platform=%s %s %s",
650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kChromeDriverVersion,
651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::SysInfo::OperatingSystemName().c_str(),
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::SysInfo::OperatingSystemVersion().c_str(),
653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::SysInfo::OperatingSystemArchitecture().c_str()));
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<base::DictionaryValue> error(new base::DictionaryValue());
655a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    error->SetString("message", full_status.message());
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    value.reset(error.release());
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!value)
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    value.reset(base::Value::CreateNullValue());
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue body_params;
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  body_params.SetInteger("status", status.code());
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  body_params.Set("value", value.release());
664a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  body_params.SetString("sessionId", session_id);
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string body;
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::JSONWriter::WriteWithOptions(
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &body_params, base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION,
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &body);
669a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<net::HttpServerResponseInfo> response(
670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new net::HttpServerResponseInfo(net::HTTP_OK));
671a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  response->SetBody(body, "application/json; charset=utf-8");
672a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return response.Pass();
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kNewSessionPathPattern[] = "session";
678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
679ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool MatchesMethod(HttpMethod command_method, const std::string& method) {
680ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string lower_method = StringToLowerASCII(method);
681ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  switch (command_method) {
682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  case kGet:
683ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return lower_method == "get";
684ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  case kPost:
685ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return lower_method == "post" || lower_method == "put";
686ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  case kDelete:
687ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return lower_method == "delete";
688ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
689ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return false;
690ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
691ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
692ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool MatchesCommand(const std::string& method,
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const std::string& path,
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const CommandMapping& command,
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    std::string* session_id,
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    base::DictionaryValue* out_params) {
697ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!MatchesMethod(command.method, method))
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> path_parts;
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(path, '/', &path_parts);
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> command_path_parts;
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(command.path_pattern, '/', &command_path_parts);
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (path_parts.size() != command_path_parts.size())
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < path_parts.size(); ++i) {
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(command_path_parts[i].length());
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (command_path_parts[i][0] == ':') {
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string name = command_path_parts[i];
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name.erase(0, 1);
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CHECK(name.length());
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (name == "sessionId")
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        *session_id = path_parts[i];
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      else
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params.SetString(name, path_parts[i]);
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (command_path_parts[i] != path_parts[i]) {
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_params->MergeDictionary(&params);
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace internal
727