Make certificate viewer a tab-modal dialog.
[chromium-blink-merge.git] / ppapi / tests / test_url_request.cc
blobfd904db9517ada23ec98e12c7101fe8aa645c695
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 // Tests PPB_URLRequestInfo interface.
7 #include "ppapi/tests/test_url_request.h"
9 #include <string.h>
10 #include <string>
12 #include "ppapi/c/dev/ppb_testing_dev.h"
13 #include "ppapi/cpp/completion_callback.h"
14 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/var.h"
16 #include "ppapi/tests/test_utils.h"
17 #include "ppapi/tests/testing_instance.h"
19 REGISTER_TEST_CASE(URLRequest);
21 namespace {
22 // TODO(polina): move these to test_case.h/cc since other NaCl tests use them?
24 const PP_Resource kInvalidResource = 0;
25 const PP_Instance kInvalidInstance = 0;
27 // These should not exist.
28 // The bottom 2 bits are used to differentiate between different id types.
29 // 00 - module, 01 - instance, 10 - resource, 11 - var.
30 const PP_Instance kNotAnInstance = 0xFFFFF0;
31 const PP_Resource kNotAResource = 0xAAAAA0;
34 TestURLRequest::TestURLRequest(TestingInstance* instance)
35 : TestCase(instance),
36 ppb_url_request_interface_(NULL),
37 ppb_url_loader_interface_(NULL),
38 ppb_url_response_interface_(NULL),
39 ppb_core_interface_(NULL),
40 ppb_var_interface_(NULL),
41 url_loader_(kInvalidResource) {
44 bool TestURLRequest::Init() {
45 ppb_url_request_interface_ = static_cast<const PPB_URLRequestInfo*>(
46 pp::Module::Get()->GetBrowserInterface(PPB_URLREQUESTINFO_INTERFACE));
47 ppb_url_loader_interface_ = static_cast<const PPB_URLLoader*>(
48 pp::Module::Get()->GetBrowserInterface(PPB_URLLOADER_INTERFACE));
49 ppb_url_response_interface_ = static_cast<const PPB_URLResponseInfo*>(
50 pp::Module::Get()->GetBrowserInterface(PPB_URLRESPONSEINFO_INTERFACE));
51 ppb_core_interface_ = static_cast<const PPB_Core*>(
52 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
53 ppb_var_interface_ = static_cast<const PPB_Var*>(
54 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
55 if (!ppb_url_request_interface_)
56 instance_->AppendError("PPB_URLRequestInfo interface not available");
57 if (!ppb_url_response_interface_)
58 instance_->AppendError("PPB_URLResponseInfo interface not available");
59 if (!ppb_core_interface_)
60 instance_->AppendError("PPB_Core interface not available");
61 if (!ppb_var_interface_)
62 instance_->AppendError("PPB_Var interface not available");
63 if (!ppb_url_loader_interface_) {
64 instance_->AppendError("PPB_URLLoader interface not available");
65 } else {
66 url_loader_ = ppb_url_loader_interface_->Create(instance_->pp_instance());
67 if (url_loader_ == kInvalidResource)
68 instance_->AppendError("Failed to create URLLoader");
70 return EnsureRunningOverHTTP();
73 void TestURLRequest::RunTests(const std::string& filter) {
74 RUN_TEST(CreateAndIsURLRequestInfo, filter);
75 RUN_TEST(SetProperty, filter);
76 RUN_TEST(Stress, filter);
77 RUN_TEST(AppendDataToBody, filter);
80 PP_Var TestURLRequest::PP_MakeString(const char* s) {
81 return ppb_var_interface_->VarFromUtf8(s, strlen(s));
84 // Tests
85 // PP_Resource Create(PP_Instance instance)
86 // PP_Bool IsURLRequestInfo(PP_Resource resource)
87 std::string TestURLRequest::TestCreateAndIsURLRequestInfo() {
88 // Create: Invalid / non-existent instance -> invalid resource.
89 ASSERT_EQ(ppb_url_request_interface_->Create(kInvalidInstance),
90 kInvalidResource);
91 ASSERT_EQ(ppb_url_request_interface_->Create(kNotAnInstance),
92 kInvalidResource);
94 // Create: Valid instance -> valid resource.
95 PP_Resource url_request = ppb_url_request_interface_->Create(
96 instance_->pp_instance());
97 ASSERT_NE(url_request, kInvalidResource);
99 // IsURLRequestInfo:
100 // Invalid / non-existent / non-URLRequestInfo resource -> false.
101 ASSERT_NE(PP_TRUE,
102 ppb_url_request_interface_->IsURLRequestInfo(kInvalidResource));
103 ASSERT_NE(PP_TRUE,
104 ppb_url_request_interface_->IsURLRequestInfo(kNotAResource));
105 ASSERT_NE(PP_TRUE, ppb_url_request_interface_->IsURLRequestInfo(url_loader_));
107 // IsURLRequestInfo: Current URLRequestInfo resource -> true.
108 std::string error;
109 if (PP_FALSE == ppb_url_request_interface_->IsURLRequestInfo(url_request))
110 error = "IsURLRequestInfo() failed with a current URLRequestInfo resource";
112 // IsURLRequestInfo: Released URLRequestInfo resource -> false.
113 ppb_core_interface_->ReleaseResource(url_request);
114 ASSERT_NE(PP_TRUE, ppb_url_request_interface_->IsURLRequestInfo(url_request));
116 return error; // == PASS() if empty.
119 // Tests
120 // PP_Bool SetProperty(PP_Resource request,
121 // PP_URLRequestProperty property,
122 // struct PP_Var value);
123 std::string TestURLRequest::TestSetProperty() {
124 struct PropertyTestData {
125 PropertyTestData(PP_URLRequestProperty prop,
126 const std::string& name,
127 PP_Var value, PP_Bool expected) :
128 property(prop), property_name(name),
129 var(value), expected_value(expected) {
130 // var has ref count of 1 on creation.
132 PP_URLRequestProperty property;
133 std::string property_name;
134 PP_Var var; // Instance owner is responsible for releasing this var.
135 PP_Bool expected_value;
138 // All bool properties should accept PP_TRUE and PP_FALSE, while rejecting
139 // all other variable types.
140 #define TEST_BOOL(_name) \
141 PropertyTestData(ID_STR(_name), PP_MakeBool(PP_TRUE), PP_TRUE), \
142 PropertyTestData(ID_STR(_name), PP_MakeBool(PP_FALSE), PP_TRUE), \
143 PropertyTestData(ID_STR(_name), PP_MakeUndefined(), PP_FALSE), \
144 PropertyTestData(ID_STR(_name), PP_MakeNull(), PP_FALSE), \
145 PropertyTestData(ID_STR(_name), PP_MakeInt32(0), PP_FALSE), \
146 PropertyTestData(ID_STR(_name), PP_MakeDouble(0.0), PP_FALSE)
148 // These property types are always invalid for string properties.
149 #define TEST_STRING_INVALID(_name) \
150 PropertyTestData(ID_STR(_name), PP_MakeNull(), PP_FALSE), \
151 PropertyTestData(ID_STR(_name), PP_MakeBool(PP_FALSE), PP_FALSE), \
152 PropertyTestData(ID_STR(_name), PP_MakeInt32(0), PP_FALSE), \
153 PropertyTestData(ID_STR(_name), PP_MakeDouble(0.0), PP_FALSE)
155 #define TEST_INT_INVALID(_name) \
156 PropertyTestData(ID_STR(_name), PP_MakeUndefined(), PP_FALSE), \
157 PropertyTestData(ID_STR(_name), PP_MakeNull(), PP_FALSE), \
158 PropertyTestData(ID_STR(_name), PP_MakeBool(PP_FALSE), PP_FALSE), \
159 PropertyTestData(ID_STR(_name), PP_MakeString("notint"), PP_FALSE), \
160 PropertyTestData(ID_STR(_name), PP_MakeDouble(0.0), PP_FALSE)
162 // SetProperty accepts plenty of invalid values (malformed urls, negative
163 // thresholds, etc). Error checking is delayed until request opening (aka url
164 // loading).
165 #define ID_STR(arg) arg, #arg
166 PropertyTestData test_data[] = {
167 TEST_BOOL(PP_URLREQUESTPROPERTY_STREAMTOFILE),
168 TEST_BOOL(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS),
169 TEST_BOOL(PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS),
170 TEST_BOOL(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS),
171 TEST_BOOL(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS),
172 TEST_BOOL(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS),
173 TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_URL),
174 TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_METHOD),
175 TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_HEADERS),
176 TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
177 TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
178 TEST_STRING_INVALID(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
179 TEST_INT_INVALID(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
180 TEST_INT_INVALID(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
181 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
182 PP_MakeString("http://www.google.com"), PP_TRUE),
183 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
184 PP_MakeString("foo.jpg"), PP_TRUE),
185 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
186 PP_MakeString("GET"), PP_TRUE),
187 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
188 PP_MakeString("POST"), PP_TRUE),
189 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
190 PP_MakeString("Accept: text/plain"), PP_TRUE),
191 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
192 PP_MakeString(""), PP_TRUE),
193 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
194 PP_MakeString("http://www.google.com"), PP_TRUE),
195 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
196 PP_MakeString(""), PP_TRUE),
197 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL),
198 PP_MakeUndefined(), PP_TRUE),
199 PropertyTestData(
200 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
201 PP_MakeString("base64"), PP_TRUE),
202 PropertyTestData(
203 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
204 PP_MakeString(""), PP_TRUE),
205 PropertyTestData(
206 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
207 PP_MakeUndefined(), PP_TRUE),
208 PropertyTestData(
209 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
210 PP_MakeString("My Crazy Plugin"), PP_TRUE),
211 PropertyTestData(
212 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
213 PP_MakeString(""), PP_TRUE),
214 PropertyTestData(
215 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT),
216 PP_MakeUndefined(), PP_TRUE),
217 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
218 PP_MakeUndefined(), PP_FALSE),
219 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
220 PP_MakeUndefined(), PP_FALSE),
221 PropertyTestData(
222 ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
223 PP_MakeString("Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA=="),
224 PP_TRUE),
225 PropertyTestData(
226 ID_STR(PP_URLREQUESTPROPERTY_HEADERS),
227 PP_MakeString("Accept-Encoding: *\n"
228 "Accept-Charset: iso-8859-5, unicode-1-1;q=0.8"),
229 PP_TRUE),
230 PropertyTestData(
231 ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
232 PP_MakeInt32(0), PP_TRUE),
233 PropertyTestData(
234 ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
235 PP_MakeInt32(100), PP_TRUE),
236 PropertyTestData(
237 ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
238 PP_MakeInt32(0), PP_TRUE),
239 PropertyTestData(
240 ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
241 PP_MakeInt32(100), PP_TRUE),
242 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL),
243 PP_MakeString("::::::::::::"), PP_TRUE),
244 PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD),
245 PP_MakeString("INVALID"), PP_TRUE),
246 PropertyTestData(
247 ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING),
248 PP_MakeString("invalid"), PP_TRUE),
249 PropertyTestData(
250 ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD),
251 PP_MakeInt32(-100), PP_TRUE),
252 PropertyTestData(
253 ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD),
254 PP_MakeInt32(-100), PP_TRUE),
257 std::string error;
259 PP_Resource url_request = ppb_url_request_interface_->Create(
260 instance_->pp_instance());
261 if (url_request == kInvalidResource)
262 error = "Failed to create a URLRequestInfo";
264 // Loop over all test data even if we encountered an error to release vars.
265 for (size_t i = 0;
266 i < sizeof(test_data) / sizeof(test_data[0]);
267 ++i) {
268 if (error.empty() && test_data[i].expected_value !=
269 ppb_url_request_interface_->SetProperty(url_request,
270 test_data[i].property,
271 test_data[i].var)) {
272 pp::Var var(pp::Var::DontManage(), test_data[i].var);
273 error = std::string("Setting property ") +
274 test_data[i].property_name + " to " + var.DebugString() +
275 " did not return " + (test_data[i].expected_value ? "True" : "False");
276 error = test_data[i].property_name;
278 ppb_var_interface_->Release(test_data[i].var);
281 ppb_core_interface_->ReleaseResource(url_request);
282 return error; // == PASS() if empty.
285 std::string TestURLRequest::LoadAndCompareBody(
286 PP_Resource url_request, const std::string& expected_body) {
287 TestCompletionCallback callback(instance_->pp_instance(), PP_REQUIRED);
288 callback.WaitForResult(ppb_url_loader_interface_->Open(
289 url_loader_, url_request,
290 callback.GetCallback().pp_completion_callback()));
291 CHECK_CALLBACK_BEHAVIOR(callback);
292 ASSERT_EQ(PP_OK, callback.result());
294 std::string error;
295 PP_Resource url_response =
296 ppb_url_loader_interface_->GetResponseInfo(url_loader_);
297 if (url_response == kInvalidResource) {
298 error = "PPB_URLLoader::GetResponseInfo() returned invalid resource";
299 } else {
300 PP_Var status = ppb_url_response_interface_->GetProperty(
301 url_response, PP_URLRESPONSEPROPERTY_STATUSCODE);
302 if (status.type != PP_VARTYPE_INT32 && status.value.as_int != 200)
303 error = ReportError("PPB_URLLoader::Open() status", status.value.as_int);
305 std::string actual_body;
306 for (; error.empty();) { // Read the entire body in this loop.
307 const size_t kBufferSize = 32;
308 char buf[kBufferSize];
309 callback.WaitForResult(ppb_url_loader_interface_->ReadResponseBody(
310 url_loader_, buf, kBufferSize,
311 callback.GetCallback().pp_completion_callback()));
312 if (callback.failed())
313 error.assign(callback.errors());
314 else if (callback.result() < PP_OK)
315 error.assign(ReportError("PPB_URLLoader::ReadResponseBody()",
316 callback.result()));
317 if (callback.result() <= PP_OK || callback.failed())
318 break;
319 actual_body.append(buf, callback.result());
321 if (actual_body != expected_body)
322 error = "PPB_URLLoader::ReadResponseBody() read unexpected response";
324 ppb_core_interface_->ReleaseResource(url_response);
325 return error;
328 // Tests
329 // PP_Bool AppendDataToBody(
330 // PP_Resource request, const void* data, uint32_t len);
331 std::string TestURLRequest::TestAppendDataToBody() {
332 PP_Resource url_request = ppb_url_request_interface_->Create(
333 instance_->pp_instance());
334 ASSERT_NE(url_request, kInvalidResource);
336 std::string postdata("sample postdata");
337 std::string error;
338 PP_Var post_string_var = PP_MakeString("POST");
339 PP_Var echo_string_var = PP_MakeString("/echo");
341 // NULL pointer causes a crash. In general PPAPI implementation does not
342 // test for NULL because they are just a special case of bad pointers that
343 // are not detectable if set to point to an object that does not exist.
345 // Invalid resource should fail.
346 if (PP_TRUE == ppb_url_request_interface_->AppendDataToBody(
347 kInvalidResource, postdata.data(), postdata.length())) {
348 error = "AppendDataToBody() succeeded with invalid resource";
349 // Append data and POST to echoing web server.
350 } else if (PP_FALSE == ppb_url_request_interface_->SetProperty(
351 url_request, PP_URLREQUESTPROPERTY_METHOD, post_string_var)) {
352 error = "SetProperty(METHOD) failed\n";
353 } else if (PP_FALSE == ppb_url_request_interface_->SetProperty(
354 url_request, PP_URLREQUESTPROPERTY_URL, echo_string_var)) {
355 error = "SetProperty(URL) failed\n";
356 } else if (PP_FALSE == ppb_url_request_interface_->AppendDataToBody(
357 url_request, postdata.data(), postdata.length())) {
358 error = "AppendDataToBody() failed";
359 } else {
360 // Check for success.
361 error = LoadAndCompareBody(url_request, postdata);
364 ppb_var_interface_->Release(post_string_var);
365 ppb_var_interface_->Release(echo_string_var);
366 ppb_core_interface_->ReleaseResource(url_request);
367 return error; // == PASS() if empty.
370 // TODO(elijahtaylor): add TestAppendFileToBody based on a broken disabled
371 // version from a NaCl test - see crbug.com/110242 for details.
373 // Allocates and manipulates a large number of resources.
374 std::string TestURLRequest::TestStress() {
375 const int kManyResources = 500;
376 PP_Resource url_request_info[kManyResources];
378 std::string error;
379 int num_created = kManyResources;
380 for (int i = 0; i < kManyResources; i++) {
381 url_request_info[i] = ppb_url_request_interface_->Create(
382 instance_->pp_instance());
383 if (url_request_info[i] == kInvalidResource) {
384 error = "Create() failed";
385 } else if (PP_FALSE == ppb_url_request_interface_->IsURLRequestInfo(
386 url_request_info[i])) {
387 error = "IsURLRequestInfo() failed";
388 } else if (PP_FALSE == ppb_url_request_interface_->SetProperty(
389 url_request_info[i],
390 PP_URLREQUESTPROPERTY_STREAMTOFILE,
391 PP_MakeBool(PP_FALSE))) {
392 error = "SetProperty() failed";
394 if (!error.empty()) {
395 num_created = i + 1;
396 break;
399 for (int i = 0; i < num_created; i++) {
400 ppb_core_interface_->ReleaseResource(url_request_info[i]);
401 if (PP_TRUE ==
402 ppb_url_request_interface_->IsURLRequestInfo(url_request_info[i]))
403 error = "IsURLREquestInfo() succeeded after release";
405 return error; // == PASS() if empty.