Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: chrome/test/chrome_plugin/test_chrome_plugin.cc

Issue 6576020: Remove Gears from Chrome (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: windows fixes Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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 #include "chrome/test/chrome_plugin/test_chrome_plugin.h"
6
7 #include "base/at_exit.h"
8 #include "base/basictypes.h"
9 #include "base/logging.h"
10 #include "base/message_loop.h"
11 #include "base/string_util.h"
12 #include "chrome/common/chrome_plugin_api.h"
13 #include "googleurl/src/gurl.h"
14
15 static CPID g_cpid;
16 static CPBrowserFuncs g_cpbrowser_funcs;
17 static CPRequestFuncs g_cprequest_funcs;
18 static CPResponseFuncs g_cpresponse_funcs;
19 static TestFuncParams::BrowserFuncs g_cptest_funcs;
20
21 // Create a global AtExitManager so that our code can use code from base that
22 // uses Singletons, for example. We don't care about static constructors here.
23 static base::AtExitManager global_at_exit_manager;
24
25 const TestResponsePayload* FindPayload(const char* url) {
26 for (size_t i = 0; i < arraysize(kChromeTestPluginPayloads); ++i) {
27 if (strcmp(kChromeTestPluginPayloads[i].url, url) == 0)
28 return &kChromeTestPluginPayloads[i];
29 }
30 return NULL;
31 }
32
33 std::string GetPayloadHeaders(const TestResponsePayload* payload) {
34 return StringPrintf(
35 "HTTP/1.1 200 OK%c"
36 "Content-type: %s%c"
37 "%c", 0, payload->mime_type, 0, 0);
38 }
39
40 void STDCALL InvokeLaterCallback(void* data) {
41 Task* task = static_cast<Task*>(data);
42 task->Run();
43 delete task;
44 }
45
46 // ResponseStream: Manages the streaming of the payload data.
47
48 class ResponseStream : public base::RefCounted<ResponseStream> {
49 public:
50 ResponseStream(const TestResponsePayload* payload, CPRequest* request);
51
52 void Init();
53 int GetResponseInfo(CPResponseInfoType type, void* buf, uint32 buf_size);
54 int ReadData(void* buf, uint32 buf_size);
55
56 private:
57 friend class base::RefCounted<ResponseStream>;
58
59 ~ResponseStream() {
60 request_->pdata = NULL;
61 }
62
63 // Called asynchronously via InvokeLater.
64 void ResponseStarted();
65 int ReadCompleted(void* buf, uint32 buf_size);
66
67 enum ReadyStates {
68 READY_INVALID = 0,
69 READY_WAITING = 1,
70 READY_GOT_HEADERS = 2,
71 READY_GOT_DATA = 3,
72 };
73 const TestResponsePayload* payload_;
74 uint32 offset_;
75 int ready_state_;
76 CPRequest* request_;
77 };
78
79 ResponseStream::ResponseStream(const TestResponsePayload* payload,
80 CPRequest* request)
81 : payload_(payload), offset_(0), ready_state_(READY_INVALID),
82 request_(request) {
83 }
84
85 void ResponseStream::Init() {
86 if (payload_->async) {
87 // simulate an asynchronous start complete
88 ready_state_ = READY_WAITING;
89 g_cptest_funcs.invoke_later(
90 InvokeLaterCallback,
91 // downcast to Task before void, since we upcast from void to Task.
92 static_cast<Task*>(
93 NewRunnableMethod(this, &ResponseStream::ResponseStarted)),
94 500);
95 } else {
96 ready_state_ = READY_GOT_DATA;
97 }
98 }
99
100 int ResponseStream::GetResponseInfo(CPResponseInfoType type, void* buf,
101 uint32 buf_size) {
102 if (ready_state_ < READY_GOT_HEADERS)
103 return CPERR_FAILURE;
104
105 switch (type) {
106 case CPRESPONSEINFO_HTTP_STATUS:
107 if (buf)
108 memcpy(buf, &payload_->status, buf_size);
109 break;
110 case CPRESPONSEINFO_HTTP_RAW_HEADERS: {
111 std::string headers = GetPayloadHeaders(payload_);
112 if (buf_size < headers.size()+1)
113 return static_cast<int>(headers.size()+1);
114 if (buf)
115 memcpy(buf, headers.c_str(), headers.size()+1);
116 break;
117 }
118 default:
119 return CPERR_INVALID_VERSION;
120 }
121
122 return CPERR_SUCCESS;
123 }
124
125 int ResponseStream::ReadData(void* buf, uint32 buf_size) {
126 if (ready_state_ < READY_GOT_DATA) {
127 // simulate an asynchronous read complete
128 g_cptest_funcs.invoke_later(
129 InvokeLaterCallback,
130 // downcast to Task before void, since we upcast from void to Task.
131 static_cast<Task*>(
132 NewRunnableMethod(this, &ResponseStream::ReadCompleted,
133 buf, buf_size)),
134 500);
135 return CPERR_IO_PENDING;
136 }
137
138 // synchronously complete the read
139 return ReadCompleted(buf, buf_size);
140 }
141
142 void ResponseStream::ResponseStarted() {
143 ready_state_ = READY_GOT_HEADERS;
144 g_cpresponse_funcs.start_completed(request_, CPERR_SUCCESS);
145 }
146
147 int ResponseStream::ReadCompleted(void* buf, uint32 buf_size) {
148 uint32 size = static_cast<uint32>(strlen(payload_->body));
149 uint32 avail = size - offset_;
150 uint32 count = buf_size;
151 if (count > avail)
152 count = avail;
153
154 if (count) {
155 memcpy(buf, payload_->body + offset_, count);
156 }
157
158 offset_ += count;
159
160 if (ready_state_ < READY_GOT_DATA) {
161 ready_state_ = READY_GOT_DATA;
162 g_cpresponse_funcs.read_completed(request_, static_cast<int>(count));
163 }
164
165 return count;
166 }
167
168 // CPP Funcs
169
170 CPError STDCALL CPP_Shutdown() {
171 return CPERR_SUCCESS;
172 }
173
174 CPBool STDCALL CPP_ShouldInterceptRequest(CPRequest* request) {
175 DCHECK(base::strncasecmp(request->url, kChromeTestPluginProtocol,
176 arraysize(kChromeTestPluginProtocol) - 1) == 0);
177 return FindPayload(request->url) != NULL;
178 }
179
180 CPError STDCALL CPR_StartRequest(CPRequest* request) {
181 const TestResponsePayload* payload = FindPayload(request->url);
182 DCHECK(payload);
183 ResponseStream* stream = new ResponseStream(payload, request);
184 stream->AddRef(); // Released in CPR_EndRequest
185 stream->Init();
186 request->pdata = stream;
187 return payload->async ? CPERR_IO_PENDING : CPERR_SUCCESS;
188 }
189
190 void STDCALL CPR_EndRequest(CPRequest* request, CPError reason) {
191 ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
192 request->pdata = NULL;
193 stream->Release(); // balances AddRef in CPR_StartRequest
194 }
195
196 void STDCALL CPR_SetExtraRequestHeaders(CPRequest* request,
197 const char* headers) {
198 // doesn't affect us
199 }
200
201 void STDCALL CPR_SetRequestLoadFlags(CPRequest* request, uint32 flags) {
202 // doesn't affect us
203 }
204
205 void STDCALL CPR_AppendDataToUpload(CPRequest* request, const char* bytes,
206 int bytes_len) {
207 // doesn't affect us
208 }
209
210 CPError STDCALL CPR_AppendFileToUpload(CPRequest* request, const char* filepath,
211 uint64 offset, uint64 length) {
212 // doesn't affect us
213 return CPERR_FAILURE;
214 }
215
216 int STDCALL CPR_GetResponseInfo(CPRequest* request, CPResponseInfoType type,
217 void* buf, uint32 buf_size) {
218 ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
219 return stream->GetResponseInfo(type, buf, buf_size);
220 }
221
222 int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) {
223 ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
224 return stream->ReadData(buf, buf_size);
225 }
226
227 // RequestResponse: manages the retrieval of response data from the host
228
229 class RequestResponse {
230 public:
231 explicit RequestResponse(const std::string& raw_headers)
232 : raw_headers_(raw_headers), offset_(0) {}
233 void StartReading(CPRequest* request);
234 void ReadCompleted(CPRequest* request, int bytes_read);
235
236 private:
237 std::string raw_headers_;
238 std::string body_;
239 int offset_;
240 };
241
242 void RequestResponse::StartReading(CPRequest* request) {
243 int rv = 0;
244 const uint32 kReadSize = 4096;
245 do {
246 body_.resize(offset_ + kReadSize);
247 rv = g_cprequest_funcs.read(request, &body_[offset_], kReadSize);
248 if (rv > 0)
249 offset_ += rv;
250 } while (rv > 0);
251
252 if (rv != CPERR_IO_PENDING) {
253 // Either an error occurred, or we are done.
254 ReadCompleted(request, rv);
255 }
256 }
257
258 void RequestResponse::ReadCompleted(CPRequest* request, int bytes_read) {
259 if (bytes_read > 0) {
260 offset_ += bytes_read;
261 StartReading(request);
262 return;
263 }
264
265 body_.resize(offset_);
266 bool success = (bytes_read == 0);
267 g_cptest_funcs.test_complete(request, success, raw_headers_, body_);
268 g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
269 delete this;
270 }
271
272 void STDCALL CPRR_ReceivedRedirect(CPRequest* request, const char* new_url) {
273 }
274
275 void STDCALL CPRR_StartCompleted(CPRequest* request, CPError result) {
276 DCHECK(!request->pdata);
277
278 std::string raw_headers;
279 int size = g_cprequest_funcs.get_response_info(
280 request, CPRESPONSEINFO_HTTP_RAW_HEADERS, NULL, 0);
281 int rv = size < 0 ? size : g_cprequest_funcs.get_response_info(
282 request, CPRESPONSEINFO_HTTP_RAW_HEADERS,
283 WriteInto(&raw_headers, size+1), size);
284 if (rv != CPERR_SUCCESS) {
285 g_cptest_funcs.test_complete(request, false, std::string(), std::string());
286 g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
287 return;
288 }
289
290 RequestResponse* response = new RequestResponse(raw_headers);
291 request->pdata = response;
292 response->StartReading(request);
293 }
294
295 void STDCALL CPRR_ReadCompleted(CPRequest* request, int bytes_read) {
296 RequestResponse* response =
297 reinterpret_cast<RequestResponse*>(request->pdata);
298 response->ReadCompleted(request, bytes_read);
299 }
300
301 int STDCALL CPT_MakeRequest(const char* method, const GURL& url) {
302 CPRequest* request = NULL;
303 if (g_cpbrowser_funcs.create_request(g_cpid, NULL, method, url.spec().c_str(),
304 &request) != CPERR_SUCCESS ||
305 !request) {
306 return CPERR_FAILURE;
307 }
308
309 g_cprequest_funcs.set_request_load_flags(request,
310 CPREQUESTLOAD_DISABLE_INTERCEPT);
311
312 if (strcmp(method, "POST") == 0) {
313 g_cprequest_funcs.set_extra_request_headers(
314 request, "Content-Type: text/plain");
315 g_cprequest_funcs.append_data_to_upload(
316 request, kChromeTestPluginPostData,
317 arraysize(kChromeTestPluginPostData) - 1);
318 }
319
320 int rv = g_cprequest_funcs.start_request(request);
321 if (rv == CPERR_SUCCESS) {
322 CPRR_StartCompleted(request, CPERR_SUCCESS);
323 } else if (rv != CPERR_IO_PENDING) {
324 g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
325 return CPERR_FAILURE;
326 }
327
328 return CPERR_SUCCESS;
329 }
330
331 // DLL entry points
332
333 CPError STDCALL CP_Initialize(CPID id, const CPBrowserFuncs* bfuncs,
334 CPPluginFuncs* pfuncs) {
335 if (bfuncs == NULL || pfuncs == NULL)
336 return CPERR_FAILURE;
337
338 if (CP_GET_MAJOR_VERSION(bfuncs->version) > CP_MAJOR_VERSION)
339 return CPERR_INVALID_VERSION;
340
341 if (bfuncs->size < sizeof(CPBrowserFuncs) ||
342 pfuncs->size < sizeof(CPPluginFuncs))
343 return CPERR_INVALID_VERSION;
344
345 pfuncs->version = CP_VERSION;
346 pfuncs->shutdown = CPP_Shutdown;
347 pfuncs->should_intercept_request = CPP_ShouldInterceptRequest;
348
349 static CPRequestFuncs request_funcs;
350 request_funcs.start_request = CPR_StartRequest;
351 request_funcs.end_request = CPR_EndRequest;
352 request_funcs.set_extra_request_headers = CPR_SetExtraRequestHeaders;
353 request_funcs.set_request_load_flags = CPR_SetRequestLoadFlags;
354 request_funcs.append_data_to_upload = CPR_AppendDataToUpload;
355 request_funcs.get_response_info = CPR_GetResponseInfo;
356 request_funcs.read = CPR_Read;
357 request_funcs.append_file_to_upload = CPR_AppendFileToUpload;
358 pfuncs->request_funcs = &request_funcs;
359
360 static CPResponseFuncs response_funcs;
361 response_funcs.received_redirect = CPRR_ReceivedRedirect;
362 response_funcs.start_completed = CPRR_StartCompleted;
363 response_funcs.read_completed = CPRR_ReadCompleted;
364 pfuncs->response_funcs = &response_funcs;
365
366 g_cpid = id;
367 g_cpbrowser_funcs = *bfuncs;
368 g_cprequest_funcs = *bfuncs->request_funcs;
369 g_cpresponse_funcs = *bfuncs->response_funcs;
370 g_cpbrowser_funcs = *bfuncs;
371
372 const char* protocols[] = {kChromeTestPluginProtocol};
373 g_cpbrowser_funcs.enable_request_intercept(g_cpid, protocols, 1);
374 return CPERR_SUCCESS;
375 }
376
377 int STDCALL CP_Test(void* vparam) {
378 TestFuncParams* param = reinterpret_cast<TestFuncParams*>(vparam);
379 param->pfuncs.test_make_request = CPT_MakeRequest;
380
381 g_cptest_funcs = param->bfuncs;
382 return CPERR_SUCCESS;
383 }
OLDNEW
« no previous file with comments | « chrome/test/chrome_plugin/test_chrome_plugin.h ('k') | chrome/test/chrome_plugin/test_chrome_plugin.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698