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

Side by Side Diff: net/ocsp/nss_ocsp.cc

Issue 407093011: Allow URLRequests from one context to have different NetworkDelegates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix new tests Created 6 years, 4 months 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
« no previous file with comments | « mojo/services/network/url_loader_impl.cc ('k') | net/spdy/spdy_network_transaction_unittest.cc » ('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 "net/ocsp/nss_ocsp.h" 5 #include "net/ocsp/nss_ocsp.h"
6 6
7 #include <certt.h> 7 #include <certt.h>
8 #include <certdb.h> 8 #include <certdb.h>
9 #include <ocsp.h> 9 #include <ocsp.h>
10 #include <nspr.h> 10 #include <nspr.h>
11 #include <nss.h> 11 #include <nss.h>
12 #include <pthread.h> 12 #include <pthread.h>
13 #include <secerr.h> 13 #include <secerr.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 #include <string> 16 #include <string>
17 17
18 #include "base/basictypes.h" 18 #include "base/basictypes.h"
19 #include "base/callback.h" 19 #include "base/callback.h"
20 #include "base/compiler_specific.h" 20 #include "base/compiler_specific.h"
21 #include "base/lazy_instance.h" 21 #include "base/lazy_instance.h"
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/memory/scoped_ptr.h"
23 #include "base/message_loop/message_loop.h" 24 #include "base/message_loop/message_loop.h"
24 #include "base/metrics/histogram.h" 25 #include "base/metrics/histogram.h"
25 #include "base/stl_util.h" 26 #include "base/stl_util.h"
26 #include "base/strings/string_util.h" 27 #include "base/strings/string_util.h"
27 #include "base/strings/stringprintf.h" 28 #include "base/strings/stringprintf.h"
28 #include "base/synchronization/condition_variable.h" 29 #include "base/synchronization/condition_variable.h"
29 #include "base/synchronization/lock.h" 30 #include "base/synchronization/lock.h"
30 #include "base/threading/thread_checker.h" 31 #include "base/threading/thread_checker.h"
31 #include "base/time/time.h" 32 #include "base/time/time.h"
32 #include "net/base/host_port_pair.h" 33 #include "net/base/host_port_pair.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 class OCSPRequestSession 181 class OCSPRequestSession
181 : public base::RefCountedThreadSafe<OCSPRequestSession>, 182 : public base::RefCountedThreadSafe<OCSPRequestSession>,
182 public URLRequest::Delegate { 183 public URLRequest::Delegate {
183 public: 184 public:
184 OCSPRequestSession(const GURL& url, 185 OCSPRequestSession(const GURL& url,
185 const char* http_request_method, 186 const char* http_request_method,
186 base::TimeDelta timeout) 187 base::TimeDelta timeout)
187 : url_(url), 188 : url_(url),
188 http_request_method_(http_request_method), 189 http_request_method_(http_request_method),
189 timeout_(timeout), 190 timeout_(timeout),
190 request_(NULL),
191 buffer_(new IOBuffer(kRecvBufferSize)), 191 buffer_(new IOBuffer(kRecvBufferSize)),
192 response_code_(-1), 192 response_code_(-1),
193 cv_(&lock_), 193 cv_(&lock_),
194 io_loop_(NULL), 194 io_loop_(NULL),
195 finished_(false) {} 195 finished_(false) {}
196 196
197 void SetPostData(const char* http_data, PRUint32 http_data_len, 197 void SetPostData(const char* http_data, PRUint32 http_data_len,
198 const char* http_content_type) { 198 const char* http_content_type) {
199 // |upload_content_| should not be modified if |request_| is active. 199 // |upload_content_| should not be modified if |request_| is active.
200 DCHECK(!request_); 200 DCHECK(!request_);
(...skipping 10 matching lines...) Expand all
211 // At this point, it runs on worker thread. 211 // At this point, it runs on worker thread.
212 // |io_loop_| was initialized to be NULL in constructor, and 212 // |io_loop_| was initialized to be NULL in constructor, and
213 // set only in StartURLRequest, so no need to lock |lock_| here. 213 // set only in StartURLRequest, so no need to lock |lock_| here.
214 DCHECK(!io_loop_); 214 DCHECK(!io_loop_);
215 g_ocsp_io_loop.Get().PostTaskToIOLoop( 215 g_ocsp_io_loop.Get().PostTaskToIOLoop(
216 FROM_HERE, 216 FROM_HERE,
217 base::Bind(&OCSPRequestSession::StartURLRequest, this)); 217 base::Bind(&OCSPRequestSession::StartURLRequest, this));
218 } 218 }
219 219
220 bool Started() const { 220 bool Started() const {
221 return request_ != NULL; 221 return request_.get() != NULL;
222 } 222 }
223 223
224 void Cancel() { 224 void Cancel() {
225 // IO thread may set |io_loop_| to NULL, so protect by |lock_|. 225 // IO thread may set |io_loop_| to NULL, so protect by |lock_|.
226 base::AutoLock autolock(lock_); 226 base::AutoLock autolock(lock_);
227 CancelLocked(); 227 CancelLocked();
228 } 228 }
229 229
230 bool Finished() const { 230 bool Finished() const {
231 base::AutoLock autolock(lock_); 231 base::AutoLock autolock(lock_);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 279 }
280 280
281 const std::string& http_response_data() const { 281 const std::string& http_response_data() const {
282 DCHECK(finished_); 282 DCHECK(finished_);
283 return data_; 283 return data_;
284 } 284 }
285 285
286 virtual void OnReceivedRedirect(URLRequest* request, 286 virtual void OnReceivedRedirect(URLRequest* request,
287 const RedirectInfo& redirect_info, 287 const RedirectInfo& redirect_info,
288 bool* defer_redirect) OVERRIDE { 288 bool* defer_redirect) OVERRIDE {
289 DCHECK_EQ(request, request_); 289 DCHECK_EQ(request_.get(), request);
290 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 290 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
291 291
292 if (!redirect_info.new_url.SchemeIs("http")) { 292 if (!redirect_info.new_url.SchemeIs("http")) {
293 // Prevent redirects to non-HTTP schemes, including HTTPS. This matches 293 // Prevent redirects to non-HTTP schemes, including HTTPS. This matches
294 // the initial check in OCSPServerSession::CreateRequest(). 294 // the initial check in OCSPServerSession::CreateRequest().
295 CancelURLRequest(); 295 CancelURLRequest();
296 } 296 }
297 } 297 }
298 298
299 virtual void OnResponseStarted(URLRequest* request) OVERRIDE { 299 virtual void OnResponseStarted(URLRequest* request) OVERRIDE {
300 DCHECK_EQ(request, request_); 300 DCHECK_EQ(request_.get(), request);
301 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 301 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
302 302
303 int bytes_read = 0; 303 int bytes_read = 0;
304 if (request->status().is_success()) { 304 if (request->status().is_success()) {
305 response_code_ = request_->GetResponseCode(); 305 response_code_ = request_->GetResponseCode();
306 response_headers_ = request_->response_headers(); 306 response_headers_ = request_->response_headers();
307 response_headers_->GetMimeType(&response_content_type_); 307 response_headers_->GetMimeType(&response_content_type_);
308 request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read); 308 request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read);
309 } 309 }
310 OnReadCompleted(request_, bytes_read); 310 OnReadCompleted(request_.get(), bytes_read);
311 } 311 }
312 312
313 virtual void OnReadCompleted(URLRequest* request, 313 virtual void OnReadCompleted(URLRequest* request,
314 int bytes_read) OVERRIDE { 314 int bytes_read) OVERRIDE {
315 DCHECK_EQ(request, request_); 315 DCHECK_EQ(request_.get(), request);
316 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 316 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
317 317
318 do { 318 do {
319 if (!request_->status().is_success() || bytes_read <= 0) 319 if (!request_->status().is_success() || bytes_read <= 0)
320 break; 320 break;
321 data_.append(buffer_->data(), bytes_read); 321 data_.append(buffer_->data(), bytes_read);
322 } while (request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read)); 322 } while (request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read));
323 323
324 if (!request_->status().is_io_pending()) { 324 if (!request_->status().is_io_pending()) {
325 delete request_; 325 request_.reset();
326 request_ = NULL;
327 g_ocsp_io_loop.Get().RemoveRequest(this); 326 g_ocsp_io_loop.Get().RemoveRequest(this);
328 { 327 {
329 base::AutoLock autolock(lock_); 328 base::AutoLock autolock(lock_);
330 finished_ = true; 329 finished_ = true;
331 io_loop_ = NULL; 330 io_loop_ = NULL;
332 } 331 }
333 cv_.Signal(); 332 cv_.Signal();
334 Release(); // Balanced with StartURLRequest(). 333 Release(); // Balanced with StartURLRequest().
335 } 334 }
336 } 335 }
337 336
338 // Must be called on the IO loop thread. 337 // Must be called on the IO loop thread.
339 void CancelURLRequest() { 338 void CancelURLRequest() {
340 #ifndef NDEBUG 339 #ifndef NDEBUG
341 { 340 {
342 base::AutoLock autolock(lock_); 341 base::AutoLock autolock(lock_);
343 if (io_loop_) 342 if (io_loop_)
344 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 343 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
345 } 344 }
346 #endif 345 #endif
347 if (request_) { 346 if (request_) {
348 request_->Cancel(); 347 request_.reset();
349 delete request_;
350 request_ = NULL;
351 g_ocsp_io_loop.Get().RemoveRequest(this); 348 g_ocsp_io_loop.Get().RemoveRequest(this);
352 { 349 {
353 base::AutoLock autolock(lock_); 350 base::AutoLock autolock(lock_);
354 finished_ = true; 351 finished_ = true;
355 io_loop_ = NULL; 352 io_loop_ = NULL;
356 } 353 }
357 cv_.Signal(); 354 cv_.Signal();
358 Release(); // Balanced with StartURLRequest(). 355 Release(); // Balanced with StartURLRequest().
359 } 356 }
360 } 357 }
(...skipping 30 matching lines...) Expand all
391 if (url_request_context == NULL) 388 if (url_request_context == NULL)
392 return; 389 return;
393 390
394 { 391 {
395 base::AutoLock autolock(lock_); 392 base::AutoLock autolock(lock_);
396 DCHECK(!io_loop_); 393 DCHECK(!io_loop_);
397 io_loop_ = base::MessageLoopForIO::current(); 394 io_loop_ = base::MessageLoopForIO::current();
398 g_ocsp_io_loop.Get().AddRequest(this); 395 g_ocsp_io_loop.Get().AddRequest(this);
399 } 396 }
400 397
401 request_ = 398 request_ = url_request_context->CreateRequest(
402 new URLRequest(url_, DEFAULT_PRIORITY, this, url_request_context); 399 url_, DEFAULT_PRIORITY, this, NULL);
403 // To meet the privacy requirements of incognito mode. 400 // To meet the privacy requirements of incognito mode.
404 request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES | 401 request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES |
405 LOAD_DO_NOT_SEND_COOKIES); 402 LOAD_DO_NOT_SEND_COOKIES);
406 403
407 if (http_request_method_ == "POST") { 404 if (http_request_method_ == "POST") {
408 DCHECK(!upload_content_.empty()); 405 DCHECK(!upload_content_.empty());
409 DCHECK(!upload_content_type_.empty()); 406 DCHECK(!upload_content_type_.empty());
410 407
411 request_->set_method("POST"); 408 request_->set_method("POST");
412 extra_request_headers_.SetHeader( 409 extra_request_headers_.SetHeader(
413 HttpRequestHeaders::kContentType, upload_content_type_); 410 HttpRequestHeaders::kContentType, upload_content_type_);
414 411
415 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader( 412 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
416 upload_content_.data(), upload_content_.size())); 413 upload_content_.data(), upload_content_.size()));
417 request_->set_upload(make_scoped_ptr( 414 request_->set_upload(make_scoped_ptr(
418 UploadDataStream::CreateWithReader(reader.Pass(), 0))); 415 UploadDataStream::CreateWithReader(reader.Pass(), 0)));
419 } 416 }
420 if (!extra_request_headers_.IsEmpty()) 417 if (!extra_request_headers_.IsEmpty())
421 request_->SetExtraRequestHeaders(extra_request_headers_); 418 request_->SetExtraRequestHeaders(extra_request_headers_);
422 419
423 request_->Start(); 420 request_->Start();
424 AddRef(); // Release after |request_| deleted. 421 AddRef(); // Release after |request_| deleted.
425 } 422 }
426 423
427 GURL url_; // The URL we eventually wound up at 424 GURL url_; // The URL we eventually wound up at
428 std::string http_request_method_; 425 std::string http_request_method_;
429 base::TimeDelta timeout_; // The timeout for OCSP 426 base::TimeDelta timeout_; // The timeout for OCSP
430 URLRequest* request_; // The actual request this wraps 427 scoped_ptr<URLRequest> request_; // The actual request this wraps
431 scoped_refptr<IOBuffer> buffer_; // Read buffer 428 scoped_refptr<IOBuffer> buffer_; // Read buffer
432 HttpRequestHeaders extra_request_headers_; 429 HttpRequestHeaders extra_request_headers_;
433 430
434 // HTTP POST payload. |request_| reads bytes from this. 431 // HTTP POST payload. |request_| reads bytes from this.
435 std::string upload_content_; 432 std::string upload_content_;
436 std::string upload_content_type_; // MIME type of POST payload 433 std::string upload_content_type_; // MIME type of POST payload
437 434
438 int response_code_; // HTTP status code for the request 435 int response_code_; // HTTP status code for the request
439 std::string response_content_type_; 436 std::string response_content_type_;
440 scoped_refptr<HttpResponseHeaders> response_headers_; 437 scoped_refptr<HttpResponseHeaders> response_headers_;
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) { 968 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) {
972 pthread_mutex_lock(&g_request_context_lock); 969 pthread_mutex_lock(&g_request_context_lock);
973 if (request_context) { 970 if (request_context) {
974 DCHECK(!g_request_context); 971 DCHECK(!g_request_context);
975 } 972 }
976 g_request_context = request_context; 973 g_request_context = request_context;
977 pthread_mutex_unlock(&g_request_context_lock); 974 pthread_mutex_unlock(&g_request_context_lock);
978 } 975 }
979 976
980 } // namespace net 977 } // namespace net
OLDNEW
« no previous file with comments | « mojo/services/network/url_loader_impl.cc ('k') | net/spdy/spdy_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698