OLD | NEW |
1 // Copyright (c) 20010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 20010 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 "webkit/blob/blob_url_request_job.h" | 5 #include "webkit/blob/blob_url_request_job.h" |
6 | 6 |
| 7 #include "base/compiler_specific.h" |
7 #include "base/file_path.h" | 8 #include "base/file_path.h" |
8 #include "base/file_util.h" | 9 #include "base/file_util.h" |
9 #include "base/file_util_proxy.h" | 10 #include "base/file_util_proxy.h" |
10 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
11 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
12 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
13 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
14 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
15 #include "net/http/http_request_headers.h" | 16 #include "net/http/http_request_headers.h" |
16 #include "net/http/http_response_headers.h" | 17 #include "net/http/http_response_headers.h" |
17 #include "net/http/http_response_info.h" | 18 #include "net/http/http_response_info.h" |
18 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
19 #include "net/url_request/url_request.h" | 20 #include "net/url_request/url_request.h" |
20 #include "net/url_request/url_request_error_job.h" | 21 #include "net/url_request/url_request_error_job.h" |
21 #include "net/url_request/url_request_status.h" | 22 #include "net/url_request/url_request_status.h" |
22 | 23 |
23 namespace webkit_blob { | 24 namespace webkit_blob { |
24 | 25 |
25 static const int kHTTPOk = 200; | 26 static const int kHTTPOk = 200; |
26 static const int kHTTPPartialContent = 206; | 27 static const int kHTTPPartialContent = 206; |
27 static const int kHTTPNotAllowed = 403; | 28 static const int kHTTPNotAllowed = 403; |
28 static const int kHTTPNotFound = 404; | 29 static const int kHTTPNotFound = 404; |
29 static const int kHTTPMethodNotAllow = 405; | 30 static const int kHTTPMethodNotAllow = 405; |
30 static const int kHTTPRequestedRangeNotSatisfiable = 416; | 31 static const int kHTTPRequestedRangeNotSatisfiable = 416; |
31 static const int kHTTPInternalError = 500; | 32 static const int kHTTPInternalError = 500; |
32 | 33 |
33 static const char* kHTTPOKText = "OK"; | 34 static const char kHTTPOKText[] = "OK"; |
34 static const char* kHTTPPartialContentText = "Partial Content"; | 35 static const char kHTTPPartialContentText[] = "Partial Content"; |
35 static const char* kHTTPNotAllowedText = "Not Allowed"; | 36 static const char kHTTPNotAllowedText[] = "Not Allowed"; |
36 static const char* kHTTPNotFoundText = "Not Found"; | 37 static const char kHTTPNotFoundText[] = "Not Found"; |
37 static const char* kHTTPMethodNotAllowText = "Method Not Allowed"; | 38 static const char kHTTPMethodNotAllowText[] = "Method Not Allowed"; |
38 static const char* kHTTPRequestedRangeNotSatisfiableText = | 39 static const char kHTTPRequestedRangeNotSatisfiableText[] = |
39 "Requested Range Not Satisfiable"; | 40 "Requested Range Not Satisfiable"; |
40 static const char* kHTTPInternalErrorText = "Internal Server Error"; | 41 static const char kHTTPInternalErrorText[] = "Internal Server Error"; |
41 | 42 |
42 BlobURLRequestJob::BlobURLRequestJob( | 43 BlobURLRequestJob::BlobURLRequestJob( |
43 net::URLRequest* request, | 44 net::URLRequest* request, |
44 BlobData* blob_data, | 45 BlobData* blob_data, |
45 base::MessageLoopProxy* file_thread_proxy) | 46 base::MessageLoopProxy* file_thread_proxy) |
46 : URLRequestJob(request), | 47 : URLRequestJob(request), |
47 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 48 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
48 blob_data_(blob_data), | 49 blob_data_(blob_data), |
49 file_thread_proxy_(file_thread_proxy), | 50 file_thread_proxy_(file_thread_proxy), |
50 ALLOW_THIS_IN_INITIALIZER_LIST( | 51 ALLOW_THIS_IN_INITIALIZER_LIST( |
51 io_callback_(this, &BlobURLRequestJob::DidRead)), | 52 io_callback_(this, &BlobURLRequestJob::DidRead)), |
52 item_index_(0), | 53 item_index_(0), |
53 total_size_(0), | 54 total_size_(0), |
54 current_item_offset_(0), | 55 current_item_offset_(0), |
55 remaining_bytes_(0), | 56 remaining_bytes_(0), |
56 read_buf_offset_(0), | 57 read_buf_offset_(0), |
57 read_buf_size_(0), | 58 read_buf_size_(0), |
58 read_buf_remaining_bytes_(0), | 59 read_buf_remaining_bytes_(0), |
59 error_(false), | 60 error_(false), |
60 headers_set_(false), | 61 headers_set_(false), |
61 byte_range_set_(false) { | 62 byte_range_set_(false), |
| 63 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
62 } | 64 } |
63 | 65 |
64 BlobURLRequestJob::~BlobURLRequestJob() { | 66 BlobURLRequestJob::~BlobURLRequestJob() { |
65 } | 67 } |
66 | 68 |
67 void BlobURLRequestJob::Start() { | 69 void BlobURLRequestJob::Start() { |
68 // Continue asynchronously. | 70 // Continue asynchronously. |
69 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 71 MessageLoop::current()->PostTask( |
70 this, &BlobURLRequestJob::DidStart)); | 72 FROM_HERE, |
| 73 method_factory_.NewRunnableMethod(&BlobURLRequestJob::DidStart)); |
71 } | 74 } |
72 | 75 |
73 void BlobURLRequestJob::DidStart() { | 76 void BlobURLRequestJob::DidStart() { |
74 // We only support GET request per the spec. | 77 // We only support GET request per the spec. |
75 if (request()->method() != "GET") { | 78 if (request()->method() != "GET") { |
76 NotifyFailure(net::ERR_METHOD_NOT_SUPPORTED); | 79 NotifyFailure(net::ERR_METHOD_NOT_SUPPORTED); |
77 return; | 80 return; |
78 } | 81 } |
79 | 82 |
80 // If the blob data is not present, bail out. | 83 // If the blob data is not present, bail out. |
81 if (!blob_data_) { | 84 if (!blob_data_) { |
82 NotifyFailure(net::ERR_FILE_NOT_FOUND); | 85 NotifyFailure(net::ERR_FILE_NOT_FOUND); |
83 return; | 86 return; |
84 } | 87 } |
85 | 88 |
86 CountSize(); | 89 CountSize(); |
87 } | 90 } |
88 | 91 |
89 void BlobURLRequestJob::Kill() { | 92 void BlobURLRequestJob::Kill() { |
90 stream_.Close(); | 93 stream_.Close(); |
91 | 94 |
92 URLRequestJob::Kill(); | 95 URLRequestJob::Kill(); |
| 96 callback_factory_.RevokeAll(); |
| 97 method_factory_.RevokeAll(); |
93 } | 98 } |
94 | 99 |
95 void BlobURLRequestJob::ResolveFile(const FilePath& file_path) { | 100 void BlobURLRequestJob::ResolveFile(const FilePath& file_path) { |
96 // If the file thread proxy is provided, we can use it get the file info. | 101 // If the file thread proxy is provided, we can use it get the file info. |
97 if (file_thread_proxy_) { | 102 if (file_thread_proxy_) { |
98 base::FileUtilProxy::GetFileInfo( | 103 base::FileUtilProxy::GetFileInfo( |
99 file_thread_proxy_, | 104 file_thread_proxy_, |
100 file_path, | 105 file_path, |
101 callback_factory_.NewCallback(&BlobURLRequestJob::DidResolve)); | 106 callback_factory_.NewCallback(&BlobURLRequestJob::DidResolve)); |
102 return; | 107 return; |
103 } | 108 } |
104 | 109 |
105 // Otherwise, we use current thread, i.e. IO thread, as this is the case when | 110 // Otherwise, we use current thread, i.e. IO thread, as this is the case when |
106 // we run the unittest or test shell. | 111 // we run the unittest or test shell. |
107 // TODO(jianli): Consider using the proxy of current thread. | 112 // TODO(jianli): Consider using the proxy of current thread. |
108 base::PlatformFileInfo file_info; | 113 base::PlatformFileInfo file_info; |
109 bool exists = file_util::GetFileInfo(file_path, &file_info); | 114 bool exists = file_util::GetFileInfo(file_path, &file_info); |
110 | 115 |
111 // Continue asynchronously. | 116 // Continue asynchronously. |
112 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 117 MessageLoop::current()->PostTask( |
113 this, &BlobURLRequestJob::DidResolve, | 118 FROM_HERE, |
114 (exists ? base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_NOT_FOUND), | 119 method_factory_.NewRunnableMethod( |
115 file_info)); | 120 &BlobURLRequestJob::DidResolve, |
| 121 exists ? base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_NOT_FOUND, |
| 122 file_info)); |
116 } | 123 } |
117 | 124 |
118 void BlobURLRequestJob::DidResolve(base::PlatformFileError rv, | 125 void BlobURLRequestJob::DidResolve(base::PlatformFileError rv, |
119 const base::PlatformFileInfo& file_info) { | 126 const base::PlatformFileInfo& file_info) { |
120 // We may have been orphaned... | |
121 if (!request_) | |
122 return; | |
123 | |
124 // If an error occured, bail out. | 127 // If an error occured, bail out. |
125 if (rv == base::PLATFORM_FILE_ERROR_NOT_FOUND) { | 128 if (rv == base::PLATFORM_FILE_ERROR_NOT_FOUND) { |
126 NotifyFailure(net::ERR_FILE_NOT_FOUND); | 129 NotifyFailure(net::ERR_FILE_NOT_FOUND); |
127 return; | 130 return; |
128 } else if (rv != base::PLATFORM_FILE_OK) { | 131 } else if (rv != base::PLATFORM_FILE_OK) { |
129 NotifyFailure(net::ERR_FAILED); | 132 NotifyFailure(net::ERR_FAILED); |
130 return; | 133 return; |
131 } | 134 } |
132 | 135 |
133 // Validate the expected modification time. | 136 // Validate the expected modification time. |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 // We don't support multiple range requests in one single URL request, | 535 // We don't support multiple range requests in one single URL request, |
533 // because we need to do multipart encoding here. | 536 // because we need to do multipart encoding here. |
534 // TODO(jianli): Support multipart byte range requests. | 537 // TODO(jianli): Support multipart byte range requests. |
535 NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); | 538 NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); |
536 } | 539 } |
537 } | 540 } |
538 } | 541 } |
539 } | 542 } |
540 | 543 |
541 } // namespace webkit_blob | 544 } // namespace webkit_blob |
OLD | NEW |