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))),
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CommandMapping(kPost,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     "session/:sessionId/chromium/launch_app",
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     WrapToCommand("LaunchApp", base::Bind(&ExecuteLaunchApp))),
124a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
125a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/alert",
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsAlertOpen",
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteAlertCommand,
128a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                              base::Bind(&ExecuteGetAlert)))),
129a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
130a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
131a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/dismiss_alert",
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("DismissAlert",
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
134a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteDismissAlert)))),
135a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
136a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
137a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/accept_alert",
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("AcceptAlert",
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
140a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteAcceptAlert)))),
141a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
142a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
143a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/alert_text",
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetAlertMessage",
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
146a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteGetAlertText)))),
147a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
148a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
149a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/alert_text",
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetAlertPrompt",
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteAlertCommand,
152a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   base::Bind(&ExecuteSetAlertValue)))),
153a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
154a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/forward",
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GoForward", base::Bind(&ExecuteGoForward))),
156a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
157a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/back",
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GoBack", base::Bind(&ExecuteGoBack))),
159a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
160a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/refresh",
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Refresh", base::Bind(&ExecuteRefresh))),
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/execute",
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ExecuteScript", base::Bind(&ExecuteExecuteScript))),
166a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
167a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/execute_async",
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("ExecuteAsyncScript",
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteExecuteAsyncScript))),
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/url",
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetUrl", base::Bind(&ExecuteGetCurrentUrl))),
174a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
175a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/title",
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetTitle", base::Bind(&ExecuteGetTitle))),
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/source",
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSource", base::Bind(&ExecuteGetPageSource))),
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/screenshot",
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("Screenshot", base::Bind(&ExecuteScreenshot))),
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CommandMapping(
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          kGet,
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "session/:sessionId/chromium/heap_snapshot",
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          WrapToCommand("HeapSnapshot", base::Bind(&ExecuteTakeHeapSnapshot))),
189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/visible",
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
192a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/visible",
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element",
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("FindElement", base::Bind(&ExecuteFindElement, 50))),
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/elements",
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("FindElements", base::Bind(&ExecuteFindElements, 50))),
203a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
204a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/active",
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetActiveElement",
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetActiveElement))),
207a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
208a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/element",
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("FindChildElement",
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteFindChildElement, 50))),
211a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
212a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/elements",
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("FindChildElements",
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteFindChildElements, 50))),
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/click",
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClickElement", base::Bind(&ExecuteClickElement))),
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/clear",
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClearElement", base::Bind(&ExecuteClearElement))),
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/submit",
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SubmitElement", base::Bind(&ExecuteSubmitElement))),
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/text",
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetElementText", base::Bind(&ExecuteGetElementText))),
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/value",
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("TypeElement", base::Bind(&ExecuteSendKeysToElement))),
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/file",
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("UploadFile", base::Bind(&ExecuteUploadFile))),
239a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
240a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/value",
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementValue",
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementValue))),
243a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
244a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/name",
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementTagName",
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementTagName))),
247a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
248a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/selected",
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsElementSelected",
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteIsElementSelected))),
251a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
252a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/enabled",
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsElementEnabled",
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteIsElementEnabled))),
255a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
256a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/displayed",
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsElementDisplayed",
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteIsElementDisplayed))),
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/hover",
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("HoverElement", base::Bind(&ExecuteHoverOverElement))),
263a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
264a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/location",
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementLocation",
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementLocation))),
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/location_in_view",
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand(
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              "GetElementLocationInView",
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              base::Bind(&ExecuteGetElementLocationOnceScrolledIntoView))),
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/size",
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetElementSize", base::Bind(&ExecuteGetElementSize))),
277a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
278a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/attribute/:name",
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetElementAttribute",
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetElementAttribute))),
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/element/:id/equals/:other",
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("IsElementEqual", base::Bind(&ExecuteElementEquals))),
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/cookie",
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetCookies", base::Bind(&ExecuteGetCookies))),
289a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
290a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/cookie",
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("AddCookie", base::Bind(&ExecuteAddCookie))),
292a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
293a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/cookie",
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("DeleteAllCookies",
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteDeleteAllCookies))),
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kDelete,
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/cookie/:name",
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("DeleteCookie", base::Bind(&ExecuteDeleteCookie))),
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/frame",
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SwitchToFrame", base::Bind(&ExecuteSwitchToFrame))),
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
306a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          "session/:sessionId/frame/parent",
307a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          WrapToCommand("SwitchToParentFrame",
308a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        base::Bind(&ExecuteSwitchToParentFrame))),
309a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      CommandMapping(
310a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          kPost,
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window",
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SwitchToWindow", base::Bind(&ExecuteSwitchToWindow))),
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window/:windowHandle/size",
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetWindowSize", base::Bind(&ExecuteGetWindowSize))),
317a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
318a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window/:windowHandle/position",
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetWindowPosition",
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetWindowPosition))),
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window/:windowHandle/size",
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetWindowSize", base::Bind(&ExecuteSetWindowSize))),
325a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
326a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window/:windowHandle/position",
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("SetWindowPosition",
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteSetWindowPosition))),
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/window/:windowHandle/maximize",
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MaximizeWindow", base::Bind(&ExecuteMaximizeWindow))),
333a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
334a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/window",
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("CloseWindow", base::Bind(&ExecuteClose))),
336a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
337a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/element/:id/drag",
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
339a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
340a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
341a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/element/:id/css/:propertyName",
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetElementCSSProperty",
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetElementValueOfCSSProperty))),
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/timeouts/implicit_wait",
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetImplicitWait", base::Bind(&ExecuteImplicitlyWait))),
348a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
349a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/timeouts/async_script",
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("SetScriptTimeout",
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteSetScriptTimeout))),
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/timeouts",
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetTimeout", base::Bind(&ExecuteSetTimeout))),
356a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
357a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/execute_sql",
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/location",
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetGeolocation", base::Bind(&ExecuteGetLocation))),
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/location",
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetGeolocation", base::Bind(&ExecuteSetLocation))),
367a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
368a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/application_cache/status",
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&ExecuteGetStatus)),
370a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
371a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/browser_connection",
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
373a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
374a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/browser_connection",
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
376a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
377a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
378a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage/key/:key",
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetLocalStorageItem",
38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageItem, kLocalStorage))),
381a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
382a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kDelete,
383a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage/key/:key",
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("RemoveLocalStorageItem",
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteRemoveStorageItem, kLocalStorage))),
386a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
387a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
388a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage",
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetLocalStorageKeys",
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageKeys, kLocalStorage))),
391a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
392a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
393a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage",
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetLocalStorageKeys",
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteSetStorageItem, kLocalStorage))),
396a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
397a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kDelete,
398a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage",
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClearLocalStorage",
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteClearStorage, kLocalStorage))),
401a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
402a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
403a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/local_storage/size",
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetLocalStorageSize",
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageSize, kLocalStorage))),
406a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
407a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
408a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage/key/:key",
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSessionStorageItem",
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageItem, kSessionStorage))),
411a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kDelete,
412a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/session_storage/key/:key",
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("RemoveSessionStorageItem",
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteRemoveStorageItem,
415a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                              kSessionStorage))),
416a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
417a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
418a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage",
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSessionStorageKeys",
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageKeys, kSessionStorage))),
421a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
422a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
423a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage",
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("SetSessionStorageItem",
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteSetStorageItem, kSessionStorage))),
426a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
427a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kDelete,
428a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage",
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("ClearSessionStorage",
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteClearStorage, kSessionStorage))),
431a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
432a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kGet,
433a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/session_storage/size",
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("GetSessionStorageSize",
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        base::Bind(&ExecuteGetStorageSize, kSessionStorage))),
436a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
437a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/orientation",
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
439a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
440a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/orientation",
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
442a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
443a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/click",
44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Click", base::Bind(&ExecuteMouseClick))),
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/doubleclick",
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("DoubleClick", base::Bind(&ExecuteMouseDoubleClick))),
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/buttondown",
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MouseDown", base::Bind(&ExecuteMouseButtonDown))),
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
45458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
45558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/buttonup",
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MouseUp", base::Bind(&ExecuteMouseButtonUp))),
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
45858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
45958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "session/:sessionId/moveto",
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("MouseMove", base::Bind(&ExecuteMouseMoveTo))),
461a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(
462a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          kPost,
463a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          "session/:sessionId/keys",
46458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          WrapToCommand("Type", base::Bind(&ExecuteSendKeysToActiveElement))),
465a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
466a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/available_engines",
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
468a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
469a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/active_engine",
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
471a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
472a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/activated",
473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
474a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
475a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/deactivate",
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
477a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
478a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/ime/activate",
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
480a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
481a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/click",
48258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("Tap", base::Bind(&ExecuteTouchSingleTap))),
483a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
484a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/down",
48558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("TouchDown", base::Bind(&ExecuteTouchDown))),
486a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
487a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/up",
48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("TouchUp", base::Bind(&ExecuteTouchUp))),
489a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
490a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/move",
49158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("TouchMove", base::Bind(&ExecuteTouchMove))),
492a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
493a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/scroll",
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
495a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
496a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/doubleclick",
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
498a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
499a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/longclick",
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&UnimplementedCommand)),
501a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
502a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/touch/flick",
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     WrapToCommand("TouchFlick", base::Bind(&ExecuteFlick))),
504a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kPost,
505a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/log",
50658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetLog", base::Bind(&ExecuteGetLog))),
507a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
508a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/log/types",
50958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("GetLogTypes",
51058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&ExecuteGetAvailableLogTypes))),
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kPost, "logs", base::Bind(&UnimplementedCommand)),
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kGet, "status", base::Bind(&ExecuteGetStatus)),
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Custom Chrome commands:
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Allow quit all to be called with GET or POST.
51658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
51758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kGet,
51858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kShutdownPath,
51958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ExecuteQuitAll,
52058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("QuitAll", base::Bind(&ExecuteQuit, true)),
52158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     &session_thread_map_)),
52258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandMapping(
52358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kPost,
52458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kShutdownPath,
52558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ExecuteQuitAll,
52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("QuitAll", base::Bind(&ExecuteQuit, true)),
52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     &session_thread_map_)),
528a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      CommandMapping(kGet,
529a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                     "session/:sessionId/is_loading",
53058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     WrapToCommand("IsLoading", base::Bind(&ExecuteIsLoading))),
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CommandMapping(kGet,
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     "session/:sessionId/autoreport",
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     WrapToCommand("IsAutoReporting",
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::Bind(&ExecuteIsAutoReporting))),
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CommandMapping(kPost,
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     "session/:sessionId/autoreport",
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     WrapToCommand(
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         "SetAutoReporting",
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         base::Bind(&ExecuteSetAutoReporting))),
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
541a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  command_map_.reset(
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new CommandMap(commands, commands + arraysize(commands)));
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpHandler::~HttpHandler() {}
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
547ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid HttpHandler::Handle(const net::HttpServerRequestInfo& request,
548a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                         const HttpResponseSenderFunc& send_response_func) {
549a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  CHECK(thread_checker_.CalledOnValidThread());
550a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
551a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (received_shutdown_)
552a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
553a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
554a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  std::string path = request.path;
555a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (!StartsWithASCII(path, url_base_, true)) {
556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<net::HttpServerResponseInfo> response(
557a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new net::HttpServerResponseInfo(net::HTTP_BAD_REQUEST));
558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    response->SetBody("unhandled request", "text/plain");
559a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    send_response_func.Run(response.Pass());
560a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
561a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
562a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
563a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  path.erase(0, url_base_.length());
564a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
565a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  HandleCommand(request, path, send_response_func);
56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (path == kShutdownPath)
568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    received_shutdown_ = true;
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCommand HttpHandler::WrapToCommand(
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const char* name,
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const SessionCommand& session_command) {
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return base::Bind(&ExecuteSessionCommand,
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    &session_thread_map_,
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    name,
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    session_command,
57858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    false);
579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCommand HttpHandler::WrapToCommand(
58258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const char* name,
583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const WindowCommand& window_command) {
58458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return WrapToCommand(name, base::Bind(&ExecuteWindowCommand, window_command));
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCommand HttpHandler::WrapToCommand(
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const char* name,
589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const ElementCommand& element_command) {
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return WrapToCommand(name,
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       base::Bind(&ExecuteElementCommand, element_command));
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
594a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid HttpHandler::HandleCommand(
595ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const net::HttpServerRequestInfo& request,
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& trimmed_path,
597a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const HttpResponseSenderFunc& send_response_func) {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string session_id;
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandMap::const_iterator iter = command_map_->begin();
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (true) {
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter == command_map_->end()) {
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      scoped_ptr<net::HttpServerResponseInfo> response(
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          new net::HttpServerResponseInfo(net::HTTP_NOT_FOUND));
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      response->SetBody("unknown command: " + trimmed_path, "text/plain");
606a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      send_response_func.Run(response.Pass());
607a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      return;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (internal::MatchesCommand(
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            request.method, trimmed_path, *iter, &session_id, &params)) {
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++iter;
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
616ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (request.data.length()) {
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue* body_params;
618ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    scoped_ptr<base::Value> parsed_body(base::JSONReader::Read(request.data));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!parsed_body || !parsed_body->GetAsDictionary(&body_params)) {
620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      scoped_ptr<net::HttpServerResponseInfo> response(
621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          new net::HttpServerResponseInfo(net::HTTP_BAD_REQUEST));
6220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      response->SetBody("missing command parameters", "text/plain");
623a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      send_response_func.Run(response.Pass());
624a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      return;
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.MergeDictionary(body_params);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
629a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  iter->command.Run(params,
630a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                    session_id,
631a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                    base::Bind(&HttpHandler::PrepareResponse,
632a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                               weak_ptr_factory_.GetWeakPtr(),
633a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                               trimmed_path,
634a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                               send_response_func));
635a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
637a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid HttpHandler::PrepareResponse(
638a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& trimmed_path,
639a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const HttpResponseSenderFunc& send_response_func,
640a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const Status& status,
641a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    scoped_ptr<base::Value> value,
642a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& session_id) {
643a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  CHECK(thread_checker_.CalledOnValidThread());
644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<net::HttpServerResponseInfo> response =
645a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      PrepareResponseHelper(trimmed_path, status, value.Pass(), session_id);
646a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  send_response_func.Run(response.Pass());
647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (trimmed_path == kShutdownPath)
648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    quit_func_.Run();
649a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
650a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<net::HttpServerResponseInfo> HttpHandler::PrepareResponseHelper(
652a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& trimmed_path,
653a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const Status& status,
654a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    scoped_ptr<base::Value> value,
655a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& session_id) {
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (status.code() == kUnknownCommand) {
657a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<net::HttpServerResponseInfo> response(
658a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new net::HttpServerResponseInfo(net::HTTP_NOT_IMPLEMENTED));
659a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    response->SetBody("unimplemented command: " + trimmed_path, "text/plain");
660a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return response.Pass();
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (status.IsError()) {
664a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    Status full_status(status);
665a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    full_status.AddDetails(base::StringPrintf(
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "Driver info: chromedriver=%s,platform=%s %s %s",
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kChromeDriverVersion,
668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::SysInfo::OperatingSystemName().c_str(),
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::SysInfo::OperatingSystemVersion().c_str(),
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::SysInfo::OperatingSystemArchitecture().c_str()));
671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<base::DictionaryValue> error(new base::DictionaryValue());
672a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    error->SetString("message", full_status.message());
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    value.reset(error.release());
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!value)
676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    value.reset(base::Value::CreateNullValue());
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue body_params;
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  body_params.SetInteger("status", status.code());
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  body_params.Set("value", value.release());
681a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  body_params.SetString("sessionId", session_id);
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string body;
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::JSONWriter::WriteWithOptions(
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &body_params, base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION,
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &body);
686a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<net::HttpServerResponseInfo> response(
687a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new net::HttpServerResponseInfo(net::HTTP_OK));
688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  response->SetBody(body, "application/json; charset=utf-8");
689a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return response.Pass();
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kNewSessionPathPattern[] = "session";
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
696ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool MatchesMethod(HttpMethod command_method, const std::string& method) {
6976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string lower_method = base::StringToLowerASCII(method);
698ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  switch (command_method) {
699ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  case kGet:
700ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return lower_method == "get";
701ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  case kPost:
702ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return lower_method == "post" || lower_method == "put";
703ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  case kDelete:
704ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return lower_method == "delete";
705ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return false;
707ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
708ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
709ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool MatchesCommand(const std::string& method,
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const std::string& path,
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const CommandMapping& command,
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    std::string* session_id,
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    base::DictionaryValue* out_params) {
714ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!MatchesMethod(command.method, method))
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> path_parts;
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(path, '/', &path_parts);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> command_path_parts;
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(command.path_pattern, '/', &command_path_parts);
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (path_parts.size() != command_path_parts.size())
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < path_parts.size(); ++i) {
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(command_path_parts[i].length());
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (command_path_parts[i][0] == ':') {
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string name = command_path_parts[i];
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name.erase(0, 1);
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CHECK(name.length());
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (name == "sessionId")
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        *session_id = path_parts[i];
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      else
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params.SetString(name, path_parts[i]);
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (command_path_parts[i] != path_parts[i]) {
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_params->MergeDictionary(&params);
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace internal
744