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

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: And fix more stuff... Created 6 years, 5 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
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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 class OCSPRequestSession 180 class OCSPRequestSession
180 : public base::RefCountedThreadSafe<OCSPRequestSession>, 181 : public base::RefCountedThreadSafe<OCSPRequestSession>,
181 public URLRequest::Delegate { 182 public URLRequest::Delegate {
182 public: 183 public:
183 OCSPRequestSession(const GURL& url, 184 OCSPRequestSession(const GURL& url,
184 const char* http_request_method, 185 const char* http_request_method,
185 base::TimeDelta timeout) 186 base::TimeDelta timeout)
186 : url_(url), 187 : url_(url),
187 http_request_method_(http_request_method), 188 http_request_method_(http_request_method),
188 timeout_(timeout), 189 timeout_(timeout),
189 request_(NULL),
190 buffer_(new IOBuffer(kRecvBufferSize)), 190 buffer_(new IOBuffer(kRecvBufferSize)),
191 response_code_(-1), 191 response_code_(-1),
192 cv_(&lock_), 192 cv_(&lock_),
193 io_loop_(NULL), 193 io_loop_(NULL),
194 finished_(false) {} 194 finished_(false) {}
195 195
196 void SetPostData(const char* http_data, PRUint32 http_data_len, 196 void SetPostData(const char* http_data, PRUint32 http_data_len,
197 const char* http_content_type) { 197 const char* http_content_type) {
198 // |upload_content_| should not be modified if |request_| is active. 198 // |upload_content_| should not be modified if |request_| is active.
199 DCHECK(!request_); 199 DCHECK(!request_);
(...skipping 10 matching lines...) Expand all
210 // At this point, it runs on worker thread. 210 // At this point, it runs on worker thread.
211 // |io_loop_| was initialized to be NULL in constructor, and 211 // |io_loop_| was initialized to be NULL in constructor, and
212 // set only in StartURLRequest, so no need to lock |lock_| here. 212 // set only in StartURLRequest, so no need to lock |lock_| here.
213 DCHECK(!io_loop_); 213 DCHECK(!io_loop_);
214 g_ocsp_io_loop.Get().PostTaskToIOLoop( 214 g_ocsp_io_loop.Get().PostTaskToIOLoop(
215 FROM_HERE, 215 FROM_HERE,
216 base::Bind(&OCSPRequestSession::StartURLRequest, this)); 216 base::Bind(&OCSPRequestSession::StartURLRequest, this));
217 } 217 }
218 218
219 bool Started() const { 219 bool Started() const {
220 return request_ != NULL; 220 return request_.get() != NULL;
221 } 221 }
222 222
223 void Cancel() { 223 void Cancel() {
224 // IO thread may set |io_loop_| to NULL, so protect by |lock_|. 224 // IO thread may set |io_loop_| to NULL, so protect by |lock_|.
225 base::AutoLock autolock(lock_); 225 base::AutoLock autolock(lock_);
226 CancelLocked(); 226 CancelLocked();
227 } 227 }
228 228
229 bool Finished() const { 229 bool Finished() const {
230 base::AutoLock autolock(lock_); 230 base::AutoLock autolock(lock_);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 278 }
279 279
280 const std::string& http_response_data() const { 280 const std::string& http_response_data() const {
281 DCHECK(finished_); 281 DCHECK(finished_);
282 return data_; 282 return data_;
283 } 283 }
284 284
285 virtual void OnReceivedRedirect(URLRequest* request, 285 virtual void OnReceivedRedirect(URLRequest* request,
286 const GURL& new_url, 286 const GURL& new_url,
287 bool* defer_redirect) OVERRIDE { 287 bool* defer_redirect) OVERRIDE {
288 DCHECK_EQ(request, request_); 288 DCHECK_EQ(request_.get(), request);
289 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 289 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
290 290
291 if (!new_url.SchemeIs("http")) { 291 if (!new_url.SchemeIs("http")) {
292 // Prevent redirects to non-HTTP schemes, including HTTPS. This matches 292 // Prevent redirects to non-HTTP schemes, including HTTPS. This matches
293 // the initial check in OCSPServerSession::CreateRequest(). 293 // the initial check in OCSPServerSession::CreateRequest().
294 CancelURLRequest(); 294 CancelURLRequest();
295 } 295 }
296 } 296 }
297 297
298 virtual void OnResponseStarted(URLRequest* request) OVERRIDE { 298 virtual void OnResponseStarted(URLRequest* request) OVERRIDE {
299 DCHECK_EQ(request, request_); 299 DCHECK_EQ(request_.get(), request);
300 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 300 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
301 301
302 int bytes_read = 0; 302 int bytes_read = 0;
303 if (request->status().is_success()) { 303 if (request->status().is_success()) {
304 response_code_ = request_->GetResponseCode(); 304 response_code_ = request_->GetResponseCode();
305 response_headers_ = request_->response_headers(); 305 response_headers_ = request_->response_headers();
306 response_headers_->GetMimeType(&response_content_type_); 306 response_headers_->GetMimeType(&response_content_type_);
307 request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read); 307 request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read);
308 } 308 }
309 OnReadCompleted(request_, bytes_read); 309 OnReadCompleted(request_.get(), bytes_read);
310 } 310 }
311 311
312 virtual void OnReadCompleted(URLRequest* request, 312 virtual void OnReadCompleted(URLRequest* request,
313 int bytes_read) OVERRIDE { 313 int bytes_read) OVERRIDE {
314 DCHECK_EQ(request, request_); 314 DCHECK_EQ(request_.get(), request);
315 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 315 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
316 316
317 do { 317 do {
318 if (!request_->status().is_success() || bytes_read <= 0) 318 if (!request_->status().is_success() || bytes_read <= 0)
319 break; 319 break;
320 data_.append(buffer_->data(), bytes_read); 320 data_.append(buffer_->data(), bytes_read);
321 } while (request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read)); 321 } while (request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read));
322 322
323 if (!request_->status().is_io_pending()) { 323 if (!request_->status().is_io_pending()) {
324 delete request_; 324 request_.reset();
325 request_ = NULL;
326 g_ocsp_io_loop.Get().RemoveRequest(this); 325 g_ocsp_io_loop.Get().RemoveRequest(this);
327 { 326 {
328 base::AutoLock autolock(lock_); 327 base::AutoLock autolock(lock_);
329 finished_ = true; 328 finished_ = true;
330 io_loop_ = NULL; 329 io_loop_ = NULL;
331 } 330 }
332 cv_.Signal(); 331 cv_.Signal();
333 Release(); // Balanced with StartURLRequest(). 332 Release(); // Balanced with StartURLRequest().
334 } 333 }
335 } 334 }
336 335
337 // Must be called on the IO loop thread. 336 // Must be called on the IO loop thread.
338 void CancelURLRequest() { 337 void CancelURLRequest() {
339 #ifndef NDEBUG 338 #ifndef NDEBUG
340 { 339 {
341 base::AutoLock autolock(lock_); 340 base::AutoLock autolock(lock_);
342 if (io_loop_) 341 if (io_loop_)
343 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 342 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
344 } 343 }
345 #endif 344 #endif
346 if (request_) { 345 if (request_) {
347 request_->Cancel(); 346 request_.reset();
348 delete request_;
349 request_ = NULL;
350 g_ocsp_io_loop.Get().RemoveRequest(this); 347 g_ocsp_io_loop.Get().RemoveRequest(this);
351 { 348 {
352 base::AutoLock autolock(lock_); 349 base::AutoLock autolock(lock_);
353 finished_ = true; 350 finished_ = true;
354 io_loop_ = NULL; 351 io_loop_ = NULL;
355 } 352 }
356 cv_.Signal(); 353 cv_.Signal();
357 Release(); // Balanced with StartURLRequest(). 354 Release(); // Balanced with StartURLRequest().
358 } 355 }
359 } 356 }
(...skipping 30 matching lines...) Expand all
390 if (url_request_context == NULL) 387 if (url_request_context == NULL)
391 return; 388 return;
392 389
393 { 390 {
394 base::AutoLock autolock(lock_); 391 base::AutoLock autolock(lock_);
395 DCHECK(!io_loop_); 392 DCHECK(!io_loop_);
396 io_loop_ = base::MessageLoopForIO::current(); 393 io_loop_ = base::MessageLoopForIO::current();
397 g_ocsp_io_loop.Get().AddRequest(this); 394 g_ocsp_io_loop.Get().AddRequest(this);
398 } 395 }
399 396
400 request_ = 397 request_ = url_request_context->CreateRequest(
401 new URLRequest(url_, DEFAULT_PRIORITY, this, url_request_context); 398 url_, DEFAULT_PRIORITY, this, NULL);
402 // To meet the privacy requirements of incognito mode. 399 // To meet the privacy requirements of incognito mode.
403 request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES | 400 request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES |
404 LOAD_DO_NOT_SEND_COOKIES); 401 LOAD_DO_NOT_SEND_COOKIES);
405 402
406 if (http_request_method_ == "POST") { 403 if (http_request_method_ == "POST") {
407 DCHECK(!upload_content_.empty()); 404 DCHECK(!upload_content_.empty());
408 DCHECK(!upload_content_type_.empty()); 405 DCHECK(!upload_content_type_.empty());
409 406
410 request_->set_method("POST"); 407 request_->set_method("POST");
411 extra_request_headers_.SetHeader( 408 extra_request_headers_.SetHeader(
412 HttpRequestHeaders::kContentType, upload_content_type_); 409 HttpRequestHeaders::kContentType, upload_content_type_);
413 410
414 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader( 411 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
415 upload_content_.data(), upload_content_.size())); 412 upload_content_.data(), upload_content_.size()));
416 request_->set_upload(make_scoped_ptr( 413 request_->set_upload(make_scoped_ptr(
417 UploadDataStream::CreateWithReader(reader.Pass(), 0))); 414 UploadDataStream::CreateWithReader(reader.Pass(), 0)));
418 } 415 }
419 if (!extra_request_headers_.IsEmpty()) 416 if (!extra_request_headers_.IsEmpty())
420 request_->SetExtraRequestHeaders(extra_request_headers_); 417 request_->SetExtraRequestHeaders(extra_request_headers_);
421 418
422 request_->Start(); 419 request_->Start();
423 AddRef(); // Release after |request_| deleted. 420 AddRef(); // Release after |request_| deleted.
424 } 421 }
425 422
426 GURL url_; // The URL we eventually wound up at 423 GURL url_; // The URL we eventually wound up at
427 std::string http_request_method_; 424 std::string http_request_method_;
428 base::TimeDelta timeout_; // The timeout for OCSP 425 base::TimeDelta timeout_; // The timeout for OCSP
429 URLRequest* request_; // The actual request this wraps 426 scoped_ptr<URLRequest> request_; // The actual request this wraps
430 scoped_refptr<IOBuffer> buffer_; // Read buffer 427 scoped_refptr<IOBuffer> buffer_; // Read buffer
431 HttpRequestHeaders extra_request_headers_; 428 HttpRequestHeaders extra_request_headers_;
432 429
433 // HTTP POST payload. |request_| reads bytes from this. 430 // HTTP POST payload. |request_| reads bytes from this.
434 std::string upload_content_; 431 std::string upload_content_;
435 std::string upload_content_type_; // MIME type of POST payload 432 std::string upload_content_type_; // MIME type of POST payload
436 433
437 int response_code_; // HTTP status code for the request 434 int response_code_; // HTTP status code for the request
438 std::string response_content_type_; 435 std::string response_content_type_;
439 scoped_refptr<HttpResponseHeaders> response_headers_; 436 scoped_refptr<HttpResponseHeaders> response_headers_;
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) { 967 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) {
971 pthread_mutex_lock(&g_request_context_lock); 968 pthread_mutex_lock(&g_request_context_lock);
972 if (request_context) { 969 if (request_context) {
973 DCHECK(!g_request_context); 970 DCHECK(!g_request_context);
974 } 971 }
975 g_request_context = request_context; 972 g_request_context = request_context;
976 pthread_mutex_unlock(&g_request_context_lock); 973 pthread_mutex_unlock(&g_request_context_lock);
977 } 974 }
978 975
979 } // namespace net 976 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698