diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-01 19:48:36 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-01 19:48:36 +0000 |
commit | 3eb07da6e868e49e28cb5a6d8a57037f2c45a20e (patch) | |
tree | b9e05e275e38b176b1473e0f9e66075706ca238b /chrome_frame/npapi_url_request.cc | |
parent | 55750b57e30ecc9f3657d1ebd08853e232ba4e23 (diff) | |
download | chromium_src-3eb07da6e868e49e28cb5a6d8a57037f2c45a20e.zip chromium_src-3eb07da6e868e49e28cb5a6d8a57037f2c45a20e.tar.gz chromium_src-3eb07da6e868e49e28cb5a6d8a57037f2c45a20e.tar.bz2 |
TEST=new tests added.
Review URL: http://codereview.chromium.org/545093
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37728 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/npapi_url_request.cc')
-rw-r--r-- | chrome_frame/npapi_url_request.cc | 173 |
1 files changed, 162 insertions, 11 deletions
diff --git a/chrome_frame/npapi_url_request.cc b/chrome_frame/npapi_url_request.cc index 33052a1..d7d9a2f 100644 --- a/chrome_frame/npapi_url_request.cc +++ b/chrome_frame/npapi_url_request.cc @@ -33,6 +33,39 @@ #include "chrome_frame/np_browser_functions.h" #include "net/base/net_errors.h" +class NPAPIUrlRequest : public PluginUrlRequest { + public: + explicit NPAPIUrlRequest(NPP instance); + ~NPAPIUrlRequest(); + + virtual bool Start(); + virtual void Stop(); + virtual bool Read(int bytes_to_read); + + // Called from NPAPI + bool OnStreamCreated(const char* mime_type, NPStream* stream); + NPError OnStreamDestroyed(NPReason reason); + int OnWriteReady(); + int OnWrite(void* buffer, int len); + + // Thread unsafe implementation of ref counting, since + // this will be called on the plugin UI thread only. + virtual unsigned long API_CALL AddRef(); + virtual unsigned long API_CALL Release(); + + private: + PluginUrlRequestDelegate* delegate_; + unsigned long ref_count_; + NPP instance_; + NPStream* stream_; + size_t pending_read_size_; + URLRequestStatus status_; + + PlatformThreadId thread_; + static int instance_count_; + DISALLOW_COPY_AND_ASSIGN(NPAPIUrlRequest); +}; + int NPAPIUrlRequest::instance_count_ = 0; NPAPIUrlRequest::NPAPIUrlRequest(NPP instance) @@ -62,9 +95,7 @@ bool NPAPIUrlRequest::Start() { NOTREACHED() << "PluginUrlRequest only supports 'GET'/'POST'"; } - if (NPERR_NO_ERROR == result) { - request_handler()->AddRequest(this); - } else { + if (NPERR_NO_ERROR != result) { int os_error = net::ERR_FAILED; switch (result) { case NPERR_INVALID_URL: @@ -74,7 +105,8 @@ bool NPAPIUrlRequest::Start() { break; } - OnResponseEnd(URLRequestStatus(URLRequestStatus::FAILED, os_error)); + delegate_->OnResponseEnd(id(), + URLRequestStatus(URLRequestStatus::FAILED, os_error)); return false; } @@ -88,10 +120,6 @@ void NPAPIUrlRequest::Stop() { npapi::DestroyStream(instance_, stream_, NPRES_USER_BREAK); stream_ = NULL; } - - request_handler()->RemoveRequest(this); - if (!status_.is_io_pending()) - OnResponseEnd(status_); } bool NPAPIUrlRequest::Read(int bytes_to_read) { @@ -105,13 +133,13 @@ bool NPAPIUrlRequest::OnStreamCreated(const char* mime_type, NPStream* stream) { // TODO(iyengar) // Add support for passing persistent cookies and information about any URL // redirects to Chrome. - OnResponseStarted(mime_type, stream->headers, stream->end, + delegate_->OnResponseStarted(id(), mime_type, stream->headers, stream->end, base::Time::FromTimeT(stream->lastmodified), std::string(), std::string(), 0); return true; } -void NPAPIUrlRequest::OnStreamDestroyed(NPReason reason) { +NPError NPAPIUrlRequest::OnStreamDestroyed(NPReason reason) { URLRequestStatus::Status status = URLRequestStatus::FAILED; switch (reason) { case NPRES_DONE: @@ -128,6 +156,9 @@ void NPAPIUrlRequest::OnStreamDestroyed(NPReason reason) { status_.set_os_error(net::ERR_CONNECTION_CLOSED); break; } + + delegate_->OnResponseEnd(id(), status_); + return NPERR_NO_ERROR; } int NPAPIUrlRequest::OnWriteReady() { @@ -136,7 +167,7 @@ int NPAPIUrlRequest::OnWriteReady() { int NPAPIUrlRequest::OnWrite(void* buffer, int len) { pending_read_size_ = 0; - OnReadComplete(buffer, len); + delegate_->OnReadComplete(id(), buffer, len); return len; } @@ -155,3 +186,123 @@ STDMETHODIMP_(ULONG) NPAPIUrlRequest::Release() { return ret; } +NPAPIUrlRequestManager::NPAPIUrlRequestManager() : instance_(NULL) { +} + +NPAPIUrlRequestManager::~NPAPIUrlRequestManager() { + StopAll(); +} + +// PluginUrlRequestManager implementation +bool NPAPIUrlRequestManager::IsThreadSafe() { + return false; +} + +void NPAPIUrlRequestManager::StartRequest(int request_id, + const IPC::AutomationURLRequest& request_info) { + scoped_refptr<NPAPIUrlRequest> new_request(new NPAPIUrlRequest(instance_)); + DCHECK(new_request); + if (new_request->Initialize(this, request_id, request_info.url, + request_info.method, request_info.referrer, + request_info.extra_request_headers, request_info.upload_data.get(), + enable_frame_busting_)) { + // Add to map. + DCHECK(NULL == request_map_[request_id].get()); + request_map_[request_id] = new_request; + if (new_request->Start()) { + // Keep additional reference on request for NPSTREAM + // This will be released in NPP_UrlNotify + new_request->AddRef(); + } + } +} + +void NPAPIUrlRequestManager::ReadRequest(int request_id, int bytes_to_read) { + scoped_refptr<NPAPIUrlRequest> request = request_map_[request_id]; + DCHECK(request.get()); + if (request) + request->Read(bytes_to_read); +} + +void NPAPIUrlRequestManager::EndRequest(int request_id) { + scoped_refptr<NPAPIUrlRequest> request = request_map_[request_id]; + if (request) + request->Stop(); +} + +void NPAPIUrlRequestManager::StopAll() { + for (RequestMap::iterator index = request_map_.begin(); + index != request_map_.end(); + ++index) { + scoped_refptr<NPAPIUrlRequest> request = (*index).second; + request->Stop(); + } +} + +// PluginRequestDelegate implementation. +// Callbacks from NPAPIUrlRequest. Simply forward to the delegate. +void NPAPIUrlRequestManager::OnResponseStarted(int request_id, + const char* mime_type, const char* headers, int size, + base::Time last_modified, const std::string& peristent_cookies, + const std::string& redirect_url, int redirect_status) { + delegate_->OnResponseStarted(request_id, mime_type, headers, size, + last_modified, peristent_cookies, redirect_url, redirect_status); +} + +void NPAPIUrlRequestManager::OnReadComplete(int request_id, const void* buffer, + int len) { + delegate_->OnReadComplete(request_id, buffer, len); +} + +void NPAPIUrlRequestManager::OnResponseEnd(int request_id, + const URLRequestStatus& status) { + // Delete from map. + RequestMap::iterator it = request_map_.find(request_id); + DCHECK(request_map_.end() != it); + scoped_refptr<NPAPIUrlRequest> request = (*it).second; + request_map_.erase(it); + + // Inform delegate unless canceled. + if (status.status() != URLRequestStatus::CANCELED) + delegate_->OnResponseEnd(request_id, status); +} + +// Notifications from browser. Find the NPAPIUrlRequest and forward to it. +bool NPAPIUrlRequestManager::NewStream(NPMIMEType type, NPStream* stream, + NPBool seekable, uint16* stream_type) { + NPAPIUrlRequest* request = RequestFromNotifyData(stream->notifyData); + DCHECK(request_map_.find(request->id()) != request_map_.end()); + // We need to return the requested stream mode if we are returning a success + // code. If we don't do this it causes Opera to blow up. + *stream_type = NP_NORMAL; + return request->OnStreamCreated(type, stream); +} + +int32 NPAPIUrlRequestManager::WriteReady(NPStream* stream) { + NPAPIUrlRequest* request = RequestFromNotifyData(stream->notifyData); + DCHECK(request_map_.find(request->id()) != request_map_.end()); + return request->OnWriteReady(); +} + +int32 NPAPIUrlRequestManager::Write(NPStream* stream, int32 offset, + int32 len, void* buffer) { + NPAPIUrlRequest* request = RequestFromNotifyData(stream->notifyData); + DCHECK(request_map_.find(request->id()) != request_map_.end()); + return request->OnWrite(buffer, len); +} + +NPError NPAPIUrlRequestManager::DestroyStream(NPStream* stream, + NPReason reason) { + NPAPIUrlRequest* request = RequestFromNotifyData(stream->notifyData); + DCHECK(request_map_.find(request->id()) != request_map_.end()); + return request->OnStreamDestroyed(reason); +} + +void NPAPIUrlRequestManager::UrlNotify(const char* url, NPReason reason, + void* notify_data) { + NPAPIUrlRequest* request = RequestFromNotifyData(notify_data); + if (request) { + request->Stop(); + request->Release(); + } +} |