1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_TEST_WEBDRIVER_DISPATCH_H_
#define CHROME_TEST_WEBDRIVER_DISPATCH_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/logging.h"
#include "chrome/test/webdriver/commands/response.h"
#include "third_party/mongoose/mongoose.h"
class DictionaryValue;
namespace base {
class WaitableEvent;
}
namespace webdriver {
class Command;
class HttpResponse;
namespace internal {
// Converts a |Response| into a |HttpResponse| to be returned to the client.
// This function is exposed for testing.
void PrepareHttpResponse(const Response& command_response,
HttpResponse* const http_response);
// Sends a |response| to a WebDriver command back to the client.
// |connection| is the communication pipe to the HTTP server and
// |request_info| contains any data sent by the user.
void SendResponse(struct mg_connection* const connection,
const std::string& request_method,
const Response& response);
// Parses the request info and returns whether parsing was successful. If not,
// |response| has been modified with the error.
bool ParseRequestInfo(const struct mg_request_info* const request_info,
std::string* method,
std::vector<std::string>* path_segments,
DictionaryValue** parameters,
Response* const response);
// Allows the bulk of the implementation of |Dispatch| to be moved out of this
// header file. Takes ownership of |command|.
void DispatchHelper(Command* const command,
const std::string& method,
Response* const response);
} // namespace internal
// Template function for dispatching commands sent to the WebDriver REST
// service. |CommandType| must be a subtype of |webdriver::Command|.
template<typename CommandType>
void Dispatch(struct mg_connection* connection,
const struct mg_request_info* request_info,
void* user_data) {
std::string method;
std::vector<std::string> path_segments;
DictionaryValue* parameters = NULL;
Response response;
if (internal::ParseRequestInfo(request_info,
&method,
&path_segments,
¶meters,
&response)) {
std::string post_data(request_info->post_data, request_info->post_data_len);
LOG(INFO) << "Received command, url: " << request_info->uri
<< ", method: " << request_info->request_method
<< ", postd data: " << post_data;
internal::DispatchHelper(
new CommandType(path_segments, parameters),
method,
&response);
}
internal::SendResponse(connection,
request_info->request_method,
response);
LOG(INFO) << "Sent command response, url: " << request_info->uri;
}
class Dispatcher {
public:
// Creates a new dispatcher that will register all URL callbacks with the
// given |context|. Each callback's pattern will be prefixed with the provided
// |root|.
Dispatcher(struct mg_context* context, const std::string& root);
~Dispatcher();
// Registers a callback for a WebDriver command using the given URL |pattern|.
// The |CommandType| must be a subtype of |webdriver::Command|.
template<typename CommandType>
void Add(const std::string& pattern);
// Registers a callback that will shutdown the server. When any HTTP request
// is received at this URL |pattern|, the |shutdown_event| will be signaled.
void AddShutdown(const std::string& pattern,
base::WaitableEvent* shutdown_event);
// Registers a callback for the given pattern that will return a simple
// "HTTP/1.1 200 OK" message with "ok" in the body. Used for checking the
// status of the server.
void AddHealthz(const std::string& pattern);
// Registers a callback for the given pattern that will return the current
// WebDriver log contents.
void AddLog(const std::string& pattern);
// Registers a callback that will always respond with a
// "HTTP/1.1 501 Not Implemented" message.
void SetNotImplemented(const std::string& pattern);
// Registers a callback that will respond for all other requests with a
// "HTTP/1.1 403 Forbidden" message. Should be called only after registering
// other callbacks.
void ForbidAllOtherRequests();
private:
struct mg_context* context_;
const std::string root_;
DISALLOW_COPY_AND_ASSIGN(Dispatcher);
};
template <typename CommandType>
void Dispatcher::Add(const std::string& pattern) {
mg_set_uri_callback(context_, (root_ + pattern).c_str(),
&Dispatch<CommandType>, NULL);
}
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_DISPATCH_H_
|