| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 | 7 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 |
| 8 // until NSS 3.12.2 comes out and we update to it. | 8 // until NSS 3.12.2 comes out and we update to it. |
| 9 #define Lock FOO_NSS_Lock | 9 #define Lock FOO_NSS_Lock |
| 10 #include <certt.h> | 10 #include <certt.h> |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 : public base::RefCountedThreadSafe<OCSPRequestSession>, | 86 : public base::RefCountedThreadSafe<OCSPRequestSession>, |
| 87 public URLRequest::Delegate, | 87 public URLRequest::Delegate, |
| 88 public MessageLoop::DestructionObserver { | 88 public MessageLoop::DestructionObserver { |
| 89 public: | 89 public: |
| 90 OCSPRequestSession(const GURL& url, | 90 OCSPRequestSession(const GURL& url, |
| 91 const char* http_request_method, | 91 const char* http_request_method, |
| 92 base::TimeDelta timeout) | 92 base::TimeDelta timeout) |
| 93 : url_(url), | 93 : url_(url), |
| 94 http_request_method_(http_request_method), | 94 http_request_method_(http_request_method), |
| 95 timeout_(timeout), | 95 timeout_(timeout), |
| 96 io_loop_(Singleton<OCSPInitSingleton>::get()->io_thread()), | |
| 97 request_(NULL), | 96 request_(NULL), |
| 98 buffer_(new net::IOBuffer(kRecvBufferSize)), | 97 buffer_(new net::IOBuffer(kRecvBufferSize)), |
| 99 response_code_(-1), | 98 response_code_(-1), |
| 100 cv_(&lock_), | 99 cv_(&lock_), |
| 100 io_loop_(Singleton<OCSPInitSingleton>::get()->io_thread()), |
| 101 finished_(false) {} | 101 finished_(false) {} |
| 102 | 102 |
| 103 void SetPostData(const char* http_data, PRUint32 http_data_len, | 103 void SetPostData(const char* http_data, PRUint32 http_data_len, |
| 104 const char* http_content_type) { | 104 const char* http_content_type) { |
| 105 upload_content_.assign(http_data, http_data_len); | 105 upload_content_.assign(http_data, http_data_len); |
| 106 upload_content_type_.assign(http_content_type); | 106 upload_content_type_.assign(http_content_type); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void AddHeader(const char* http_header_name, const char* http_header_value) { | 109 void AddHeader(const char* http_header_name, const char* http_header_value) { |
| 110 if (!extra_request_headers_.empty()) | 110 if (!extra_request_headers_.empty()) |
| 111 extra_request_headers_ += "\r\n"; | 111 extra_request_headers_ += "\r\n"; |
| 112 StringAppendF(&extra_request_headers_, | 112 StringAppendF(&extra_request_headers_, |
| 113 "%s: %s", http_header_name, http_header_value); | 113 "%s: %s", http_header_name, http_header_value); |
| 114 } | 114 } |
| 115 | 115 |
| 116 void Start() { | 116 void Start() { |
| 117 // IO thread may set |io_loop_| to NULL, so protect by |lock_|. |
| 118 AutoLock autolock(lock_); |
| 117 if (io_loop_) { | 119 if (io_loop_) { |
| 118 io_loop_->PostTask( | 120 io_loop_->PostTask( |
| 119 FROM_HERE, | 121 FROM_HERE, |
| 120 NewRunnableMethod(this, &OCSPRequestSession::StartURLRequest)); | 122 NewRunnableMethod(this, &OCSPRequestSession::StartURLRequest)); |
| 121 } | 123 } |
| 122 } | 124 } |
| 123 | 125 |
| 124 bool Started() const { | 126 bool Started() const { |
| 125 return request_ != NULL; | 127 return request_ != NULL; |
| 126 } | 128 } |
| 127 | 129 |
| 128 void Cancel() { | 130 void Cancel() { |
| 129 if (io_loop_ && request_) { | 131 // IO thread may set |io_loop_| to NULL, so protect by |lock_|. |
| 132 AutoLock autolock(lock_); |
| 133 if (io_loop_) { |
| 130 io_loop_->PostTask( | 134 io_loop_->PostTask( |
| 131 FROM_HERE, | 135 FROM_HERE, |
| 132 NewRunnableMethod(this, &OCSPRequestSession::CancelURLRequest)); | 136 NewRunnableMethod(this, &OCSPRequestSession::CancelURLRequest)); |
| 133 } | 137 } |
| 134 } | 138 } |
| 135 | 139 |
| 136 bool Finished() const { | 140 bool Finished() const { |
| 137 AutoLock autolock(lock_); | 141 AutoLock autolock(lock_); |
| 138 return finished_; | 142 return finished_; |
| 139 } | 143 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 DCHECK_EQ(request, request_); | 211 DCHECK_EQ(request, request_); |
| 208 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); | 212 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); |
| 209 | 213 |
| 210 do { | 214 do { |
| 211 if (!request_->status().is_success() || bytes_read <= 0) | 215 if (!request_->status().is_success() || bytes_read <= 0) |
| 212 break; | 216 break; |
| 213 data_.append(buffer_->data(), bytes_read); | 217 data_.append(buffer_->data(), bytes_read); |
| 214 } while (request_->Read(buffer_, kRecvBufferSize, &bytes_read)); | 218 } while (request_->Read(buffer_, kRecvBufferSize, &bytes_read)); |
| 215 | 219 |
| 216 if (!request_->status().is_io_pending()) { | 220 if (!request_->status().is_io_pending()) { |
| 221 MessageLoop* io_loop = io_loop_; |
| 217 { | 222 { |
| 218 AutoLock autolock(lock_); | 223 AutoLock autolock(lock_); |
| 219 finished_ = true; | 224 finished_ = true; |
| 225 io_loop_ = NULL; |
| 220 } | 226 } |
| 221 cv_.Signal(); | 227 cv_.Signal(); |
| 222 delete request_; | 228 delete request_; |
| 223 request_ = NULL; | 229 request_ = NULL; |
| 224 io_loop_->RemoveDestructionObserver(this); | 230 io_loop->RemoveDestructionObserver(this); |
| 225 io_loop_ = NULL; | |
| 226 } | 231 } |
| 227 } | 232 } |
| 228 | 233 |
| 229 virtual void WillDestroyCurrentMessageLoop() { | 234 virtual void WillDestroyCurrentMessageLoop() { |
| 230 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); | 235 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); |
| 236 { |
| 237 AutoLock autolock(lock_); |
| 238 io_loop_ = NULL; |
| 239 } |
| 231 if (request_) { | 240 if (request_) { |
| 232 request_->Cancel(); | 241 request_->Cancel(); |
| 233 delete request_; | 242 delete request_; |
| 234 request_ = NULL; | 243 request_ = NULL; |
| 235 } | 244 } |
| 236 io_loop_ = NULL; | |
| 237 } | 245 } |
| 238 | 246 |
| 239 private: | 247 private: |
| 240 friend class base::RefCountedThreadSafe<OCSPRequestSession>; | 248 friend class base::RefCountedThreadSafe<OCSPRequestSession>; |
| 241 | 249 |
| 242 virtual ~OCSPRequestSession() { | 250 virtual ~OCSPRequestSession() { |
| 243 DCHECK(!request_); | 251 DCHECK(!request_); |
| 244 if (io_loop_) | 252 if (io_loop_) |
| 245 io_loop_->RemoveDestructionObserver(this); | 253 io_loop_->RemoveDestructionObserver(this); |
| 246 io_loop_ = NULL; | |
| 247 } | 254 } |
| 248 | 255 |
| 249 void StartURLRequest() { | 256 void StartURLRequest() { |
| 250 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); | 257 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); |
| 251 DCHECK(!request_); | 258 DCHECK(!request_); |
| 252 | 259 |
| 253 io_loop_->AddDestructionObserver(this); | 260 io_loop_->AddDestructionObserver(this); |
| 254 | 261 |
| 255 request_ = new URLRequest(url_, this); | 262 request_ = new URLRequest(url_, this); |
| 256 request_->set_context( | 263 request_->set_context( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 271 request_->AppendBytesToUpload(upload_content_.data(), | 278 request_->AppendBytesToUpload(upload_content_.data(), |
| 272 static_cast<int>(upload_content_.size())); | 279 static_cast<int>(upload_content_.size())); |
| 273 } | 280 } |
| 274 if (!extra_request_headers_.empty()) | 281 if (!extra_request_headers_.empty()) |
| 275 request_->SetExtraRequestHeaders(extra_request_headers_); | 282 request_->SetExtraRequestHeaders(extra_request_headers_); |
| 276 | 283 |
| 277 request_->Start(); | 284 request_->Start(); |
| 278 } | 285 } |
| 279 | 286 |
| 280 void CancelURLRequest() { | 287 void CancelURLRequest() { |
| 281 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); | 288 if (io_loop_) |
| 289 DCHECK_EQ(MessageLoopForIO::current(), io_loop_); |
| 282 if (request_) { | 290 if (request_) { |
| 283 request_->Cancel(); | 291 request_->Cancel(); |
| 284 delete request_; | 292 delete request_; |
| 285 request_ = NULL; | 293 request_ = NULL; |
| 286 } | 294 } |
| 287 } | 295 } |
| 288 | 296 |
| 289 GURL url_; // The URL we eventually wound up at | 297 GURL url_; // The URL we eventually wound up at |
| 290 std::string http_request_method_; | 298 std::string http_request_method_; |
| 291 base::TimeDelta timeout_; // The timeout for OCSP | 299 base::TimeDelta timeout_; // The timeout for OCSP |
| 292 MessageLoop* io_loop_; // Message loop of the IO thread | |
| 293 URLRequest* request_; // The actual request this wraps | 300 URLRequest* request_; // The actual request this wraps |
| 294 scoped_refptr<net::IOBuffer> buffer_; // Read buffer | 301 scoped_refptr<net::IOBuffer> buffer_; // Read buffer |
| 295 std::string extra_request_headers_; // Extra headers for the request, if any | 302 std::string extra_request_headers_; // Extra headers for the request, if any |
| 296 std::string upload_content_; // HTTP POST payload | 303 std::string upload_content_; // HTTP POST payload |
| 297 std::string upload_content_type_; // MIME type of POST payload | 304 std::string upload_content_type_; // MIME type of POST payload |
| 298 | 305 |
| 299 int response_code_; // HTTP status code for the request | 306 int response_code_; // HTTP status code for the request |
| 300 std::string response_content_type_; | 307 std::string response_content_type_; |
| 301 scoped_refptr<net::HttpResponseHeaders> response_headers_; | 308 scoped_refptr<net::HttpResponseHeaders> response_headers_; |
| 302 std::string data_; // Results of the requst | 309 std::string data_; // Results of the requst |
| 303 | 310 |
| 304 // |lock_| protects |finished_| only. | 311 // |lock_| protects |finished_| and |io_loop_|. |
| 305 mutable Lock lock_; | 312 mutable Lock lock_; |
| 306 ConditionVariable cv_; | 313 ConditionVariable cv_; |
| 307 | 314 |
| 315 MessageLoop* io_loop_; // Message loop of the IO thread |
| 308 bool finished_; | 316 bool finished_; |
| 309 | 317 |
| 310 DISALLOW_COPY_AND_ASSIGN(OCSPRequestSession); | 318 DISALLOW_COPY_AND_ASSIGN(OCSPRequestSession); |
| 311 }; | 319 }; |
| 312 | 320 |
| 313 // Concrete class for SEC_HTTP_SERVER_SESSION. | 321 // Concrete class for SEC_HTTP_SERVER_SESSION. |
| 314 class OCSPServerSession { | 322 class OCSPServerSession { |
| 315 public: | 323 public: |
| 316 OCSPServerSession(const char* host, PRUint16 port) | 324 OCSPServerSession(const char* host, PRUint16 port) |
| 317 : host_(host), port_(port) {} | 325 : host_(host), port_(port) {} |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 // This function would be called before NSS initialization. | 561 // This function would be called before NSS initialization. |
| 554 void SetURLRequestContextForOCSP(URLRequestContext* request_context) { | 562 void SetURLRequestContextForOCSP(URLRequestContext* request_context) { |
| 555 OCSPInitSingleton::set_url_request_context(request_context); | 563 OCSPInitSingleton::set_url_request_context(request_context); |
| 556 } | 564 } |
| 557 | 565 |
| 558 URLRequestContext* GetURLRequestContextForOCSP() { | 566 URLRequestContext* GetURLRequestContextForOCSP() { |
| 559 return OCSPInitSingleton::url_request_context(); | 567 return OCSPInitSingleton::url_request_context(); |
| 560 } | 568 } |
| 561 | 569 |
| 562 } // namespace net | 570 } // namespace net |
| OLD | NEW |