summaryrefslogtreecommitdiffstats
path: root/chrome_frame/urlmon_url_request.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_frame/urlmon_url_request.h')
-rw-r--r--chrome_frame/urlmon_url_request.h308
1 files changed, 61 insertions, 247 deletions
diff --git a/chrome_frame/urlmon_url_request.h b/chrome_frame/urlmon_url_request.h
index d4abee5..e47edcc 100644
--- a/chrome_frame/urlmon_url_request.h
+++ b/chrome_frame/urlmon_url_request.h
@@ -8,263 +8,77 @@
#include <urlmon.h>
#include <atlbase.h>
#include <atlcom.h>
-#include <atlwin.h>
-#include <algorithm>
#include <string>
-#include "base/lock.h"
-#include "base/platform_thread.h"
-#include "base/thread.h"
#include "base/scoped_comptr_win.h"
+#include "base/thread.h"
+#include "base/waitable_event.h"
#include "chrome_frame/plugin_url_request.h"
-#include "chrome_frame/chrome_frame_delegate.h"
+#include "chrome_frame/utils.h"
-#include "net/base/net_errors.h"
-#include "net/base/upload_data.h"
+class UrlmonUrlRequest;
-class UrlmonUrlRequest
- : public CComObjectRootEx<CComMultiThreadModel>,
- public PluginUrlRequest,
- public IServiceProviderImpl<UrlmonUrlRequest>,
- public IBindStatusCallback,
- public IHttpNegotiate,
- public IAuthenticate,
- public IHttpSecurity,
- public CWindowImpl<UrlmonUrlRequest>,
- public TaskMarshallerThroughWindowsMessages<UrlmonUrlRequest> {
+class UrlmonUrlRequestManager :
+ public PluginUrlRequestManager,
+ public PluginUrlRequestDelegate {
public:
- typedef TaskMarshallerThroughWindowsMessages<UrlmonUrlRequest>
- TaskMarshaller;
-
- UrlmonUrlRequest();
- ~UrlmonUrlRequest();
-
-BEGIN_COM_MAP(UrlmonUrlRequest)
- COM_INTERFACE_ENTRY(IHttpNegotiate)
- COM_INTERFACE_ENTRY(IServiceProvider)
- COM_INTERFACE_ENTRY(IBindStatusCallback)
- COM_INTERFACE_ENTRY(IWindowForBindingUI)
- COM_INTERFACE_ENTRY(IAuthenticate)
- COM_INTERFACE_ENTRY(IHttpSecurity)
-END_COM_MAP()
-
-BEGIN_SERVICE_MAP(UrlmonUrlRequest)
- SERVICE_ENTRY(IID_IHttpNegotiate);
-END_SERVICE_MAP()
-
-BEGIN_MSG_MAP(UrlmonUrlRequest)
- CHAIN_MSG_MAP(TaskMarshaller)
-END_MSG_MAP()
-
- // PluginUrlRequest implementation
- virtual bool Start();
- virtual void Stop();
- virtual bool Read(int bytes_to_read);
-
- void TransferToHost(IUnknown* host);
-
- // IBindStatusCallback implementation
- STDMETHOD(OnStartBinding)(DWORD reserved, IBinding* binding);
- STDMETHOD(GetPriority)(LONG* priority);
- STDMETHOD(OnLowResource)(DWORD reserved);
- STDMETHOD(OnProgress)(ULONG progress, ULONG max_progress,
- ULONG status_code, LPCWSTR status_text);
- STDMETHOD(OnStopBinding)(HRESULT result, LPCWSTR error);
- STDMETHOD(GetBindInfo)(DWORD* bind_flags, BINDINFO* bind_info);
- STDMETHOD(OnDataAvailable)(DWORD flags, DWORD size, FORMATETC* formatetc,
- STGMEDIUM* storage);
- STDMETHOD(OnObjectAvailable)(REFIID iid, IUnknown* object);
-
- // IHttpNegotiate implementation
- STDMETHOD(BeginningTransaction)(const wchar_t* url,
- const wchar_t* current_headers, DWORD reserved,
- wchar_t** additional_headers);
- STDMETHOD(OnResponse)(DWORD dwResponseCode, const wchar_t* response_headers,
- const wchar_t* request_headers, wchar_t** additional_headers);
-
- // IWindowForBindingUI implementation. This interface is used typically to
- // query the window handle which URLMON uses as the parent of error dialogs.
- STDMETHOD(GetWindow)(REFGUID guid_reason, HWND* parent_window);
-
- // IAuthenticate implementation. Used to return the parent window for the
- // dialog displayed by IE for authenticating with a proxy.
- STDMETHOD(Authenticate)(HWND* parent_window, LPWSTR* user_name,
- LPWSTR* password);
-
- // IHttpSecurity implementation.
- STDMETHOD(OnSecurityProblem)(DWORD problem);
-
- HRESULT ConnectToExistingMoniker(IMoniker* moniker, IBindCtx* context,
- const std::wstring& url);
-
- void set_parent_window(HWND parent_window) {
- parent_window_ = parent_window;
- }
-
- // Needed to support PostTask.
- static bool ImplementsThreadSafeReferenceCounting() {
- return true;
- }
-
- // URL requests are handled on this thread.
- void set_worker_thread(base::Thread* worker_thread) {
- worker_thread_ = worker_thread;
- }
-
- virtual void OnFinalMessage(HWND window);
-
- protected:
- // The following functions issue and handle Urlmon requests on the dedicated
- // Urlmon thread.
- void StartAsync();
- void StopAsync();
- void ReadAsync(int bytes_to_read);
- void ReleaseBindings();
-
- static const size_t kCopyChunkSize = 32 * 1024;
- // URL requests are handled on this thread.
- base::Thread* worker_thread_;
-
- // A fake stream class to make it easier to copy received data using
- // IStream::CopyTo instead of allocating temporary buffers and keeping
- // track of data copied so far.
- class SendStream
- : public CComObjectRoot,
- public IStream {
- public:
- SendStream() {
- }
-
- BEGIN_COM_MAP(SendStream)
- COM_INTERFACE_ENTRY(IStream)
- COM_INTERFACE_ENTRY(ISequentialStream)
- END_COM_MAP()
+ UrlmonUrlRequestManager();
+ ~UrlmonUrlRequestManager();
- void Initialize(UrlmonUrlRequest* request) {
- request_ = request;
- }
-
- STDMETHOD(Read)(void* pv, ULONG cb, ULONG* read) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(Write)(const void * buffer, ULONG size, ULONG* size_written) {
- DCHECK(request_);
- int size_to_write = static_cast<int>(
- std::min(static_cast<ULONG>(MAXINT), size));
- request_->OnReadComplete(buffer, size_to_write);
- if (size_written)
- *size_written = size_to_write;
- return S_OK;
- }
-
- STDMETHOD(Seek)(LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER* new_pos) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(SetSize)(ULARGE_INTEGER new_size) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(CopyTo)(IStream* stream, ULARGE_INTEGER cb, ULARGE_INTEGER* read,
- ULARGE_INTEGER* written) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(Commit)(DWORD flags) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(Revert)() {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(LockRegion)(ULARGE_INTEGER offset, ULARGE_INTEGER cb,
- DWORD type) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(UnlockRegion)(ULARGE_INTEGER offset, ULARGE_INTEGER cb,
- DWORD type) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- STDMETHOD(Stat)(STATSTG *pstatstg, DWORD grfStatFlag) {
- return E_NOTIMPL;
- }
-
- STDMETHOD(Clone)(IStream** stream) {
- DCHECK(false) << __FUNCTION__;
- return E_NOTIMPL;
- }
-
- protected:
- scoped_refptr<UrlmonUrlRequest> request_;
- DISALLOW_COPY_AND_ASSIGN(SendStream);
- };
-
- // Manage data caching. Note: this class supports cache
- // size less than 2GB
- class Cache {
- public:
- // Adds data to the end of the cache.
- bool Append(IStream* source, size_t* bytes_copied);
-
- // Reads from the cache.
- bool Read(IStream* dest, size_t size, size_t* bytes_copied);
-
- // Returns the size of the cache.
- size_t Size() const;
-
- // Returns true if the cache has valid data.
- bool is_valid() const {
- return Size() != 0;
- }
-
- protected:
- std::vector<byte> cache_;
- char read_buffer_[kCopyChunkSize];
- };
-
- HRESULT StartAsyncDownload();
- // Sends over the response end notification to chrome, releases the bindings
- // and releases the initial reference on the UrlmonUrlRequest object.
- // After this function is called we should not attempt to access any members
- // as the object could become invalid at any point.
- void EndRequest();
- // Executes in the context of the UI thread and releases the outstanding
- // reference to us. It also deletes the request mapping for this instance.
- void EndRequestInternal();
- int GetHttpResponseStatus() const;
- std::string GetHttpHeaders() const;
-
- static net::Error HresultToNetError(HRESULT hr);
+ // Use specific moniker and bind context when Chrome request this url.
+ // Used from ChromeActiveDocument's implementation of IPersistMoniker::Load().
+ void UseMonikerForUrl(IMoniker* moniker, IBindCtx* bind_ctx,
+ const std::wstring& url);
+ void StealMonikerFromRequest(int request_id, IMoniker** moniker);
private:
- std::wstring redirect_url_;
- int redirect_status_;
- ScopedComPtr<IBinding> binding_;
- ScopedComPtr<IMoniker> moniker_;
- ScopedComPtr<IBindCtx> bind_context_;
- Cache cached_data_;
- size_t pending_read_size_;
- URLRequestStatus status_;
-
- PlatformThreadId thread_;
- static int instance_count_;
- HWND parent_window_;
- // Set to true if a redirect notification was aborted.
- bool ignore_redirect_stop_binding_error_;
-
- DISALLOW_COPY_AND_ASSIGN(UrlmonUrlRequest);
+ struct MonikerForUrl {
+ ScopedComPtr<IMoniker> moniker;
+ ScopedComPtr<IBindCtx> bind_ctx;
+ std::wstring url;
+ };
+
+ friend class MessageLoop;
+ friend struct RunnableMethodTraits<UrlmonUrlRequestManager>;
+ static bool ImplementsThreadSafeReferenceCounting() { return true; }
+ void AddRef() {}
+ void Release() {}
+
+ // PluginUrlRequestManager implementation.
+ virtual bool IsThreadSafe();
+ virtual void StartRequest(int request_id,
+ const IPC::AutomationURLRequest& request_info);
+ virtual void ReadRequest(int request_id, int bytes_to_read);
+ virtual void EndRequest(int request_id);
+ virtual void StopAll();
+
+ // PluginUrlRequestDelegate implementation
+ virtual void 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);
+ virtual void OnReadComplete(int request_id, const void* buffer, int len);
+ virtual void OnResponseEnd(int request_id, const URLRequestStatus& status);
+
+ // Methods executed in worker thread.
+ void StartRequestWorker(int request_id,
+ const IPC::AutomationURLRequest& request_info,
+ MonikerForUrl* moniker_for_url);
+ void ReadRequestWorker(int request_id, int bytes_to_read);
+ void EndRequestWorker(int request_id);
+ void StopAllWorker();
+ void StealMonikerFromRequestWorker(int request_id, IMoniker** moniker,
+ base::WaitableEvent* done);
+
+ // Map for (request_id <-> UrlmonUrlRequest)
+ typedef std::map<int, scoped_refptr<UrlmonUrlRequest> > RequestMap;
+ RequestMap request_map_;
+ scoped_refptr<UrlmonUrlRequest> LookupRequest(int request_id);
+
+ scoped_ptr<MonikerForUrl> moniker_for_url_;
+ STAThread worker_thread_;
+ base::WaitableEvent map_empty_;
+ bool stopping_;
};
#endif // CHROME_FRAME_URLMON_URL_REQUEST_H_