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