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

Side by Side Diff: ppapi/cpp/url_loader.cc

Issue 11417145: Provide a safer URLLoader ReadResponseBody API (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years 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
« no previous file with comments | « ppapi/cpp/url_loader.h ('k') | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/cpp/url_loader.h" 5 #include "ppapi/cpp/url_loader.h"
6 6
7 #include <string.h> // memcpy
8
7 #include "ppapi/c/ppb_url_loader.h" 9 #include "ppapi/c/ppb_url_loader.h"
8 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/cpp/completion_callback.h"
10 #include "ppapi/cpp/file_ref.h" 11 #include "ppapi/cpp/file_ref.h"
11 #include "ppapi/cpp/instance_handle.h" 12 #include "ppapi/cpp/instance_handle.h"
12 #include "ppapi/cpp/module.h" 13 #include "ppapi/cpp/module.h"
13 #include "ppapi/cpp/module_impl.h" 14 #include "ppapi/cpp/module_impl.h"
14 #include "ppapi/cpp/url_request_info.h" 15 #include "ppapi/cpp/url_request_info.h"
15 #include "ppapi/cpp/url_response_info.h" 16 #include "ppapi/cpp/url_response_info.h"
16 17
17 namespace pp { 18 namespace pp {
18 19
19 namespace { 20 namespace {
20 21
22 template <> const char* interface_name<PPB_URLLoader_1_1>() {
23 return PPB_URLLOADER_INTERFACE_1_1;
24 }
25
21 template <> const char* interface_name<PPB_URLLoader_1_0>() { 26 template <> const char* interface_name<PPB_URLLoader_1_0>() {
22 return PPB_URLLOADER_INTERFACE_1_0; 27 return PPB_URLLOADER_INTERFACE_1_0;
23 } 28 }
24 29
25 } // namespace 30 } // namespace
26 31
27 URLLoader::URLLoader(PP_Resource resource) : Resource(resource) { 32 URLLoader::URLLoader(PP_Resource resource) : Resource(resource) {
28 } 33 }
29 34
30 URLLoader::URLLoader(const InstanceHandle& instance) { 35 URLLoader::URLLoader(const InstanceHandle& instance) {
31 if (!has_interface<PPB_URLLoader_1_0>()) 36 if (has_interface<PPB_URLLoader_1_1>()) {
32 return; 37 PassRefFromConstructor(get_interface<PPB_URLLoader_1_1>()->Create(
33 PassRefFromConstructor(get_interface<PPB_URLLoader_1_0>()->Create( 38 instance.pp_instance()));
34 instance.pp_instance())); 39 } else if (has_interface<PPB_URLLoader_1_0>()) {
40 PassRefFromConstructor(get_interface<PPB_URLLoader_1_0>()->Create(
41 instance.pp_instance()));
42 }
35 } 43 }
36 44
37 URLLoader::URLLoader(const URLLoader& other) : Resource(other) { 45 URLLoader::URLLoader(const URLLoader& other) : Resource(other) {
38 } 46 }
39 47
40 int32_t URLLoader::Open(const URLRequestInfo& request_info, 48 int32_t URLLoader::Open(const URLRequestInfo& request_info,
41 const CompletionCallback& cc) { 49 const CompletionCallback& cc) {
42 if (!has_interface<PPB_URLLoader_1_0>()) 50 if (has_interface<PPB_URLLoader_1_1>()) {
43 return cc.MayForce(PP_ERROR_NOINTERFACE); 51 return get_interface<PPB_URLLoader_1_1>()->Open(
44 return get_interface<PPB_URLLoader_1_0>()->Open(pp_resource(), 52 pp_resource(), request_info.pp_resource(), cc.pp_completion_callback());
45 request_info.pp_resource(), 53 } else if (has_interface<PPB_URLLoader_1_0>()) {
46 cc.pp_completion_callback()); 54 return get_interface<PPB_URLLoader_1_0>()->Open(
55 pp_resource(), request_info.pp_resource(), cc.pp_completion_callback());
56 }
57 return cc.MayForce(PP_ERROR_NOINTERFACE);
47 } 58 }
48 59
49 int32_t URLLoader::FollowRedirect(const CompletionCallback& cc) { 60 int32_t URLLoader::FollowRedirect(const CompletionCallback& cc) {
50 if (!has_interface<PPB_URLLoader_1_0>()) 61 if (has_interface<PPB_URLLoader_1_1>()) {
51 return cc.MayForce(PP_ERROR_NOINTERFACE); 62 return get_interface<PPB_URLLoader_1_1>()->FollowRedirect(
52 return get_interface<PPB_URLLoader_1_0>()->FollowRedirect( 63 pp_resource(), cc.pp_completion_callback());
53 pp_resource(), cc.pp_completion_callback()); 64 } else if (has_interface<PPB_URLLoader_1_0>()) {
65 return get_interface<PPB_URLLoader_1_0>()->FollowRedirect(
66 pp_resource(), cc.pp_completion_callback());
67 }
68 return cc.MayForce(PP_ERROR_NOINTERFACE);
54 } 69 }
55 70
56 bool URLLoader::GetUploadProgress(int64_t* bytes_sent, 71 bool URLLoader::GetUploadProgress(int64_t* bytes_sent,
57 int64_t* total_bytes_to_be_sent) const { 72 int64_t* total_bytes_to_be_sent) const {
58 if (!has_interface<PPB_URLLoader_1_0>()) 73 if (has_interface<PPB_URLLoader_1_1>()) {
59 return false; 74 return PP_ToBool(get_interface<PPB_URLLoader_1_1>()->GetUploadProgress(
60 return PP_ToBool(get_interface<PPB_URLLoader_1_0>()->GetUploadProgress( 75 pp_resource(), bytes_sent, total_bytes_to_be_sent));
61 pp_resource(), bytes_sent, total_bytes_to_be_sent)); 76 } else if (has_interface<PPB_URLLoader_1_0>()) {
77 return PP_ToBool(get_interface<PPB_URLLoader_1_0>()->GetUploadProgress(
78 pp_resource(), bytes_sent, total_bytes_to_be_sent));
79 }
80 return false;
62 } 81 }
63 82
64 bool URLLoader::GetDownloadProgress( 83 bool URLLoader::GetDownloadProgress(
65 int64_t* bytes_received, 84 int64_t* bytes_received,
66 int64_t* total_bytes_to_be_received) const { 85 int64_t* total_bytes_to_be_received) const {
67 if (!has_interface<PPB_URLLoader_1_0>()) 86 if (has_interface<PPB_URLLoader_1_1>()) {
68 return false; 87 return PP_ToBool(get_interface<PPB_URLLoader_1_1>()->GetDownloadProgress(
69 return PP_ToBool(get_interface<PPB_URLLoader_1_0>()->GetDownloadProgress( 88 pp_resource(), bytes_received, total_bytes_to_be_received));
70 pp_resource(), bytes_received, total_bytes_to_be_received)); 89 } else if (has_interface<PPB_URLLoader_1_0>()) {
90 return PP_ToBool(get_interface<PPB_URLLoader_1_0>()->GetDownloadProgress(
91 pp_resource(), bytes_received, total_bytes_to_be_received));
92 }
93 return false;
71 } 94 }
72 95
73 URLResponseInfo URLLoader::GetResponseInfo() const { 96 URLResponseInfo URLLoader::GetResponseInfo() const {
74 if (!has_interface<PPB_URLLoader_1_0>()) 97 if (has_interface<PPB_URLLoader_1_1>()) {
75 return URLResponseInfo(); 98 return URLResponseInfo(PASS_REF,
76 return URLResponseInfo(PASS_REF, 99 get_interface<PPB_URLLoader_1_1>()->GetResponseInfo(
77 get_interface<PPB_URLLoader_1_0>()->GetResponseInfo( 100 pp_resource()));
78 pp_resource())); 101 } else if (has_interface<PPB_URLLoader_1_0>()) {
102 return URLResponseInfo(PASS_REF,
103 get_interface<PPB_URLLoader_1_0>()->GetResponseInfo(
104 pp_resource()));
105 }
106 return URLResponseInfo();
79 } 107 }
80 108
81 int32_t URLLoader::ReadResponseBody(void* buffer, 109 int32_t URLLoader::ReadResponseBody(void* buffer,
82 int32_t bytes_to_read, 110 int32_t bytes_to_read,
83 const CompletionCallback& cc) { 111 const CompletionCallback& cc) {
84 if (!has_interface<PPB_URLLoader_1_0>()) 112 if (has_interface<PPB_URLLoader_1_1>()) {
85 return cc.MayForce(PP_ERROR_NOINTERFACE); 113 return get_interface<PPB_URLLoader_1_1>()->ReadResponseBody(
86 return get_interface<PPB_URLLoader_1_0>()->ReadResponseBody( 114 pp_resource(), buffer, bytes_to_read, cc.pp_completion_callback());
87 pp_resource(), buffer, bytes_to_read, cc.pp_completion_callback()); 115 } else if (has_interface<PPB_URLLoader_1_0>()) {
116 return get_interface<PPB_URLLoader_1_0>()->ReadResponseBody(
117 pp_resource(), buffer, bytes_to_read, cc.pp_completion_callback());
118 }
119 return cc.MayForce(PP_ERROR_NOINTERFACE);
120 }
121
122 int32_t URLLoader::ReadResponseBody(
123 int32_t max_read_length,
124 const CompletionCallbackWithOutput< std::vector<char> >& cc) {
125 if (has_interface<PPB_URLLoader_1_1>()) {
126 PP_ArrayOutput array_output = cc.output();
127 return get_interface<PPB_URLLoader_1_1>()->ReadResponseBodyToArray(
128 pp_resource(), max_read_length, &array_output,
129 cc.pp_completion_callback());
130 } else if (has_interface<PPB_URLLoader_1_0>()) {
131 // Data for our callback wrapper. The callback handler will delete it and
132 // temp_buffer.
133 CallbackData1_0* data = new CallbackData1_0;
134 data->output = cc.output();
135 data->temp_buffer = max_read_length >= 0 ? new char[max_read_length] : NULL;
136 data->original_callback = cc.pp_completion_callback();
137
138 // Actual returned bytes might not equals to max_read_length. We need to
139 // read to a temporary buffer first and copy later to make sure the array
140 // buffer has correct size.
141 return get_interface<PPB_URLLoader_1_0>()->ReadResponseBody(
142 pp_resource(), data->temp_buffer, max_read_length,
143 PP_MakeCompletionCallback(&CallbackConverter, data));
144 }
145 return cc.MayForce(PP_ERROR_NOINTERFACE);
88 } 146 }
89 147
90 int32_t URLLoader::FinishStreamingToFile(const CompletionCallback& cc) { 148 int32_t URLLoader::FinishStreamingToFile(const CompletionCallback& cc) {
91 if (!has_interface<PPB_URLLoader_1_0>()) 149 if (has_interface<PPB_URLLoader_1_1>()) {
92 return cc.MayForce(PP_ERROR_NOINTERFACE); 150 return get_interface<PPB_URLLoader_1_1>()->FinishStreamingToFile(
93 return get_interface<PPB_URLLoader_1_0>()->FinishStreamingToFile( 151 pp_resource(), cc.pp_completion_callback());
94 pp_resource(), cc.pp_completion_callback()); 152 } else if (has_interface<PPB_URLLoader_1_0>()) {
153 return get_interface<PPB_URLLoader_1_0>()->FinishStreamingToFile(
154 pp_resource(), cc.pp_completion_callback());
155 }
156 return cc.MayForce(PP_ERROR_NOINTERFACE);
95 } 157 }
96 158
97 void URLLoader::Close() { 159 void URLLoader::Close() {
98 if (!has_interface<PPB_URLLoader_1_0>()) 160 if (has_interface<PPB_URLLoader_1_1>())
99 return; 161 get_interface<PPB_URLLoader_1_1>()->Close(pp_resource());
100 get_interface<PPB_URLLoader_1_0>()->Close(pp_resource()); 162 else if (has_interface<PPB_URLLoader_1_0>())
163 get_interface<PPB_URLLoader_1_0>()->Close(pp_resource());
164 }
165
166 // static
167 void URLLoader::CallbackConverter(void* user_data, int32_t result) {
168 CallbackData1_0* data = static_cast<CallbackData1_0*>(user_data);
169
170 if (result >= 0) {
171 // Copy to the destination buffer owned by the callback.
172 char* buffer = static_cast<char*>(data->output.GetDataBuffer(
173 data->output.user_data, result, sizeof(char)));
174 memcpy(buffer, data->temp_buffer, result);
175 delete[] data->temp_buffer;
176 }
177
178 // Now execute the original callback.
179 PP_RunCompletionCallback(&data->original_callback, result);
180 delete data;
101 } 181 }
102 182
103 } // namespace pp 183 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/cpp/url_loader.h ('k') | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698