mshtml: Use our submit implementation for all windows, but only for POST method.

This commit is contained in:
Jacek Caban 2015-02-02 13:43:49 +01:00 committed by Alexandre Julliard
parent 4a6743e913
commit f0fc2ba27d
6 changed files with 111 additions and 11 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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),

View File

@ -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;

View File

@ -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);