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

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/mount_node_http.cc

Issue 77423002: [NaCl SDK] Add URLLoader fake pepper interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: feedback Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "nacl_io/mount_node_http.h" 5 #include "nacl_io/mount_node_http.h"
6 6
7 #include <assert.h> 7 #include <assert.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <string.h> 10 #include <string.h>
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 return EIO; 144 return EIO;
145 } 145 }
146 146
147 } // namespace 147 } // namespace
148 148
149 void MountNodeHttp::SetCachedSize(off_t size) { 149 void MountNodeHttp::SetCachedSize(off_t size) {
150 has_cached_size_ = true; 150 has_cached_size_ = true;
151 stat_.st_size = size; 151 stat_.st_size = size;
152 } 152 }
153 153
154 Error MountNodeHttp::FSync() { return ENOSYS; } 154 Error MountNodeHttp::FSync() { return EACCES; }
155 155
156 Error MountNodeHttp::GetDents(size_t offs, 156 Error MountNodeHttp::GetDents(size_t offs,
157 struct dirent* pdir, 157 struct dirent* pdir,
158 size_t count, 158 size_t count,
159 int* out_bytes) { 159 int* out_bytes) {
160 *out_bytes = 0; 160 *out_bytes = 0;
161 return ENOSYS; 161 return EACCES;
162 } 162 }
163 163
164 Error MountNodeHttp::GetStat(struct stat* stat) { 164 Error MountNodeHttp::GetStat(struct stat* stat) {
165 AUTO_LOCK(node_lock_); 165 AUTO_LOCK(node_lock_);
166 166
167 // Assume we need to 'HEAD' if we do not know the size, otherwise, assume 167 // Assume we need to 'HEAD' if we do not know the size, otherwise, assume
168 // that the information is constant. We can add a timeout if needed. 168 // that the information is constant. We can add a timeout if needed.
169 MountHttp* mount = static_cast<MountHttp*>(mount_); 169 MountHttp* mount = static_cast<MountHttp*>(mount_);
170 if (stat_.st_size == 0 || !mount->cache_stat_) { 170 if (stat_.st_size == 0 || !mount->cache_stat_) {
171 StringMap_t headers; 171 StringMap_t headers;
(...skipping 14 matching lines...) Expand all
186 186
187 ScopedResource scoped_loader(mount_->ppapi(), loader); 187 ScopedResource scoped_loader(mount_->ppapi(), loader);
188 ScopedResource scoped_request(mount_->ppapi(), request); 188 ScopedResource scoped_request(mount_->ppapi(), request);
189 ScopedResource scoped_response(mount_->ppapi(), response); 189 ScopedResource scoped_response(mount_->ppapi(), response);
190 190
191 size_t entity_length; 191 size_t entity_length;
192 if (ParseContentLength(response_headers, &entity_length)) { 192 if (ParseContentLength(response_headers, &entity_length)) {
193 SetCachedSize(static_cast<off_t>(entity_length)); 193 SetCachedSize(static_cast<off_t>(entity_length));
194 } else if (cache_content_ && !has_cached_size_) { 194 } else if (cache_content_ && !has_cached_size_) {
195 error = DownloadToCache(); 195 error = DownloadToCache();
196 // TODO(binji): this error should not be dropped, but it requires a bit 196 if (error)
197 // of a refactor of the tests. See crbug.com/245431 197 return error;
198 // if (error)
199 // return error;
200 } else { 198 } else {
201 // Don't use SetCachedSize here -- it is actually unknown. 199 // Don't use SetCachedSize here -- it is actually unknown.
202 stat_.st_size = 0; 200 stat_.st_size = 0;
203 } 201 }
204 202
205 stat_.st_atime = 0; // TODO(binji): Use "Last-Modified". 203 stat_.st_atime = 0; // TODO(binji): Use "Last-Modified".
206 stat_.st_mtime = 0; 204 stat_.st_mtime = 0;
207 stat_.st_ctime = 0; 205 stat_.st_ctime = 0;
208 206
209 stat_.st_mode |= S_IFREG; 207 stat_.st_mode |= S_IFREG;
(...skipping 13 matching lines...) Expand all
223 *out_bytes = 0; 221 *out_bytes = 0;
224 222
225 AUTO_LOCK(node_lock_); 223 AUTO_LOCK(node_lock_);
226 if (cache_content_) { 224 if (cache_content_) {
227 if (cached_data_.empty()) { 225 if (cached_data_.empty()) {
228 Error error = DownloadToCache(); 226 Error error = DownloadToCache();
229 if (error) 227 if (error)
230 return error; 228 return error;
231 } 229 }
232 230
233 return ReadPartialFromCache(attr.offs, buf, count, out_bytes); 231 return ReadPartialFromCache(attr, buf, count, out_bytes);
234 } 232 }
235 233
236 return DownloadPartial(attr.offs, buf, count, out_bytes); 234 return DownloadPartial(attr, buf, count, out_bytes);
237 } 235 }
238 236
239 Error MountNodeHttp::FTruncate(off_t size) { return ENOSYS; } 237 Error MountNodeHttp::FTruncate(off_t size) { return EACCES; }
240 238
241 Error MountNodeHttp::Write(const HandleAttr& attr, 239 Error MountNodeHttp::Write(const HandleAttr& attr,
242 const void* buf, 240 const void* buf,
243 size_t count, 241 size_t count,
244 int* out_bytes) { 242 int* out_bytes) {
245 // TODO(binji): support POST? 243 // TODO(binji): support POST?
246 *out_bytes = 0; 244 *out_bytes = 0;
247 return ENOSYS; 245 return EACCES;
248 } 246 }
249 247
250 Error MountNodeHttp::GetSize(size_t* out_size) { 248 Error MountNodeHttp::GetSize(size_t* out_size) {
251 *out_size = 0; 249 *out_size = 0;
252 250
253 // TODO(binji): This value should be cached properly; i.e. obey the caching 251 // TODO(binji): This value should be cached properly; i.e. obey the caching
254 // headers returned by the server. 252 // headers returned by the server.
255 AUTO_LOCK(node_lock_); 253 AUTO_LOCK(node_lock_);
256 if (!has_cached_size_) { 254 if (!has_cached_size_) {
257 // Even if DownloadToCache fails, the best result we can return is what 255 // Even if DownloadToCache fails, the best result we can return is what
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 uint32_t response_headers_length; 333 uint32_t response_headers_length;
336 const char* response_headers_str = 334 const char* response_headers_str =
337 var_interface->VarToUtf8(response_headers_var, &response_headers_length); 335 var_interface->VarToUtf8(response_headers_var, &response_headers_length);
338 336
339 *out_loader = loader.Release(); 337 *out_loader = loader.Release();
340 *out_request = request.Release(); 338 *out_request = request.Release();
341 *out_response = response.Release(); 339 *out_response = response.Release();
342 *out_response_headers = 340 *out_response_headers =
343 ParseHeaders(response_headers_str, response_headers_length); 341 ParseHeaders(response_headers_str, response_headers_length);
344 342
343 var_interface->Release(response_headers_var);
344
345 return 0; 345 return 0;
346 } 346 }
347 347
348 Error MountNodeHttp::DownloadToCache() { 348 Error MountNodeHttp::DownloadToCache() {
349 StringMap_t headers; 349 StringMap_t headers;
350 PP_Resource loader; 350 PP_Resource loader;
351 PP_Resource request; 351 PP_Resource request;
352 PP_Resource response; 352 PP_Resource response;
353 int32_t statuscode; 353 int32_t statuscode;
354 StringMap_t response_headers; 354 StringMap_t response_headers;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 if (bytes_read < bytes_to_read) { 397 if (bytes_read < bytes_to_read) {
398 SetCachedSize(total_bytes_read); 398 SetCachedSize(total_bytes_read);
399 cached_data_.resize(total_bytes_read); 399 cached_data_.resize(total_bytes_read);
400 return 0; 400 return 0;
401 } 401 }
402 402
403 cached_data_.resize(total_bytes_read + bytes_to_read); 403 cached_data_.resize(total_bytes_read + bytes_to_read);
404 } 404 }
405 } 405 }
406 406
407 Error MountNodeHttp::ReadPartialFromCache(size_t offs, 407 Error MountNodeHttp::ReadPartialFromCache(const HandleAttr& attr,
408 void* buf, 408 void* buf,
409 int count, 409 int count,
410 int* out_bytes) { 410 int* out_bytes) {
411 *out_bytes = 0; 411 *out_bytes = 0;
412 size_t size = cached_data_.size();
412 413
413 if (offs > cached_data_.size()) 414 if (attr.offs + count > size)
414 return EINVAL; 415 count = size - attr.offs;
415 416
416 count = std::min(count, static_cast<int>(cached_data_.size() - offs)); 417 if (count <= 0)
417 memcpy(buf, &cached_data_.data()[offs], count); 418 return 0;
418 419
420 memcpy(buf, &cached_data_.data()[attr.offs], count);
419 *out_bytes = count; 421 *out_bytes = count;
420 return 0; 422 return 0;
421 } 423 }
422 424
423 Error MountNodeHttp::DownloadPartial(size_t offs, 425 Error MountNodeHttp::DownloadPartial(const HandleAttr& attr,
424 void* buf, 426 void* buf,
425 size_t count, 427 size_t count,
426 int* out_bytes) { 428 int* out_bytes) {
427 *out_bytes = 0; 429 *out_bytes = 0;
428 430
429 StringMap_t headers; 431 StringMap_t headers;
430 432
431 char buffer[100]; 433 char buffer[100];
432 // Range request is inclusive: 0-99 returns 100 bytes. 434 // Range request is inclusive: 0-99 returns 100 bytes.
433 snprintf(&buffer[0], 435 snprintf(&buffer[0],
434 sizeof(buffer), 436 sizeof(buffer),
435 "bytes=%" PRIuS "-%" PRIuS, 437 "bytes=%" PRIuS "-%" PRIuS,
436 offs, 438 attr.offs,
437 offs + count - 1); 439 attr.offs + count - 1);
438 headers["Range"] = buffer; 440 headers["Range"] = buffer;
439 441
440 PP_Resource loader; 442 PP_Resource loader;
441 PP_Resource request; 443 PP_Resource request;
442 PP_Resource response; 444 PP_Resource response;
443 int32_t statuscode; 445 int32_t statuscode;
444 StringMap_t response_headers; 446 StringMap_t response_headers;
445 Error error = OpenUrl("GET", 447 Error error = OpenUrl("GET",
446 &headers, 448 &headers,
447 &loader, 449 &loader,
448 &request, 450 &request,
449 &response, 451 &response,
450 &statuscode, 452 &statuscode,
451 &response_headers); 453 &response_headers);
452 if (error) 454 if (error)
453 return error; 455 return error;
454 456
455 PepperInterface* ppapi = mount_->ppapi(); 457 PepperInterface* ppapi = mount_->ppapi();
456 ScopedResource scoped_loader(ppapi, loader); 458 ScopedResource scoped_loader(ppapi, loader);
457 ScopedResource scoped_request(ppapi, request); 459 ScopedResource scoped_request(ppapi, request);
458 ScopedResource scoped_response(ppapi, response); 460 ScopedResource scoped_response(ppapi, response);
459 461
460 size_t read_start = 0; 462 size_t read_start = 0;
461 if (statuscode == STATUSCODE_OK) { 463 if (statuscode == STATUSCODE_OK) {
462 // No partial result, read everything starting from the part we care about. 464 // No partial result, read everything starting from the part we care about.
463 size_t content_length; 465 size_t content_length;
464 if (ParseContentLength(response_headers, &content_length)) { 466 if (ParseContentLength(response_headers, &content_length)) {
465 if (offs >= content_length) 467 if (attr.offs >= content_length)
466 return EINVAL; 468 return EINVAL;
467 469
468 // Clamp count, if trying to read past the end of the file. 470 // Clamp count, if trying to read past the end of the file.
469 if (offs + count > content_length) { 471 if (attr.offs + count > content_length) {
470 count = content_length - offs; 472 count = content_length - attr.offs;
471 } 473 }
472 } 474 }
473 } else if (statuscode == STATUSCODE_PARTIAL_CONTENT) { 475 } else if (statuscode == STATUSCODE_PARTIAL_CONTENT) {
474 // Determine from the headers where we are reading. 476 // Determine from the headers where we are reading.
475 size_t read_end; 477 size_t read_end;
476 size_t entity_length; 478 size_t entity_length;
477 if (ParseContentRange( 479 if (ParseContentRange(
478 response_headers, &read_start, &read_end, &entity_length)) { 480 response_headers, &read_start, &read_end, &entity_length)) {
479 if (read_start > offs || read_start > read_end) { 481 if (read_start > attr.offs || read_start > read_end) {
480 // If this error occurs, the server is returning bogus values. 482 // If this error occurs, the server is returning bogus values.
481 return EINVAL; 483 return EINVAL;
482 } 484 }
483 485
484 // Clamp count, if trying to read past the end of the file. 486 // Clamp count, if trying to read past the end of the file.
485 count = std::min(read_end - read_start, count); 487 count = std::min(read_end - read_start, count);
486 } else { 488 } else {
487 // Partial Content without Content-Range. Assume that the server gave us 489 // Partial Content without Content-Range. Assume that the server gave us
488 // exactly what we asked for. This can happen even when the server 490 // exactly what we asked for. This can happen even when the server
489 // returns 200 -- the cache may return 206 in this case, but not modify 491 // returns 200 -- the cache may return 206 in this case, but not modify
490 // the headers. 492 // the headers.
491 read_start = offs; 493 read_start = attr.offs;
492 } 494 }
493 } 495 }
494 496
495 if (read_start < offs) { 497 if (read_start < attr.offs) {
496 // We aren't yet at the location where we want to start reading. Read into 498 // We aren't yet at the location where we want to start reading. Read into
497 // our dummy buffer until then. 499 // our dummy buffer until then.
498 size_t bytes_to_read = offs - read_start; 500 size_t bytes_to_read = attr.offs - read_start;
499 if (buffer_.size() < bytes_to_read) 501 if (buffer_.size() < bytes_to_read)
500 buffer_.resize(std::min(bytes_to_read, MAX_READ_BUFFER_SIZE)); 502 buffer_.resize(std::min(bytes_to_read, MAX_READ_BUFFER_SIZE));
501 503
502 while (bytes_to_read > 0) { 504 while (bytes_to_read > 0) {
503 int32_t bytes_read; 505 int32_t bytes_read;
504 Error error = 506 Error error =
505 DownloadToBuffer(loader, buffer_.data(), buffer_.size(), &bytes_read); 507 DownloadToBuffer(loader, buffer_.data(), buffer_.size(), &bytes_read);
506 if (error) 508 if (error)
507 return error; 509 return error;
508 510
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 bytes_to_read -= bytes_read; 544 bytes_to_read -= bytes_read;
543 out_buffer += bytes_read; 545 out_buffer += bytes_read;
544 } 546 }
545 547
546 *out_bytes = count; 548 *out_bytes = count;
547 return 0; 549 return 0;
548 } 550 }
549 551
550 } // namespace nacl_io 552 } // namespace nacl_io
551 553
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/nacl_io/mount_node_http.h ('k') | native_client_sdk/src/tests/nacl_io_test/example.dsc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698