Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / test / plugin / plugin_geturl_test.cc
blob20838e533b31044b70fc919ce7fdf9b35885e79a
1 // Copyright (c) 2011 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.
5 #include "content/test/plugin/plugin_geturl_test.h"
7 #include <stdio.h>
9 #include "base/basictypes.h"
10 #include "base/file_util.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
15 // url for "self". The %22%22 is to make a statement for javascript to
16 // evaluate and return.
17 #define SELF_URL "javascript:window.location+\"\""
19 // The identifier for the self url stream.
20 #define SELF_URL_STREAM_ID 1
22 // The identifier for the fetched url stream.
23 #define FETCHED_URL_STREAM_ID 2
25 // url for testing GetURL with a bogus URL.
26 #define BOGUS_URL "bogoproto:///x:/asdf.xysdhffieasdf.asdhj/"
28 // url for testing redirect notifications sent to plugins.
29 #define REDIRECT_SRC_URL \
30 "http://mock.http/npapi/plugin_read_page_redirect_src.html"
32 // The notification id for the redirect notification url that we will cancel.
33 #define REDIRECT_SRC_URL_NOTIFICATION_CANCEL_ID 4
35 // The notification id for the redirect notification url that we will accept.
36 #define REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID 5
38 // The identifier for the bogus url stream.
39 #define BOGUS_URL_STREAM_ID 3
41 // The maximum chunk size of stream data.
42 #define STREAM_CHUNK 197
44 namespace NPAPIClient {
46 PluginGetURLTest::PluginGetURLTest(NPP id, NPNetscapeFuncs *host_functions)
47 : PluginTest(id, host_functions),
48 tests_started_(false),
49 tests_in_progress_(0),
50 test_file_(NULL),
51 expect_404_response_(false),
52 npn_evaluate_context_(false),
53 handle_url_redirects_(false),
54 received_url_redirect_cancel_notification_(false),
55 received_url_redirect_allow_notification_(false),
56 check_cookies_(false) {
59 PluginGetURLTest::~PluginGetURLTest() {}
61 NPError PluginGetURLTest::New(uint16 mode, int16 argc, const char* argn[],
62 const char* argv[], NPSavedData* saved) {
63 const char* page_not_found_url = GetArgValue("page_not_found_url", argc,
64 argn, argv);
65 if (page_not_found_url) {
66 page_not_found_url_ = page_not_found_url;
67 expect_404_response_ = true;
70 const char* fail_write_url = GetArgValue("fail_write_url", argc,
71 argn, argv);
72 if (fail_write_url) {
73 fail_write_url_ = fail_write_url;
76 const char* referrer_target_url = GetArgValue("ref_target", argc,
77 argn, argv);
78 if (referrer_target_url) {
79 referrer_target_url_ = referrer_target_url;
82 if (!base::strcasecmp(GetArgValue("name", argc, argn, argv),
83 "geturlredirectnotify")) {
84 handle_url_redirects_ = true;
87 NPError error = PluginTest::New(mode, argc, argn, argv, saved);
89 // The above sets test_name().
90 if (test_name() == "cookies")
91 check_cookies_ = true;
93 return error;
96 NPError PluginGetURLTest::SetWindow(NPWindow* pNPWindow) {
97 #if !defined(OS_MACOSX)
98 if (pNPWindow->window == NULL)
99 return NPERR_NO_ERROR;
100 #endif
102 if (!tests_started_) {
103 tests_started_ = true;
105 tests_in_progress_++;
107 if (expect_404_response_) {
108 HostFunctions()->geturl(id(), page_not_found_url_.c_str(), NULL);
109 return NPERR_NO_ERROR;
110 } else if (!fail_write_url_.empty()) {
111 HostFunctions()->geturl(id(), fail_write_url_.c_str(), NULL);
112 return NPERR_NO_ERROR;
113 } else if (!referrer_target_url_.empty()) {
114 HostFunctions()->pushpopupsenabledstate(id(), true);
115 HostFunctions()->geturl(id(), referrer_target_url_.c_str(), "_blank");
116 HostFunctions()->poppopupsenabledstate(id());
117 return NPERR_NO_ERROR;
118 } else if (handle_url_redirects_) {
119 HostFunctions()->geturlnotify(
120 id(), REDIRECT_SRC_URL, NULL,
121 reinterpret_cast<void*>(REDIRECT_SRC_URL_NOTIFICATION_CANCEL_ID));
122 return NPERR_NO_ERROR;
123 } else if (check_cookies_) {
124 HostFunctions()->geturlnotify(
125 id(),
126 "plugin_ref_target_page.html",
127 NULL,
128 reinterpret_cast<void*>(SELF_URL_STREAM_ID));
129 return NPERR_NO_ERROR;
132 std::string url = SELF_URL;
133 HostFunctions()->geturlnotify(id(), url.c_str(), NULL,
134 reinterpret_cast<void*>(SELF_URL_STREAM_ID));
136 tests_in_progress_++;
137 std::string bogus_url = BOGUS_URL;
138 HostFunctions()->geturlnotify(id(), bogus_url.c_str(), NULL,
139 reinterpret_cast<void*>(BOGUS_URL_STREAM_ID));
141 return NPERR_NO_ERROR;
144 NPError PluginGetURLTest::NewStream(NPMIMEType type, NPStream* stream,
145 NPBool seekable, uint16* stype) {
146 if (stream == NULL) {
147 SetError("NewStream got null stream");
148 return NPERR_INVALID_PARAM;
151 if (test_completed()) {
152 return PluginTest::NewStream(type, stream, seekable, stype);
155 if (!referrer_target_url_.empty()) {
156 return NPERR_NO_ERROR;
159 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
160 cast_validity_check);
162 if (expect_404_response_) {
163 NPObject *window_obj = NULL;
164 HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj);
165 if (!window_obj) {
166 SetError("Failed to get NPObject for plugin instance2");
167 SignalTestCompleted();
168 return NPERR_NO_ERROR;
171 std::string script = "javascript:document.title=\"OK\"";
172 NPString script_string;
173 script_string.UTF8Characters = script.c_str();
174 script_string.UTF8Length = static_cast<unsigned int>(script.length());
175 NPVariant result_var;
177 npn_evaluate_context_ = true;
178 HostFunctions()->evaluate(id(), window_obj, &script_string, &result_var);
179 npn_evaluate_context_ = false;
180 return NPERR_NO_ERROR;
183 if (!fail_write_url_.empty() || check_cookies_) {
184 return NPERR_NO_ERROR;
188 unsigned long stream_id = reinterpret_cast<unsigned long>(
189 stream->notifyData);
191 switch (stream_id) {
192 case SELF_URL_STREAM_ID:
193 break;
194 case FETCHED_URL_STREAM_ID:
196 std::string filename = self_url_;
197 if (filename.find("file:///", 0) != 0) {
198 SetError("Test expects a file-url.");
199 break;
202 // TODO(evanm): use the net:: functions to convert file:// URLs to
203 // on-disk file paths. But it probably doesn't actually matter in
204 // this test.
206 #if defined(OS_WIN)
207 filename = filename.substr(8); // remove "file:///"
208 // Assume an ASCII path on Windows.
209 base::FilePath path = base::FilePath(base::ASCIIToWide(filename));
210 #else
211 filename = filename.substr(7); // remove "file://"
212 base::FilePath path = base::FilePath(filename);
213 #endif
215 test_file_ = base::OpenFile(path, "r");
216 if (!test_file_) {
217 SetError("Could not open source file");
220 break;
221 case BOGUS_URL_STREAM_ID:
222 SetError("Unexpected NewStream for BOGUS_URL");
223 break;
224 case REDIRECT_SRC_URL_NOTIFICATION_CANCEL_ID:
225 SetError("Should not redirect to URL when plugin denied it.");
226 break;
227 case REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID:
228 break;
229 default:
230 SetError("Unexpected NewStream callback");
231 break;
233 return NPERR_NO_ERROR;
236 int32 PluginGetURLTest::WriteReady(NPStream *stream) {
237 if (test_completed()) {
238 return PluginTest::WriteReady(stream);
241 if (!referrer_target_url_.empty() || check_cookies_) {
242 return STREAM_CHUNK;
245 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
246 cast_validity_check);
247 unsigned long stream_id = reinterpret_cast<unsigned long>(
248 stream->notifyData);
249 if (stream_id == BOGUS_URL_STREAM_ID)
250 SetError("Received WriteReady for BOGUS_URL");
252 return STREAM_CHUNK;
255 int32 PluginGetURLTest::Write(NPStream *stream, int32 offset, int32 len,
256 void *buffer) {
257 if (test_completed()) {
258 return PluginTest::Write(stream, offset, len, buffer);
261 if (!fail_write_url_.empty()) {
262 SignalTestCompleted();
263 return -1;
266 if (!referrer_target_url_.empty() || check_cookies_) {
267 return len;
270 if (stream == NULL) {
271 SetError("Write got null stream");
272 return -1;
274 if (len < 0 || len > STREAM_CHUNK) {
275 SetError("Write got bogus stream chunk size");
276 return -1;
279 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
280 cast_validity_check);
281 unsigned long stream_id = reinterpret_cast<unsigned long>(
282 stream->notifyData);
283 switch (stream_id) {
284 case SELF_URL_STREAM_ID:
285 self_url_.append(static_cast<char*>(buffer), len);
286 break;
287 case FETCHED_URL_STREAM_ID:
289 char read_buffer[STREAM_CHUNK];
290 int32 bytes =
291 static_cast<int32>(fread(read_buffer, 1, len, test_file_));
292 // Technically, fread could return fewer than len
293 // bytes. But this is not likely.
294 if (bytes != len)
295 SetError("Did not read correct bytelength from source file");
296 if (memcmp(read_buffer, buffer, len))
297 SetError("Content mismatch between data and source!");
299 break;
300 case BOGUS_URL_STREAM_ID:
301 SetError("Unexpected write callback for BOGUS_URL");
302 break;
303 case REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID:
304 break;
305 default:
306 SetError("Unexpected write callback");
307 break;
309 // Pretend that we took all the data.
310 return len;
314 NPError PluginGetURLTest::DestroyStream(NPStream *stream, NPError reason) {
315 if (test_completed()) {
316 return PluginTest::DestroyStream(stream, reason);
319 if (stream == NULL) {
320 SetError("NewStream got null stream");
321 return NPERR_INVALID_PARAM;
324 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
325 cast_validity_check);
327 if (expect_404_response_) {
328 if (npn_evaluate_context_) {
329 SetError("Received destroyStream in the context of NPN_Evaluate.");
332 SignalTestCompleted();
333 return NPERR_NO_ERROR;
336 if (!referrer_target_url_.empty()) {
337 return NPERR_NO_ERROR;
340 if (check_cookies_) {
341 SignalTestCompleted();
342 return NPERR_NO_ERROR;
345 unsigned long stream_id =
346 reinterpret_cast<unsigned long>(stream->notifyData);
347 switch (stream_id) {
348 case SELF_URL_STREAM_ID:
349 // don't care
350 break;
351 case REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID:
352 break;
353 case FETCHED_URL_STREAM_ID:
355 char read_buffer[STREAM_CHUNK];
356 size_t bytes = fread(read_buffer, 1, sizeof(read_buffer), test_file_);
357 if (bytes != 0)
358 SetError("Data and source mismatch on length");
359 base::CloseFile(test_file_);
361 break;
362 default:
363 SetError("Unexpected NewStream callback");
364 break;
366 return NPERR_NO_ERROR;
369 void PluginGetURLTest::StreamAsFile(NPStream* stream, const char* fname) {
370 if (stream == NULL) {
371 SetError("NewStream got null stream");
372 return;
375 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
376 cast_validity_check);
377 unsigned long stream_id =
378 reinterpret_cast<unsigned long>(stream->notifyData);
379 switch (stream_id) {
380 case SELF_URL_STREAM_ID:
381 // don't care
382 break;
383 default:
384 SetError("Unexpected NewStream callback");
385 break;
389 void PluginGetURLTest::URLNotify(const char* url, NPReason reason, void* data) {
390 if (!tests_in_progress_) {
391 SetError("URLNotify received after tests completed");
392 return;
395 if (!url) {
396 SetError("URLNotify received NULL url");
397 return;
400 if (check_cookies_)
401 return;
403 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(data), cast_validity_check);
404 unsigned long stream_id = reinterpret_cast<unsigned long>(data);
405 switch (stream_id) {
406 case SELF_URL_STREAM_ID:
407 if (strcmp(url, SELF_URL) != 0)
408 SetError("URLNotify reported incorrect url for SELF_URL");
410 // We have our stream url. Go fetch it.
411 HostFunctions()->geturlnotify(id(), self_url_.c_str(), NULL,
412 reinterpret_cast<void*>(FETCHED_URL_STREAM_ID));
413 break;
414 case FETCHED_URL_STREAM_ID:
415 if (!url || strcmp(url, self_url_.c_str()) != 0)
416 SetError("URLNotify reported incorrect url for FETCHED_URL");
417 tests_in_progress_--;
418 break;
419 case BOGUS_URL_STREAM_ID:
420 if (reason != NPRES_NETWORK_ERR) {
421 std::string err = "BOGUS_URL received unexpected URLNotify status: ";
422 err.append(base::IntToString(reason));
423 SetError(err);
425 tests_in_progress_--;
426 break;
427 case REDIRECT_SRC_URL_NOTIFICATION_CANCEL_ID: {
428 if (!received_url_redirect_cancel_notification_) {
429 SetError("Failed to receive URLRedirect notification for cancel");
431 if (reason != NPRES_NETWORK_ERR) {
432 SetError("Redirected URL didn't get canceled");
434 break;
436 case REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID: {
437 if (!received_url_redirect_allow_notification_) {
438 SetError("Failed to receive URLRedirect notification for allow");
440 if (reason != NPRES_DONE) {
441 SetError("Redirected URL didn't complete successfully");
443 tests_in_progress_--;
444 break;
446 default:
447 SetError("Unexpected NewStream callback");
448 break;
451 if (tests_in_progress_ == 0)
452 SignalTestCompleted();
455 void PluginGetURLTest::URLRedirectNotify(const char* url,
456 int32_t status,
457 void* notify_data) {
458 unsigned long stream_id = reinterpret_cast<unsigned long>(notify_data);
459 if (stream_id == REDIRECT_SRC_URL_NOTIFICATION_CANCEL_ID) {
460 if (!base::strcasecmp(url,
461 "http://mock.http/npapi/plugin_read_page.html")) {
462 received_url_redirect_cancel_notification_ = true;
463 // Disallow redirect notification.
464 HostFunctions()->urlredirectresponse(id(), notify_data, false);
466 // Now start a request that we will allow to redirect.
467 HostFunctions()->geturlnotify(
468 id(), REDIRECT_SRC_URL, NULL,
469 reinterpret_cast<void*>(REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID));
471 } else if (stream_id == REDIRECT_SRC_URL_NOTIFICATION_ALLOW_ID) {
472 received_url_redirect_allow_notification_ = true;
473 HostFunctions()->urlredirectresponse(id(), notify_data, true);
477 } // namespace NPAPIClient