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"
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.
33 #define REDIRECT_SRC_URL_NOTIFICATION_ID 4
35 // The identifier for the bogus url stream.
36 #define BOGUS_URL_STREAM_ID 3
38 // The maximum chunk size of stream data.
39 #define STREAM_CHUNK 197
41 namespace NPAPIClient {
43 PluginGetURLTest::PluginGetURLTest(NPP id, NPNetscapeFuncs *host_functions)
44 : PluginTest(id, host_functions),
45 tests_started_(false),
46 tests_in_progress_(0),
48 expect_404_response_(false),
49 npn_evaluate_context_(false),
50 handle_url_redirects_(false),
51 received_url_redirect_notification_(false),
52 check_cookies_(false) {
55 PluginGetURLTest::~PluginGetURLTest() {}
57 NPError PluginGetURLTest::New(uint16 mode, int16 argc, const char* argn[],
58 const char* argv[], NPSavedData* saved) {
59 const char* page_not_found_url = GetArgValue("page_not_found_url", argc,
61 if (page_not_found_url) {
62 page_not_found_url_ = page_not_found_url;
63 expect_404_response_ = true;
66 const char* fail_write_url = GetArgValue("fail_write_url", argc,
69 fail_write_url_ = fail_write_url;
72 const char* referrer_target_url = GetArgValue("ref_target", argc,
74 if (referrer_target_url) {
75 referrer_target_url_ = referrer_target_url;
78 if (!base::strcasecmp(GetArgValue("name", argc, argn, argv),
79 "geturlredirectnotify")) {
80 handle_url_redirects_ = true;
83 NPError error = PluginTest::New(mode, argc, argn, argv, saved);
85 // The above sets test_name().
86 if (test_name() == "cookies")
87 check_cookies_ = true;
92 NPError PluginGetURLTest::SetWindow(NPWindow* pNPWindow) {
93 #if !defined(OS_MACOSX)
94 if (pNPWindow->window == NULL)
95 return NPERR_NO_ERROR;
98 if (!tests_started_) {
99 tests_started_ = true;
101 tests_in_progress_++;
103 if (expect_404_response_) {
104 HostFunctions()->geturl(id(), page_not_found_url_.c_str(), NULL);
105 return NPERR_NO_ERROR;
106 } else if (!fail_write_url_.empty()) {
107 HostFunctions()->geturl(id(), fail_write_url_.c_str(), NULL);
108 return NPERR_NO_ERROR;
109 } else if (!referrer_target_url_.empty()) {
110 HostFunctions()->pushpopupsenabledstate(id(), true);
111 HostFunctions()->geturl(id(), referrer_target_url_.c_str(), "_blank");
112 HostFunctions()->poppopupsenabledstate(id());
113 return NPERR_NO_ERROR;
114 } else if (handle_url_redirects_) {
115 HostFunctions()->geturlnotify(
116 id(), REDIRECT_SRC_URL, NULL,
117 reinterpret_cast<void*>(REDIRECT_SRC_URL_NOTIFICATION_ID));
118 return NPERR_NO_ERROR;
119 } else if (check_cookies_) {
120 HostFunctions()->geturlnotify(
122 "plugin_ref_target_page.html",
124 reinterpret_cast<void*>(SELF_URL_STREAM_ID));
125 return NPERR_NO_ERROR;
128 std::string url = SELF_URL;
129 HostFunctions()->geturlnotify(id(), url.c_str(), NULL,
130 reinterpret_cast<void*>(SELF_URL_STREAM_ID));
132 tests_in_progress_++;
133 std::string bogus_url = BOGUS_URL;
134 HostFunctions()->geturlnotify(id(), bogus_url.c_str(), NULL,
135 reinterpret_cast<void*>(BOGUS_URL_STREAM_ID));
137 return NPERR_NO_ERROR;
140 NPError PluginGetURLTest::NewStream(NPMIMEType type, NPStream* stream,
141 NPBool seekable, uint16* stype) {
142 if (stream == NULL) {
143 SetError("NewStream got null stream");
144 return NPERR_INVALID_PARAM;
147 if (test_completed()) {
148 return PluginTest::NewStream(type, stream, seekable, stype);
151 if (!referrer_target_url_.empty()) {
152 return NPERR_NO_ERROR;
155 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
156 cast_validity_check);
158 if (expect_404_response_) {
159 NPObject *window_obj = NULL;
160 HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj);
162 SetError("Failed to get NPObject for plugin instance2");
163 SignalTestCompleted();
164 return NPERR_NO_ERROR;
167 std::string script = "javascript:document.title=\"OK\"";
168 NPString script_string;
169 script_string.UTF8Characters = script.c_str();
170 script_string.UTF8Length = static_cast<unsigned int>(script.length());
171 NPVariant result_var;
173 npn_evaluate_context_ = true;
174 HostFunctions()->evaluate(id(), window_obj, &script_string, &result_var);
175 npn_evaluate_context_ = false;
176 return NPERR_NO_ERROR;
179 if (!fail_write_url_.empty() || check_cookies_) {
180 return NPERR_NO_ERROR;
184 unsigned long stream_id = reinterpret_cast<unsigned long>(
188 case SELF_URL_STREAM_ID:
190 case FETCHED_URL_STREAM_ID:
192 std::string filename = self_url_;
193 if (filename.find("file:///", 0) != 0) {
194 SetError("Test expects a file-url.");
198 // TODO(evanm): use the net:: functions to convert file:// URLs to
199 // on-disk file paths. But it probably doesn't actually matter in
203 filename = filename.substr(8); // remove "file:///"
204 // Assume an ASCII path on Windows.
205 base::FilePath path = base::FilePath(ASCIIToWide(filename));
207 filename = filename.substr(7); // remove "file://"
208 base::FilePath path = base::FilePath(filename);
211 test_file_ = file_util::OpenFile(path, "r");
213 SetError("Could not open source file");
217 case BOGUS_URL_STREAM_ID:
218 SetError("Unexpected NewStream for BOGUS_URL");
220 case REDIRECT_SRC_URL_NOTIFICATION_ID:
221 SetError("Should not redirect to URL when plugin denied it.");
224 SetError("Unexpected NewStream callback");
227 return NPERR_NO_ERROR;
230 int32 PluginGetURLTest::WriteReady(NPStream *stream) {
231 if (test_completed()) {
232 return PluginTest::WriteReady(stream);
235 if (!referrer_target_url_.empty() || check_cookies_) {
239 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
240 cast_validity_check);
241 unsigned long stream_id = reinterpret_cast<unsigned long>(
243 if (stream_id == BOGUS_URL_STREAM_ID)
244 SetError("Received WriteReady for BOGUS_URL");
249 int32 PluginGetURLTest::Write(NPStream *stream, int32 offset, int32 len,
251 if (test_completed()) {
252 return PluginTest::Write(stream, offset, len, buffer);
255 if (!fail_write_url_.empty()) {
256 SignalTestCompleted();
260 if (!referrer_target_url_.empty() || check_cookies_) {
264 if (stream == NULL) {
265 SetError("Write got null stream");
268 if (len < 0 || len > STREAM_CHUNK) {
269 SetError("Write got bogus stream chunk size");
273 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
274 cast_validity_check);
275 unsigned long stream_id = reinterpret_cast<unsigned long>(
278 case SELF_URL_STREAM_ID:
279 self_url_.append(static_cast<char*>(buffer), len);
281 case FETCHED_URL_STREAM_ID:
283 char read_buffer[STREAM_CHUNK];
285 static_cast<int32>(fread(read_buffer, 1, len, test_file_));
286 // Technically, fread could return fewer than len
287 // bytes. But this is not likely.
289 SetError("Did not read correct bytelength from source file");
290 if (memcmp(read_buffer, buffer, len))
291 SetError("Content mismatch between data and source!");
294 case BOGUS_URL_STREAM_ID:
295 SetError("Unexpected write callback for BOGUS_URL");
298 SetError("Unexpected write callback");
301 // Pretend that we took all the data.
306 NPError PluginGetURLTest::DestroyStream(NPStream *stream, NPError reason) {
307 if (test_completed()) {
308 return PluginTest::DestroyStream(stream, reason);
311 if (stream == NULL) {
312 SetError("NewStream got null stream");
313 return NPERR_INVALID_PARAM;
316 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
317 cast_validity_check);
319 if (expect_404_response_) {
320 if (npn_evaluate_context_) {
321 SetError("Received destroyStream in the context of NPN_Evaluate.");
324 SignalTestCompleted();
325 return NPERR_NO_ERROR;
328 if (!referrer_target_url_.empty()) {
329 return NPERR_NO_ERROR;
332 if (check_cookies_) {
333 SignalTestCompleted();
334 return NPERR_NO_ERROR;
337 unsigned long stream_id =
338 reinterpret_cast<unsigned long>(stream->notifyData);
340 case SELF_URL_STREAM_ID:
343 case FETCHED_URL_STREAM_ID:
345 char read_buffer[STREAM_CHUNK];
346 size_t bytes = fread(read_buffer, 1, sizeof(read_buffer), test_file_);
348 SetError("Data and source mismatch on length");
349 file_util::CloseFile(test_file_);
353 SetError("Unexpected NewStream callback");
356 return NPERR_NO_ERROR;
359 void PluginGetURLTest::StreamAsFile(NPStream* stream, const char* fname) {
360 if (stream == NULL) {
361 SetError("NewStream got null stream");
365 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(stream->notifyData),
366 cast_validity_check);
367 unsigned long stream_id =
368 reinterpret_cast<unsigned long>(stream->notifyData);
370 case SELF_URL_STREAM_ID:
374 SetError("Unexpected NewStream callback");
379 void PluginGetURLTest::URLNotify(const char* url, NPReason reason, void* data) {
380 if (!tests_in_progress_) {
381 SetError("URLNotify received after tests completed");
386 SetError("URLNotify received NULL url");
393 COMPILE_ASSERT(sizeof(unsigned long) <= sizeof(data), cast_validity_check);
394 unsigned long stream_id = reinterpret_cast<unsigned long>(data);
396 case SELF_URL_STREAM_ID:
397 if (strcmp(url, SELF_URL) != 0)
398 SetError("URLNotify reported incorrect url for SELF_URL");
400 // We have our stream url. Go fetch it.
401 HostFunctions()->geturlnotify(id(), self_url_.c_str(), NULL,
402 reinterpret_cast<void*>(FETCHED_URL_STREAM_ID));
404 case FETCHED_URL_STREAM_ID:
405 if (!url || strcmp(url, self_url_.c_str()) != 0)
406 SetError("URLNotify reported incorrect url for FETCHED_URL");
407 tests_in_progress_--;
409 case BOGUS_URL_STREAM_ID:
410 if (reason != NPRES_NETWORK_ERR) {
411 std::string err = "BOGUS_URL received unexpected URLNotify status: ";
412 err.append(base::IntToString(reason));
415 tests_in_progress_--;
417 case REDIRECT_SRC_URL_NOTIFICATION_ID: {
418 if (!received_url_redirect_notification_) {
419 SetError("Failed to receive URLRedirect notification");
421 tests_in_progress_--;
425 SetError("Unexpected NewStream callback");
429 if (tests_in_progress_ == 0)
430 SignalTestCompleted();
433 void PluginGetURLTest::URLRedirectNotify(const char* url,
436 if (!base::strcasecmp(url, "http://mock.http/npapi/plugin_read_page.html")) {
437 received_url_redirect_notification_ = true;
438 // Disallow redirect notification.
439 HostFunctions()->urlredirectresponse(id(), notify_data, false);
443 } // namespace NPAPIClient