OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 "webkit/glue/plugins/test/plugin_geturl_test.h" | |
6 | |
7 #include <stdio.h> | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/file_util.h" | |
11 #include "base/string_number_conversions.h" | |
12 #include "base/utf_string_conversions.h" | |
13 | |
14 // url for "self". The %22%22 is to make a statement for javascript to | |
15 // evaluate and return. | |
16 #define SELF_URL "javascript:window.location+\"\"" | |
17 | |
18 // The identifier for the self url stream. | |
19 #define SELF_URL_STREAM_ID 1 | |
20 | |
21 // The identifier for the fetched url stream. | |
22 #define FETCHED_URL_STREAM_ID 2 | |
23 | |
24 // url for testing GetURL with a bogus URL. | |
25 #define BOGUS_URL "bogoproto:///x:/asdf.xysdhffieasdf.asdhj/" | |
26 | |
27 // url for testing redirect notifications sent to plugins. | |
28 #define REDIRECT_SRC_URL \ | |
29 "http://mock.http/npapi/plugin_read_page_redirect_src.html" | |
30 | |
31 // The notification id for the redirect notification url. | |
32 #define REDIRECT_SRC_URL_NOTIFICATION_ID 4 | |
33 | |
34 // The identifier for the bogus url stream. | |
35 #define BOGUS_URL_STREAM_ID 3 | |
36 | |
37 // The maximum chunk size of stream data. | |
38 #define STREAM_CHUNK 197 | |
39 | |
40 namespace NPAPIClient { | |
41 | |
42 PluginGetURLTest::PluginGetURLTest(NPP id, NPNetscapeFuncs *host_functions) | |
43 : PluginTest(id, host_functions), | |
44 tests_started_(false), | |
45 tests_in_progress_(0), | |
46 test_file_(NULL), | |
47 expect_404_response_(false), | |
48 npn_evaluate_context_(false), | |
49 handle_url_redirects_(false), | |
50 received_url_redirect_notification_(false) { | |
51 } | |
52 | |
53 NPError PluginGetURLTest::New(uint16 mode, int16 argc, const char* argn[], | |
54 const char* argv[], NPSavedData* saved) { | |
55 const char* page_not_found_url = GetArgValue("page_not_found_url", argc, | |
56 argn, argv); | |
57 if (page_not_found_url) { | |
58 page_not_found_url_ = page_not_found_url; | |
59 expect_404_response_ = true; | |
60 } | |
61 | |
62 const char* fail_write_url = GetArgValue("fail_write_url", argc, | |
63 argn, argv); | |
64 if (fail_write_url) { | |
65 fail_write_url_ = fail_write_url; | |
66 } | |
67 | |
68 const char* referrer_target_url = GetArgValue("ref_target", argc, | |
69 argn, argv); | |
70 if (referrer_target_url) { | |
71 referrer_target_url_ = referrer_target_url; | |
72 } | |
73 | |
74 if (!base::strcasecmp(GetArgValue("name", argc, argn, argv), | |
75 "geturlredirectnotify")) { | |
76 handle_url_redirects_ = true; | |
77 } | |
78 return PluginTest::New(mode, argc, argn, argv, saved); | |
79 } | |
80 | |
81 NPError PluginGetURLTest::SetWindow(NPWindow* pNPWindow) { | |
82 if (pNPWindow->window == NULL) | |
83 return NPERR_NO_ERROR; | |
84 | |
85 if (!tests_started_) { | |
86 tests_started_ = true; | |
87 | |
88 tests_in_progress_++; | |
89 | |
90 if (expect_404_response_) { | |
91 HostFunctions()->geturl(id(), page_not_found_url_.c_str(), NULL); | |
92 return NPERR_NO_ERROR; | |
93 } else if (!fail_write_url_.empty()) { | |
94 HostFunctions()->geturl(id(), fail_write_url_.c_str(), NULL); | |
95 return NPERR_NO_ERROR; | |
96 } else if (!referrer_target_url_.empty()) { | |
97 HostFunctions()->pushpopupsenabledstate(id(), true); | |
98 HostFunctions()->geturl(id(), referrer_target_url_.c_str(), "_blank"); | |
99 HostFunctions()->poppopupsenabledstate(id()); | |
100 return NPERR_NO_ERROR; | |
101 } else if (handle_url_redirects_) { | |
102 HostFunctions()->geturlnotify( | |
103 id(), REDIRECT_SRC_URL, NULL, | |
104 reinterpret_cast<void*>(REDIRECT_SRC_URL_NOTIFICATION_ID)); | |
105 return NPERR_NO_ERROR; | |
106 } | |
107 | |
108 std::string url = SELF_URL; | |
109 HostFunctions()->geturlnotify(id(), url.c_str(), NULL, | |
110 reinterpret_cast<void*>(SELF_URL_STREAM_ID)); | |
111 | |
112 tests_in_progress_++; | |
113 std::string bogus_url = BOGUS_URL; | |
114 HostFunctions()->geturlnotify(id(), bogus_url.c_str(), NULL, | |
115 reinterpret_cast<void*>(BOGUS_URL_STREAM_ID)); | |
116 } | |
117 return NPERR_NO_ERROR; | |
118 } | |
119 | |
120 NPError PluginGetURLTest::NewStream(NPMIMEType type, NPStream* stream, | |
121 NPBool seekable, uint16* stype) { | |
122 if (stream == NULL) { | |
123 SetError("NewStream got null stream"); | |
124 return NPERR_INVALID_PARAM; | |
125 } | |
126 | |
127 if (test_completed()) { | |
128 return PluginTest::NewStream(type, stream, seekable, stype); | |
129 } | |
130 | |
131 if (!referrer_target_url_.empty()) { | |
132 return NPERR_NO_ERROR; | |
133 } | |
134 | |
135 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData), | |
136 cast_validity_check); | |
137 | |
138 if (expect_404_response_) { | |
139 NPObject *window_obj = NULL; | |
140 HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj); | |
141 if (!window_obj) { | |
142 SetError("Failed to get NPObject for plugin instance2"); | |
143 SignalTestCompleted(); | |
144 return NPERR_NO_ERROR; | |
145 } | |
146 | |
147 std::string script = "javascript:alert('Hi there from plugin');"; | |
148 NPString script_string; | |
149 script_string.UTF8Characters = script.c_str(); | |
150 script_string.UTF8Length = static_cast<unsigned int>(script.length()); | |
151 NPVariant result_var; | |
152 | |
153 npn_evaluate_context_ = true; | |
154 HostFunctions()->evaluate(id(), window_obj, &script_string, &result_var); | |
155 npn_evaluate_context_ = false; | |
156 return NPERR_NO_ERROR; | |
157 } | |
158 | |
159 if (!fail_write_url_.empty()) { | |
160 return NPERR_NO_ERROR; | |
161 } | |
162 | |
163 | |
164 unsigned long stream_id = reinterpret_cast<unsigned long>( | |
165 stream->notifyData); | |
166 | |
167 switch (stream_id) { | |
168 case SELF_URL_STREAM_ID: | |
169 break; | |
170 case FETCHED_URL_STREAM_ID: | |
171 { | |
172 std::string filename = self_url_; | |
173 if (filename.find("file:///", 0) != 0) { | |
174 SetError("Test expects a file-url."); | |
175 break; | |
176 } | |
177 | |
178 // TODO(evanm): use the net:: functions to convert file:// URLs to | |
179 // on-disk file paths. But it probably doesn't actually matter in | |
180 // this test. | |
181 | |
182 #if defined(OS_WIN) | |
183 filename = filename.substr(8); // remove "file:///" | |
184 // Assume an ASCII path on Windows. | |
185 FilePath path = FilePath(ASCIIToWide(filename)); | |
186 #else | |
187 filename = filename.substr(7); // remove "file://" | |
188 FilePath path = FilePath(filename); | |
189 #endif | |
190 | |
191 test_file_ = file_util::OpenFile(path, "r"); | |
192 if (!test_file_) { | |
193 SetError("Could not open source file"); | |
194 } | |
195 } | |
196 break; | |
197 case BOGUS_URL_STREAM_ID: | |
198 SetError("Unexpected NewStream for BOGUS_URL"); | |
199 break; | |
200 case REDIRECT_SRC_URL_NOTIFICATION_ID: | |
201 SetError("Should not redirect to URL when plugin denied it."); | |
202 break; | |
203 default: | |
204 SetError("Unexpected NewStream callback"); | |
205 break; | |
206 } | |
207 return NPERR_NO_ERROR; | |
208 } | |
209 | |
210 int32 PluginGetURLTest::WriteReady(NPStream *stream) { | |
211 if (test_completed()) { | |
212 return PluginTest::WriteReady(stream); | |
213 } | |
214 | |
215 if (!referrer_target_url_.empty()) { | |
216 return STREAM_CHUNK; | |
217 } | |
218 | |
219 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData), | |
220 cast_validity_check); | |
221 unsigned long stream_id = reinterpret_cast<unsigned long>( | |
222 stream->notifyData); | |
223 if (stream_id == BOGUS_URL_STREAM_ID) | |
224 SetError("Received WriteReady for BOGUS_URL"); | |
225 | |
226 return STREAM_CHUNK; | |
227 } | |
228 | |
229 int32 PluginGetURLTest::Write(NPStream *stream, int32 offset, int32 len, | |
230 void *buffer) { | |
231 if (test_completed()) { | |
232 return PluginTest::Write(stream, offset, len, buffer); | |
233 } | |
234 | |
235 if (!fail_write_url_.empty()) { | |
236 SignalTestCompleted(); | |
237 return -1; | |
238 } | |
239 | |
240 if (!referrer_target_url_.empty()) { | |
241 return len; | |
242 } | |
243 | |
244 if (stream == NULL) { | |
245 SetError("Write got null stream"); | |
246 return -1; | |
247 } | |
248 if (len < 0 || len > STREAM_CHUNK) { | |
249 SetError("Write got bogus stream chunk size"); | |
250 return -1; | |
251 } | |
252 | |
253 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData), | |
254 cast_validity_check); | |
255 unsigned long stream_id = reinterpret_cast<unsigned long>( | |
256 stream->notifyData); | |
257 switch (stream_id) { | |
258 case SELF_URL_STREAM_ID: | |
259 self_url_.append(static_cast<char*>(buffer), len); | |
260 break; | |
261 case FETCHED_URL_STREAM_ID: | |
262 { | |
263 char read_buffer[STREAM_CHUNK]; | |
264 int32 bytes = fread(read_buffer, 1, len, test_file_); | |
265 // Technically, fread could return fewer than len | |
266 // bytes. But this is not likely. | |
267 if (bytes != len) | |
268 SetError("Did not read correct bytelength from source file"); | |
269 if (memcmp(read_buffer, buffer, len)) | |
270 SetError("Content mismatch between data and source!"); | |
271 } | |
272 break; | |
273 case BOGUS_URL_STREAM_ID: | |
274 SetError("Unexpected write callback for BOGUS_URL"); | |
275 break; | |
276 default: | |
277 SetError("Unexpected write callback"); | |
278 break; | |
279 } | |
280 // Pretend that we took all the data. | |
281 return len; | |
282 } | |
283 | |
284 | |
285 NPError PluginGetURLTest::DestroyStream(NPStream *stream, NPError reason) { | |
286 if (test_completed()) { | |
287 return PluginTest::DestroyStream(stream, reason); | |
288 } | |
289 | |
290 if (stream == NULL) { | |
291 SetError("NewStream got null stream"); | |
292 return NPERR_INVALID_PARAM; | |
293 } | |
294 | |
295 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData), | |
296 cast_validity_check); | |
297 | |
298 if (expect_404_response_) { | |
299 if (npn_evaluate_context_) { | |
300 SetError("Received destroyStream in the context of NPN_Evaluate."); | |
301 } | |
302 | |
303 SignalTestCompleted(); | |
304 return NPERR_NO_ERROR; | |
305 } | |
306 | |
307 if (!referrer_target_url_.empty()) { | |
308 return NPERR_NO_ERROR; | |
309 } | |
310 | |
311 unsigned long stream_id = | |
312 reinterpret_cast<unsigned long>(stream->notifyData); | |
313 switch (stream_id) { | |
314 case SELF_URL_STREAM_ID: | |
315 // don't care | |
316 break; | |
317 case FETCHED_URL_STREAM_ID: | |
318 { | |
319 char read_buffer[STREAM_CHUNK]; | |
320 size_t bytes = fread(read_buffer, 1, sizeof(read_buffer), test_file_); | |
321 if (bytes != 0) | |
322 SetError("Data and source mismatch on length"); | |
323 file_util::CloseFile(test_file_); | |
324 } | |
325 break; | |
326 default: | |
327 SetError("Unexpected NewStream callback"); | |
328 break; | |
329 } | |
330 return NPERR_NO_ERROR; | |
331 } | |
332 | |
333 void PluginGetURLTest::StreamAsFile(NPStream* stream, const char* fname) { | |
334 if (stream == NULL) { | |
335 SetError("NewStream got null stream"); | |
336 return; | |
337 } | |
338 | |
339 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData), | |
340 cast_validity_check); | |
341 unsigned long stream_id = | |
342 reinterpret_cast<unsigned long>(stream->notifyData); | |
343 switch (stream_id) { | |
344 case SELF_URL_STREAM_ID: | |
345 // don't care | |
346 break; | |
347 default: | |
348 SetError("Unexpected NewStream callback"); | |
349 break; | |
350 } | |
351 } | |
352 | |
353 void PluginGetURLTest::URLNotify(const char* url, NPReason reason, void* data) { | |
354 if (!tests_in_progress_) { | |
355 SetError("URLNotify received after tests completed"); | |
356 return; | |
357 } | |
358 | |
359 if (!url) { | |
360 SetError("URLNotify received NULL url"); | |
361 return; | |
362 } | |
363 | |
364 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(data), cast_validity_check); | |
365 unsigned long stream_id = reinterpret_cast<unsigned long>(data); | |
366 switch (stream_id) { | |
367 case SELF_URL_STREAM_ID: | |
368 if (strcmp(url, SELF_URL) != 0) | |
369 SetError("URLNotify reported incorrect url for SELF_URL"); | |
370 | |
371 // We have our stream url. Go fetch it. | |
372 HostFunctions()->geturlnotify(id(), self_url_.c_str(), NULL, | |
373 reinterpret_cast<void*>(FETCHED_URL_STREAM_ID)); | |
374 break; | |
375 case FETCHED_URL_STREAM_ID: | |
376 if (!url || strcmp(url, self_url_.c_str()) != 0) | |
377 SetError("URLNotify reported incorrect url for FETCHED_URL"); | |
378 tests_in_progress_--; | |
379 break; | |
380 case BOGUS_URL_STREAM_ID: | |
381 if (reason != NPRES_NETWORK_ERR) { | |
382 std::string err = "BOGUS_URL received unexpected URLNotify status: "; | |
383 err.append(base::IntToString(reason)); | |
384 SetError(err); | |
385 } | |
386 tests_in_progress_--; | |
387 break; | |
388 case REDIRECT_SRC_URL_NOTIFICATION_ID: { | |
389 if (!received_url_redirect_notification_) { | |
390 SetError("Failed to receive URLRedirect notification"); | |
391 } | |
392 tests_in_progress_--; | |
393 break; | |
394 } | |
395 default: | |
396 SetError("Unexpected NewStream callback"); | |
397 break; | |
398 } | |
399 | |
400 if (tests_in_progress_ == 0) | |
401 SignalTestCompleted(); | |
402 } | |
403 | |
404 void PluginGetURLTest::URLRedirectNotify(const char* url, | |
405 int32_t status, | |
406 void* notify_data) { | |
407 if (!base::strcasecmp(url, "http://mock.http/npapi/plugin_read_page.html")) { | |
408 received_url_redirect_notification_ = true; | |
409 // Disallow redirect notification. | |
410 HostFunctions()->urlredirectresponse(id(), notify_data, false); | |
411 } | |
412 } | |
413 | |
414 } // namespace NPAPIClient | |
OLD | NEW |