From f0fc2ba27d933c49313e19eabce3ce973597f37b Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 2 Feb 2015 13:43:49 +0100 Subject: [PATCH] mshtml: Use our submit implementation for all windows, but only for POST method. --- dlls/mshtml/binding.h | 3 ++- dlls/mshtml/htmlform.c | 23 ++++++++++++---- dlls/mshtml/navigate.c | 16 ++++++++++- dlls/mshtml/nsiface.idl | 59 ++++++++++++++++++++++++++++++++++++++++- dlls/mshtml/nsio.c | 19 +++++++++++-- dlls/mshtml/persist.c | 2 +- 6 files changed, 111 insertions(+), 11 deletions(-) diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index e40735cf441..c2daffd3f5f 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -57,6 +57,7 @@ typedef struct { } nsChannel; typedef struct { + nsIInputStream *post_stream; WCHAR *headers; HGLOBAL post_data; ULONG post_data_len; @@ -133,7 +134,7 @@ HRESULT create_redirect_nschannel(const WCHAR*,nsChannel*,nsChannel**) DECLSPEC_ nsresult on_start_uri_open(NSContainer*,nsIURI*,cpp_bool*) DECLSPEC_HIDDEN; HRESULT hlink_frame_navigate(HTMLDocument*,LPCWSTR,nsChannel*,DWORD,BOOL*) DECLSPEC_HIDDEN; HRESULT create_doc_uri(HTMLOuterWindow*,IUri*,nsWineURI**) DECLSPEC_HIDDEN; -HRESULT load_nsuri(HTMLOuterWindow*,nsWineURI*,nsChannelBSC*,DWORD) DECLSPEC_HIDDEN; +HRESULT load_nsuri(HTMLOuterWindow*,nsWineURI*,nsIInputStream*,nsChannelBSC*,DWORD) DECLSPEC_HIDDEN; HRESULT set_moniker(HTMLOuterWindow*,IMoniker*,IUri*,IBindCtx*,nsChannelBSC*,BOOL) DECLSPEC_HIDDEN; void prepare_for_binding(HTMLDocument*,IMoniker*,DWORD) DECLSPEC_HIDDEN; HRESULT super_navigate(HTMLOuterWindow*,IUri*,DWORD,const WCHAR*,BYTE*,DWORD) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 2b2a62f65e5..ac6eb937cf5 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -384,14 +384,15 @@ static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface) { HTMLFormElement *This = impl_from_IHTMLFormElement(iface); HTMLOuterWindow *window = NULL, *this_window = NULL; + nsAString action_uri_str, target_str, method_str; nsIInputStream *post_stream; - nsAString action_uri_str, target_str; + BOOL is_post_submit = FALSE; IUri *uri; nsresult nsres; HRESULT hres; BOOL use_new_window; - TRACE("(%p)->()\n", This); + TRACE("(%p)\n", This); if(This->element.node.doc) { HTMLDocumentNode *doc = This->element.node.doc; @@ -413,11 +414,23 @@ static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface) return S_OK; } + nsAString_Init(&method_str, NULL); + nsres = nsIDOMHTMLFormElement_GetMethod(This->nsform, &method_str); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *method; + + static const PRUnichar postW[] = {'p','o','s','t',0}; + + nsAString_GetData(&method_str, &method); + TRACE("method is %s\n", debugstr_w(method)); + is_post_submit = !strcmpiW(method, postW); + } + nsAString_Finish(&method_str); + /* - * FIXME: We currently don't use our submit implementation for sub-windows because - * load_nsuri can't support post data. We should fix it. + * FIXME: We currently use our submit implementation for POST submit. We should always use it. */ - if(window && (!window->doc_obj || window->doc_obj->basedoc.window != window)) { + if(window && !is_post_submit) { nsres = nsIDOMHTMLFormElement_Submit(This->nsform); nsAString_Finish(&target_str); IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 2ac12eab2da..878e58286f6 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -213,6 +213,8 @@ static nsProtocolStream *create_nsprotocol_stream(void) static void release_request_data(request_data_t *request_data) { + if(request_data->post_stream) + nsIInputStream_Release(request_data->post_stream); heap_free(request_data->headers); if(request_data->post_data) GlobalFree(request_data->post_data); @@ -822,6 +824,7 @@ HRESULT start_binding(HTMLInnerWindow *inner_window, BSCallback *bscallback, IBi static HRESULT read_post_data_stream(nsIInputStream *stream, BOOL contains_headers, struct list *headers_list, request_data_t *request_data) { + nsISeekableStream *seekable_stream; UINT64 available = 0; UINT32 data_len = 0; char *data, *post_data; @@ -906,6 +909,17 @@ static HRESULT read_post_data_stream(nsIInputStream *stream, BOOL contains_heade post_data[data_len] = 0; request_data->post_data = post_data; request_data->post_data_len = data_len; + + nsres = nsIInputStream_QueryInterface(stream, &IID_nsISeekableStream, (void**)&seekable_stream); + assert(nsres == NS_OK); + + nsres = nsISeekableStream_Seek(seekable_stream, NS_SEEK_SET, 0); + assert(nsres == NS_OK); + + nsISeekableStream_Release(seekable_stream); + + nsIInputStream_AddRef(stream); + request_data->post_stream = stream; TRACE("post_data = %s\n", debugstr_an(request_data->post_data, request_data->post_data_len)); return S_OK; } @@ -2267,7 +2281,7 @@ static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *dis if(FAILED(hres)) return hres; - hres = load_nsuri(window, nsuri, NULL, LOAD_FLAGS_NONE); + hres = load_nsuri(window, nsuri, request_data ? request_data->post_stream : NULL, NULL, LOAD_FLAGS_NONE); nsISupports_Release((nsISupports*)nsuri); return hres; } diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 551406cc94c..9ba7c05933c 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -59,6 +59,8 @@ typedef WCHAR PRUnichar; #define uint32_t UINT32 #define uint64_t UINT64 +#define char16_t PRUnichar + typedef uint64_t DOMTimeStamp; typedef uint32_t nsLoadFlags; typedef int64_t PRTime; @@ -150,7 +152,6 @@ typedef nsISupports nsINode; typedef nsISupports nsIStyleSheet; typedef nsISupports nsIStyleRule; typedef nsISupports nsIDOMUserDataHandler; -typedef nsISupports nsIDocShellLoadInfo; typedef nsISupports nsISHEntry; typedef nsISupports nsIPresShell; typedef nsISupports nsIDocumentCharsetInfo; @@ -383,6 +384,24 @@ interface nsIInputStream : nsISupports nsresult IsNonBlocking(bool *_retval); } +[ + object, + uuid(8429d350-1040-4661-8b71-f2a6ba455980), + local +] +interface nsISeekableStream : nsISupports +{ + enum { + NS_SEEK_SET = 0, + NS_SEEK_CUR = 1, + NS_SEEK_END = 2 + }; + + nsresult Seek(int32_t whence, int64_t offset); + nsresult Tell(int64_t *_retval); + nsresult SetEOF(); +} + [ object, uuid(395fe045-7d18-4adb-a3fd-af98c8a1af11), @@ -3691,6 +3710,44 @@ interface nsIContentViewer : nsISupports nsresult StopEmulatingMedium(); } +[ + object, + uuid(c8d3b1e1-565a-427e-9d68-b109910ce9b7), + local +] +interface nsIDocShellLoadInfo : nsISupports +{ + typedef int nsDocShellInfoLoadType; + + nsresult GetReferrer(nsIURI **aReferrer); + nsresult SetReferrer(nsIURI *aReferrer); + nsresult GetOwner(nsISupports **aOwner); + nsresult SetOwner(nsISupports *aOwner); + nsresult GetInheritOwner(bool *aInheritOwner); + nsresult SetInheritOwner(bool aInheritOwner); + nsresult GetOwnerIsExplicit(bool *aOwnerIsExplicit); + nsresult SetOwnerIsExplicit(bool aOwnerIsExplicit); + nsresult GetLoadType(nsDocShellInfoLoadType *aLoadType); + nsresult SetLoadType(nsDocShellInfoLoadType aLoadType); + nsresult GetSHEntry(nsISHEntry **aSHEntry); + nsresult SetSHEntry(nsISHEntry *aSHEntry); + nsresult GetTarget(char16_t **aTarget); + nsresult SetTarget(const char16_t * aTarget); + nsresult GetPostDataStream(nsIInputStream **aPostDataStream); + nsresult SetPostDataStream(nsIInputStream *aPostDataStream); + nsresult GetHeadersStream(nsIInputStream * *aHeadersStream); + nsresult SetHeadersStream(nsIInputStream *aHeadersStream); + nsresult GetSendReferrer(bool *aSendReferrer); + nsresult SetSendReferrer(bool aSendReferrer); + nsresult GetIsSrcdocLoad(bool *aIsSrcdocLoad); + nsresult GetSrcdocData(nsAString *aSrcdocData); + nsresult SetSrcdocData(const nsAString *aSrcdocData); + nsresult GetSourceDocShell(nsIDocShell * *aSourceDocShell); + nsresult SetSourceDocShell(nsIDocShell *aSourceDocShell); + nsresult GetBaseURI(nsIURI **aBaseURI); + nsresult SetBaseURI(nsIURI *aBaseURI); +} + [ object, uuid(3646c915-df79-4500-8b57-c65ab9c3b39f), diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index 44662b50694..0c151c405dd 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -268,8 +268,10 @@ static nsresult before_async_open(nsChannel *channel, NSContainer *container, BO return NS_OK; } -HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsChannelBSC *channelbsc, DWORD flags) +HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsIInputStream *post_stream, + nsChannelBSC *channelbsc, DWORD flags) { + nsIDocShellLoadInfo *load_info = NULL; nsIWebNavigation *web_navigation; nsIDocShell *doc_shell; HTMLDocumentNode *doc; @@ -288,14 +290,27 @@ HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsChannelBSC *channe return E_FAIL; } + if(post_stream) { + nsres = nsIDocShell_CreateLoadInfo(doc_shell, &load_info); + if(NS_FAILED(nsres)) { + nsIDocShell_Release(doc_shell); + return E_FAIL; + } + + nsres = nsIDocShellLoadInfo_SetPostDataStream(load_info, post_stream); + assert(nsres == NS_OK); + } + uri->channel_bsc = channelbsc; doc = window->base.inner_window->doc; doc->skip_mutation_notif = TRUE; - nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, NULL, flags, FALSE); + nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, load_info, flags, FALSE); if(doc == window->base.inner_window->doc) doc->skip_mutation_notif = FALSE; uri->channel_bsc = NULL; nsIDocShell_Release(doc_shell); + if(load_info) + nsIDocShellLoadInfo_Release(load_info); if(NS_FAILED(nsres)) { WARN("LoadURI failed: %08x\n", nsres); return E_FAIL; diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 5123e6cdfd4..1263f4347e7 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -398,7 +398,7 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind remove_target_tasks(window->base.inner_window->task_magic); abort_window_bindings(window->base.inner_window); - hres = load_nsuri(window, nsuri, bscallback, LOAD_FLAGS_BYPASS_CACHE); + hres = load_nsuri(window, nsuri, NULL, bscallback, LOAD_FLAGS_BYPASS_CACHE); nsISupports_Release((nsISupports*)nsuri); /* FIXME */ if(SUCCEEDED(hres)) { hres = create_pending_window(window, bscallback);