OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <vector> | 5 #include <vector> |
6 | 6 |
7 #include "net/url_request/url_request_test_job.h" | 7 #include "net/url_request/url_request_test_job.h" |
8 | 8 |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 std::string URLRequestTestJob::test_data_1() { | 35 std::string URLRequestTestJob::test_data_1() { |
36 return std::string("<html><title>Test One</title></html>"); | 36 return std::string("<html><title>Test One</title></html>"); |
37 } | 37 } |
38 std::string URLRequestTestJob::test_data_2() { | 38 std::string URLRequestTestJob::test_data_2() { |
39 return std::string("<html><title>Test Two Two</title></html>"); | 39 return std::string("<html><title>Test Two Two</title></html>"); |
40 } | 40 } |
41 std::string URLRequestTestJob::test_data_3() { | 41 std::string URLRequestTestJob::test_data_3() { |
42 return std::string("<html><title>Test Three Three Three</title></html>"); | 42 return std::string("<html><title>Test Three Three Three</title></html>"); |
43 } | 43 } |
44 | 44 |
| 45 // static getter for simple response headers |
| 46 std::string URLRequestTestJob::test_headers() { |
| 47 const char headers[] = |
| 48 "HTTP/1.1 200 OK\0" |
| 49 "Content-type: text/html\0" |
| 50 "\0"; |
| 51 return std::string(headers, arraysize(headers)); |
| 52 } |
| 53 |
| 54 // static getter for redirect response headers |
| 55 std::string URLRequestTestJob::test_redirect_headers() { |
| 56 const char headers[] = |
| 57 "HTTP/1.1 302 MOVED\0" |
| 58 "Location: somewhere\0" |
| 59 "\0"; |
| 60 return std::string(headers, arraysize(headers)); |
| 61 } |
| 62 |
| 63 // static getter for error response headers |
| 64 std::string URLRequestTestJob::test_error_headers() { |
| 65 const char headers[] = |
| 66 "HTTP/1.1 500 BOO HOO\0" |
| 67 "\0"; |
| 68 return std::string(headers, arraysize(headers)); |
| 69 } |
| 70 |
45 // static | 71 // static |
46 URLRequestJob* URLRequestTestJob::Factory(URLRequest* request, | 72 URLRequestJob* URLRequestTestJob::Factory(URLRequest* request, |
47 const std::string& scheme) { | 73 const std::string& scheme) { |
48 return new URLRequestTestJob(request); | 74 return new URLRequestTestJob(request); |
49 } | 75 } |
50 | 76 |
51 URLRequestTestJob::URLRequestTestJob(URLRequest* request) | 77 URLRequestTestJob::URLRequestTestJob(URLRequest* request) |
52 : URLRequestJob(request), | 78 : URLRequestJob(request), |
| 79 auto_advance_(false), |
53 stage_(WAITING), | 80 stage_(WAITING), |
54 offset_(0), | 81 offset_(0), |
55 async_buf_(NULL), | 82 async_buf_(NULL), |
56 async_buf_size_(0) { | 83 async_buf_size_(0) { |
57 } | 84 } |
58 | 85 |
59 // Force the response to set a reasonable MIME type | 86 URLRequestTestJob::URLRequestTestJob(URLRequest* request, bool auto_advance) |
| 87 : URLRequestJob(request), |
| 88 auto_advance_(auto_advance), |
| 89 stage_(WAITING), |
| 90 offset_(0), |
| 91 async_buf_(NULL), |
| 92 async_buf_size_(0) { |
| 93 } |
| 94 |
| 95 URLRequestTestJob::URLRequestTestJob(URLRequest* request, |
| 96 const std::string& response_headers, |
| 97 const std::string& response_data, |
| 98 bool auto_advance) |
| 99 : URLRequestJob(request), |
| 100 auto_advance_(auto_advance), |
| 101 stage_(WAITING), |
| 102 response_headers_(new net::HttpResponseHeaders(response_headers)), |
| 103 response_data_(response_data), |
| 104 offset_(0), |
| 105 async_buf_(NULL), |
| 106 async_buf_size_(0) { |
| 107 } |
| 108 |
| 109 URLRequestTestJob::~URLRequestTestJob() { |
| 110 } |
| 111 |
60 bool URLRequestTestJob::GetMimeType(std::string* mime_type) const { | 112 bool URLRequestTestJob::GetMimeType(std::string* mime_type) const { |
61 DCHECK(mime_type); | 113 DCHECK(mime_type); |
62 *mime_type = "text/html"; | 114 if (!response_headers_) |
63 return true; | 115 return false; |
| 116 return response_headers_->GetMimeType(mime_type); |
64 } | 117 } |
65 | 118 |
66 void URLRequestTestJob::Start() { | 119 void URLRequestTestJob::Start() { |
67 // Start reading asynchronously so that all error reporting and data | 120 // Start reading asynchronously so that all error reporting and data |
68 // callbacks happen as they would for network requests. | 121 // callbacks happen as they would for network requests. |
69 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 122 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
70 this, &URLRequestTestJob::StartAsync)); | 123 this, &URLRequestTestJob::StartAsync)); |
71 } | 124 } |
72 | 125 |
73 void URLRequestTestJob::StartAsync() { | 126 void URLRequestTestJob::StartAsync() { |
74 if (request_->url().spec() == test_url_1().spec()) { | 127 if (!response_headers_) { |
75 data_ = test_data_1(); | 128 response_headers_ = new net::HttpResponseHeaders(test_headers()); |
76 stage_ = DATA_AVAILABLE; // Simulate a synchronous response for this one. | 129 if (request_->url().spec() == test_url_1().spec()) { |
77 } else if (request_->url().spec() == test_url_2().spec()) { | 130 response_data_ = test_data_1(); |
78 data_ = test_data_2(); | 131 stage_ = DATA_AVAILABLE; // Simulate a synchronous response for this one. |
79 } else if (request_->url().spec() == test_url_3().spec()) { | 132 } else if (request_->url().spec() == test_url_2().spec()) { |
80 data_ = test_data_3(); | 133 response_data_ = test_data_2(); |
81 } else { | 134 } else if (request_->url().spec() == test_url_3().spec()) { |
82 // unexpected url, return error | 135 response_data_ = test_data_3(); |
83 // FIXME(brettw) we may want to use WININET errors or have some more types | 136 } else { |
84 // of errors | 137 // unexpected url, return error |
85 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, | 138 // FIXME(brettw) we may want to use WININET errors or have some more types |
86 net::ERR_INVALID_URL)); | 139 // of errors |
87 // FIXME(brettw): this should emulate a network error, and not just fail | 140 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, |
88 // initiating a connection | 141 net::ERR_INVALID_URL)); |
89 return; | 142 // FIXME(brettw): this should emulate a network error, and not just fail |
| 143 // initiating a connection |
| 144 return; |
| 145 } |
90 } | 146 } |
91 | 147 |
92 pending_jobs.push_back(scoped_refptr<URLRequestTestJob>(this)); | 148 AdvanceJob(); |
93 | 149 |
94 this->NotifyHeadersComplete(); | 150 this->NotifyHeadersComplete(); |
95 } | 151 } |
96 | 152 |
97 bool URLRequestTestJob::ReadRawData(net::IOBuffer* buf, int buf_size, | 153 bool URLRequestTestJob::ReadRawData(net::IOBuffer* buf, int buf_size, |
98 int *bytes_read) { | 154 int *bytes_read) { |
99 if (stage_ == WAITING) { | 155 if (stage_ == WAITING) { |
100 async_buf_ = buf; | 156 async_buf_ = buf; |
101 async_buf_size_ = buf_size; | 157 async_buf_size_ = buf_size; |
102 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 158 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
103 return false; | 159 return false; |
104 } | 160 } |
105 | 161 |
106 DCHECK(bytes_read); | 162 DCHECK(bytes_read); |
107 *bytes_read = 0; | 163 *bytes_read = 0; |
108 | 164 |
109 if (offset_ >= static_cast<int>(data_.length())) { | 165 if (offset_ >= static_cast<int>(response_data_.length())) { |
110 return true; // done reading | 166 return true; // done reading |
111 } | 167 } |
112 | 168 |
113 int to_read = buf_size; | 169 int to_read = buf_size; |
114 if (to_read + offset_ > static_cast<int>(data_.length())) | 170 if (to_read + offset_ > static_cast<int>(response_data_.length())) |
115 to_read = static_cast<int>(data_.length()) - offset_; | 171 to_read = static_cast<int>(response_data_.length()) - offset_; |
116 | 172 |
117 memcpy(buf->data(), &data_.c_str()[offset_], to_read); | 173 memcpy(buf->data(), &response_data_.c_str()[offset_], to_read); |
118 offset_ += to_read; | 174 offset_ += to_read; |
119 | 175 |
120 *bytes_read = to_read; | 176 *bytes_read = to_read; |
121 return true; | 177 return true; |
122 } | 178 } |
123 | 179 |
124 void URLRequestTestJob::GetResponseInfo(net::HttpResponseInfo* info) { | 180 void URLRequestTestJob::GetResponseInfo(net::HttpResponseInfo* info) { |
125 const std::string kResponseHeaders = StringPrintf( | 181 if (response_headers_) |
126 "HTTP/1.1 200 OK%c" | 182 info->headers = response_headers_; |
127 "Content-type: text/html%c" | |
128 "%c", 0, 0, 0); | |
129 info->headers = new net::HttpResponseHeaders(kResponseHeaders); | |
130 } | 183 } |
131 | 184 |
| 185 bool URLRequestTestJob::IsRedirectResponse(GURL* location, |
| 186 int* http_status_code) { |
| 187 if (!response_headers_) |
| 188 return false; |
| 189 |
| 190 std::string value; |
| 191 if (!response_headers_->IsRedirect(&value)) |
| 192 return false; |
| 193 |
| 194 *location = request_->url().Resolve(value); |
| 195 *http_status_code = response_headers_->response_code(); |
| 196 return true; |
| 197 } |
| 198 |
| 199 |
132 void URLRequestTestJob::Kill() { | 200 void URLRequestTestJob::Kill() { |
133 stage_ = DONE; | 201 stage_ = DONE; |
134 URLRequestJob::Kill(); | 202 URLRequestJob::Kill(); |
135 } | 203 } |
136 | 204 |
137 bool URLRequestTestJob::ProcessNextOperation() { | 205 void URLRequestTestJob::ProcessNextOperation() { |
138 switch (stage_) { | 206 switch (stage_) { |
139 case WAITING: | 207 case WAITING: |
140 stage_ = DATA_AVAILABLE; | 208 stage_ = DATA_AVAILABLE; |
141 // OK if ReadRawData wasn't called yet. | 209 // OK if ReadRawData wasn't called yet. |
142 if (async_buf_) { | 210 if (async_buf_) { |
143 int bytes_read; | 211 int bytes_read; |
144 if (!ReadRawData(async_buf_, async_buf_size_, &bytes_read)) | 212 if (!ReadRawData(async_buf_, async_buf_size_, &bytes_read)) |
145 NOTREACHED() << "This should not return false in DATA_AVAILABLE."; | 213 NOTREACHED() << "This should not return false in DATA_AVAILABLE."; |
146 SetStatus(URLRequestStatus()); // clear the io pending flag | 214 SetStatus(URLRequestStatus()); // clear the io pending flag |
147 NotifyReadComplete(bytes_read); | 215 NotifyReadComplete(bytes_read); |
148 } | 216 } |
149 break; | 217 break; |
150 case DATA_AVAILABLE: | 218 case DATA_AVAILABLE: |
151 stage_ = ALL_DATA; // done sending data | 219 stage_ = ALL_DATA; // done sending data |
152 break; | 220 break; |
153 case ALL_DATA: | 221 case ALL_DATA: |
154 stage_ = DONE; | 222 stage_ = DONE; |
155 return false; | 223 return; |
156 case DONE: | 224 case DONE: |
157 return false; | 225 return; |
158 default: | 226 default: |
159 NOTREACHED() << "Invalid stage"; | 227 NOTREACHED() << "Invalid stage"; |
160 return false; | 228 return; |
161 } | 229 } |
162 return true; | 230 AdvanceJob(); |
| 231 } |
| 232 |
| 233 void URLRequestTestJob::AdvanceJob() { |
| 234 if (auto_advance_) { |
| 235 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
| 236 this, &URLRequestTestJob::ProcessNextOperation)); |
| 237 return; |
| 238 } |
| 239 pending_jobs.push_back(scoped_refptr<URLRequestTestJob>(this)); |
163 } | 240 } |
164 | 241 |
165 // static | 242 // static |
166 bool URLRequestTestJob::ProcessOnePendingMessage() { | 243 bool URLRequestTestJob::ProcessOnePendingMessage() { |
167 if (pending_jobs.empty()) | 244 if (pending_jobs.empty()) |
168 return false; | 245 return false; |
169 | 246 |
170 scoped_refptr<URLRequestTestJob> next_job(pending_jobs[0]); | 247 scoped_refptr<URLRequestTestJob> next_job(pending_jobs[0]); |
171 pending_jobs.erase(pending_jobs.begin()); | 248 pending_jobs.erase(pending_jobs.begin()); |
172 | 249 |
173 if (next_job->ProcessNextOperation()) | 250 DCHECK(!next_job->auto_advance()); // auto_advance jobs should be in this q |
174 pending_jobs.push_back(next_job); | 251 next_job->ProcessNextOperation(); |
175 | |
176 return true; | 252 return true; |
177 } | 253 } |
OLD | NEW |