2 * Copyright 2006-2010 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
35 #include "wine/debug.h"
37 #include "mshtml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
42 #define NS_IOSERVICE_CLASSNAME "nsIOService"
43 #define NS_IOSERVICE_CONTRACTID "@mozilla.org/network/io-service;1"
45 static const IID NS_IOSERVICE_CID =
46 {0x9ac9e770, 0x18bc, 0x11d3, {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
47 static const IID IID_nsWineURI =
48 {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};
50 static nsIIOService *nsio = NULL;
51 static nsINetUtil *net_util;
53 static const char *request_method_strings[] = {"GET", "PUT", "POST"};
62 NSContainer *container;
63 windowref_t *window_ref;
64 nsChannelBSC *channel_bsc;
66 IUriBuilder *uri_builder;
70 static BOOL ensure_uri(nsWineURI *This)
74 assert(This->uri || This->uri_builder);
77 hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
79 WARN("CreateUriSimple failed: %08x\n", hres);
87 IUri *nsuri_get_uri(nsWineURI *nsuri)
89 if(!ensure_uri(nsuri))
92 IUri_AddRef(nsuri->uri);
96 static IUri *get_uri_nofrag(IUri *uri)
98 IUriBuilder *uri_builder;
103 hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
104 if(SUCCEEDED(hres) && !b) {
109 hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
113 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
115 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
116 IUriBuilder_Release(uri_builder);
123 BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
125 IUri *uri_nofrag1, *uri_nofrag2;
128 uri_nofrag1 = get_uri_nofrag(uri1);
132 uri_nofrag2 = get_uri_nofrag(uri2);
134 IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
135 IUri_Release(uri_nofrag2);
138 IUri_Release(uri_nofrag1);
142 static nsresult create_nsuri(IUri*,nsIURI*,HTMLWindow*,NSContainer*,nsWineURI**);
144 static const char *debugstr_nsacstr(const nsACString *nsstr)
148 nsACString_GetData(nsstr, &data);
149 return debugstr_a(data);
152 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
154 const WCHAR *ptr = nsuri;
156 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
158 if(!strncmpW(nsuri, wine_prefixW, sizeof(wine_prefixW)/sizeof(WCHAR)))
159 ptr += sizeof(wine_prefixW)/sizeof(WCHAR);
161 if(*ptr || ret_empty) {
162 *ret = SysAllocString(ptr);
164 return E_OUTOFMEMORY;
169 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
173 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
175 IOleCommandTarget *cmdtrg = NULL;
178 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
179 if(SUCCEEDED(hres)) {
180 VARIANT varUrl, varRes;
182 V_VT(&varUrl) = VT_BSTR;
183 V_BSTR(&varUrl) = url;
184 V_VT(&varRes) = VT_BOOL;
186 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
188 IOleCommandTarget_Release(cmdtrg);
190 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
191 TRACE("got VARIANT_FALSE, do not load\n");
199 static nsresult before_async_open(nsChannel *channel, NSContainer *container, BOOL *cancel)
201 HTMLDocumentObj *doc = container->doc;
207 NSContainer *container_iter = container;
209 hlnf = HLNF_OPENINNEWWINDOW;
210 while(!container_iter->doc)
211 container_iter = container_iter->parent;
212 doc = container_iter->doc;
220 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
222 return NS_ERROR_FAILURE;
227 b = !exec_shldocvw_67(doc, display_uri);
229 SysFreeString(display_uri);
235 hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, hlnf, cancel);
236 SysFreeString(display_uri);
242 HRESULT load_nsuri(HTMLWindow *window, nsWineURI *uri, nsChannelBSC *channelbsc, DWORD flags)
244 nsIWebNavigation *web_navigation;
245 nsIDocShell *doc_shell;
246 HTMLDocumentNode *doc;
249 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
250 if(NS_FAILED(nsres)) {
251 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
255 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
256 nsIWebNavigation_Release(web_navigation);
257 if(NS_FAILED(nsres)) {
258 ERR("Could not get nsIDocShell: %08x\n", nsres);
262 uri->channel_bsc = channelbsc;
264 doc->skip_mutation_notif = TRUE;
265 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIURL_iface, NULL, flags, FALSE);
266 if(doc == window->doc)
267 doc->skip_mutation_notif = FALSE;
268 uri->channel_bsc = NULL;
269 nsIDocShell_Release(doc_shell);
270 if(NS_FAILED(nsres)) {
271 WARN("LoadURI failed: %08x\n", nsres);
278 static void set_uri_nscontainer(nsWineURI *This, NSContainer *nscontainer)
280 if(This->container) {
281 if(This->container == nscontainer)
283 TRACE("Changing %p -> %p\n", This->container, nscontainer);
284 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
288 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
289 This->container = nscontainer;
292 static void set_uri_window(nsWineURI *This, HTMLWindow *window)
294 if(This->window_ref) {
295 if(This->window_ref->window == window)
297 TRACE("Changing %p -> %p\n", This->window_ref->window, window);
298 windowref_release(This->window_ref);
302 windowref_addref(window->window_ref);
303 This->window_ref = window->window_ref;
306 set_uri_nscontainer(This, window->doc_obj->nscontainer);
308 This->window_ref = NULL;
312 static inline BOOL is_http_channel(nsChannel *This)
314 return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTPS;
317 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
321 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
322 if(!strcmpiW(iter->header, name))
329 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
332 const char *header_namea;
333 http_header_t *header;
337 nsACString_GetData(header_name_str, &header_namea);
338 header_name = heap_strdupAtoW(header_namea);
340 return NS_ERROR_UNEXPECTED;
342 header = find_http_header(headers, header_name, strlenW(header_name));
343 heap_free(header_name);
345 return NS_ERROR_NOT_AVAILABLE;
347 data = heap_strdupWtoA(header->data);
349 return NS_ERROR_UNEXPECTED;
351 nsACString_SetData(_retval, data);
356 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
357 const WCHAR *value, int value_len)
359 http_header_t *header;
361 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
363 header = find_http_header(headers, name, name_len);
367 new_data = heap_strndupW(value, value_len);
369 return E_OUTOFMEMORY;
371 heap_free(header->data);
372 header->data = new_data;
374 header = heap_alloc(sizeof(http_header_t));
376 return E_OUTOFMEMORY;
378 header->header = heap_strndupW(name, name_len);
379 header->data = heap_strndupW(value, value_len);
380 if(!header->header || !header->data) {
381 heap_free(header->header);
382 heap_free(header->data);
384 return E_OUTOFMEMORY;
387 list_add_tail(headers, &header->entry);
393 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
394 const nsACString *value_str)
396 const char *namea, *valuea;
400 nsACString_GetData(name_str, &namea);
401 name = heap_strdupAtoW(namea);
403 return NS_ERROR_UNEXPECTED;
405 nsACString_GetData(value_str, &valuea);
406 value = heap_strdupAtoW(valuea);
409 return NS_ERROR_UNEXPECTED;
412 hres = set_http_header(headers, name, strlenW(name), value, strlenW(value));
416 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
419 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
421 nsACString header_str, value_str;
422 char *header, *value;
426 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
427 header = heap_strdupWtoA(iter->header);
429 return NS_ERROR_OUT_OF_MEMORY;
431 value = heap_strdupWtoA(iter->data);
434 return NS_ERROR_OUT_OF_MEMORY;
437 nsACString_InitDepend(&header_str, header);
438 nsACString_InitDepend(&value_str, value);
439 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
440 nsACString_Finish(&header_str);
441 nsACString_Finish(&value_str);
451 static void free_http_headers(struct list *list)
453 http_header_t *iter, *iter_next;
455 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
456 list_remove(&iter->entry);
457 heap_free(iter->header);
458 heap_free(iter->data);
463 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
465 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
468 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
470 nsChannel *This = impl_from_nsIHttpChannel(iface);
472 if(IsEqualGUID(&IID_nsISupports, riid)) {
473 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
474 *result = &This->nsIHttpChannel_iface;
475 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
476 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
477 *result = &This->nsIHttpChannel_iface;
478 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
479 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
480 *result = &This->nsIHttpChannel_iface;
481 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
482 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
483 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
484 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
485 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
486 *result = &This->nsIUploadChannel_iface;
487 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
488 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
489 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
491 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
496 nsIChannel_AddRef(&This->nsIHttpChannel_iface);
500 return NS_NOINTERFACE;
503 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
505 nsChannel *This = impl_from_nsIHttpChannel(iface);
506 nsrefcnt ref = InterlockedIncrement(&This->ref);
508 TRACE("(%p) ref=%d\n", This, ref);
513 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
515 nsChannel *This = impl_from_nsIHttpChannel(iface);
516 LONG ref = InterlockedDecrement(&This->ref);
519 nsIURI_Release(&This->uri->nsIURL_iface);
521 nsISupports_Release(This->owner);
522 if(This->post_data_stream)
523 nsIInputStream_Release(This->post_data_stream);
525 nsILoadGroup_Release(This->load_group);
526 if(This->notif_callback)
527 nsIInterfaceRequestor_Release(This->notif_callback);
528 if(This->original_uri)
529 nsIURI_Release(This->original_uri);
531 nsIURI_Release(This->referrer);
533 free_http_headers(&This->response_headers);
534 free_http_headers(&This->request_headers);
536 heap_free(This->content_type);
537 heap_free(This->charset);
544 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
546 nsChannel *This = impl_from_nsIHttpChannel(iface);
548 TRACE("(%p)->(%p)\n", This, aName);
550 return nsIURI_GetSpec(&This->uri->nsIURL_iface, aName);
553 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, PRBool *_retval)
555 nsChannel *This = impl_from_nsIHttpChannel(iface);
557 FIXME("(%p)->(%p)\n", This, _retval);
559 return NS_ERROR_NOT_IMPLEMENTED;
562 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
564 nsChannel *This = impl_from_nsIHttpChannel(iface);
566 WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
568 return *aStatus = NS_OK;
571 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
573 nsChannel *This = impl_from_nsIHttpChannel(iface);
575 FIXME("(%p)->(%08x)\n", This, aStatus);
577 return NS_ERROR_NOT_IMPLEMENTED;
580 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
582 nsChannel *This = impl_from_nsIHttpChannel(iface);
584 FIXME("(%p)\n", This);
586 return NS_ERROR_NOT_IMPLEMENTED;
589 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
591 nsChannel *This = impl_from_nsIHttpChannel(iface);
593 FIXME("(%p)\n", This);
595 return NS_ERROR_NOT_IMPLEMENTED;
598 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
600 nsChannel *This = impl_from_nsIHttpChannel(iface);
602 TRACE("(%p)->(%p)\n", This, aLoadGroup);
605 nsILoadGroup_AddRef(This->load_group);
607 *aLoadGroup = This->load_group;
611 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
613 nsChannel *This = impl_from_nsIHttpChannel(iface);
615 TRACE("(%p)->(%p)\n", This, aLoadGroup);
618 nsILoadGroup_Release(This->load_group);
620 nsILoadGroup_AddRef(aLoadGroup);
621 This->load_group = aLoadGroup;
626 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
628 nsChannel *This = impl_from_nsIHttpChannel(iface);
630 TRACE("(%p)->(%p)\n", This, aLoadFlags);
632 *aLoadFlags = This->load_flags;
636 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
638 nsChannel *This = impl_from_nsIHttpChannel(iface);
640 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
642 This->load_flags = aLoadFlags;
646 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
648 nsChannel *This = impl_from_nsIHttpChannel(iface);
650 TRACE("(%p)->(%p)\n", This, aOriginalURI);
652 if(This->original_uri)
653 nsIURI_AddRef(This->original_uri);
655 *aOriginalURI = This->original_uri;
659 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
661 nsChannel *This = impl_from_nsIHttpChannel(iface);
663 TRACE("(%p)->(%p)\n", This, aOriginalURI);
665 if(This->original_uri)
666 nsIURI_Release(This->original_uri);
668 nsIURI_AddRef(aOriginalURI);
669 This->original_uri = aOriginalURI;
673 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
675 nsChannel *This = impl_from_nsIHttpChannel(iface);
677 TRACE("(%p)->(%p)\n", This, aURI);
679 nsIURI_AddRef(&This->uri->nsIURL_iface);
680 *aURI = (nsIURI*)This->uri;
685 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
687 nsChannel *This = impl_from_nsIHttpChannel(iface);
689 TRACE("(%p)->(%p)\n", This, aOwner);
692 nsISupports_AddRef(This->owner);
693 *aOwner = This->owner;
698 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
700 nsChannel *This = impl_from_nsIHttpChannel(iface);
702 TRACE("(%p)->(%p)\n", This, aOwner);
705 nsISupports_AddRef(aOwner);
707 nsISupports_Release(This->owner);
708 This->owner = aOwner;
713 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
714 nsIInterfaceRequestor **aNotificationCallbacks)
716 nsChannel *This = impl_from_nsIHttpChannel(iface);
718 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
720 if(This->notif_callback)
721 nsIInterfaceRequestor_AddRef(This->notif_callback);
722 *aNotificationCallbacks = This->notif_callback;
727 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
728 nsIInterfaceRequestor *aNotificationCallbacks)
730 nsChannel *This = impl_from_nsIHttpChannel(iface);
732 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
734 if(This->notif_callback)
735 nsIInterfaceRequestor_Release(This->notif_callback);
736 if(aNotificationCallbacks)
737 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
739 This->notif_callback = aNotificationCallbacks;
744 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
746 nsChannel *This = impl_from_nsIHttpChannel(iface);
748 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
750 return NS_ERROR_NOT_IMPLEMENTED;
753 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
755 nsChannel *This = impl_from_nsIHttpChannel(iface);
757 TRACE("(%p)->(%p)\n", This, aContentType);
759 if(This->content_type) {
760 nsACString_SetData(aContentType, This->content_type);
764 WARN("unknown type\n");
765 return NS_ERROR_FAILURE;
768 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
769 const nsACString *aContentType)
771 nsChannel *This = impl_from_nsIHttpChannel(iface);
772 const char *content_type;
774 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
776 nsACString_GetData(aContentType, &content_type);
777 heap_free(This->content_type);
778 This->content_type = heap_strdupA(content_type);
783 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
784 nsACString *aContentCharset)
786 nsChannel *This = impl_from_nsIHttpChannel(iface);
788 TRACE("(%p)->(%p)\n", This, aContentCharset);
791 nsACString_SetData(aContentCharset, This->charset);
795 nsACString_SetData(aContentCharset, "");
799 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
800 const nsACString *aContentCharset)
802 nsChannel *This = impl_from_nsIHttpChannel(iface);
804 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
806 return NS_ERROR_NOT_IMPLEMENTED;
809 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, PRInt32 *aContentLength)
811 nsChannel *This = impl_from_nsIHttpChannel(iface);
813 FIXME("(%p)->(%p)\n", This, aContentLength);
815 return NS_ERROR_NOT_IMPLEMENTED;
818 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, PRInt32 aContentLength)
820 nsChannel *This = impl_from_nsIHttpChannel(iface);
822 FIXME("(%p)->(%d)\n", This, aContentLength);
824 return NS_ERROR_NOT_IMPLEMENTED;
827 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
829 nsChannel *This = impl_from_nsIHttpChannel(iface);
831 FIXME("(%p)->(%p)\n", This, _retval);
833 return NS_ERROR_NOT_IMPLEMENTED;
836 static HTMLWindow *get_window_from_load_group(nsChannel *This)
845 nsres = nsILoadGroup_GetDefaultLoadRequest(This->load_group, &req);
846 if(NS_FAILED(nsres)) {
847 ERR("GetDefaultLoadRequest failed: %08x\n", nsres);
854 nsres = nsIRequest_QueryInterface(req, &IID_nsIChannel, (void**)&channel);
855 nsIRequest_Release(req);
856 if(NS_FAILED(nsres)) {
857 WARN("Could not get nsIChannel interface: %08x\n", nsres);
861 nsres = nsIChannel_GetURI(channel, &uri);
862 nsIChannel_Release(channel);
863 if(NS_FAILED(nsres)) {
864 ERR("GetURI failed: %08x\n", nsres);
868 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
870 if(NS_FAILED(nsres)) {
871 TRACE("Could not get nsWineURI: %08x\n", nsres);
875 window = wine_uri->window_ref ? wine_uri->window_ref->window : NULL;
877 IHTMLWindow2_AddRef(&window->IHTMLWindow2_iface);
878 nsIURI_Release(&wine_uri->nsIURL_iface);
883 static HTMLWindow *get_channel_window(nsChannel *This)
885 nsIWebProgress *web_progress;
886 nsIDOMWindow *nswindow;
890 if(This->load_group) {
891 nsIRequestObserver *req_observer;
893 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
894 if(NS_FAILED(nsres) || !req_observer) {
895 ERR("GetGroupObserver failed: %08x\n", nsres);
899 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
900 nsIRequestObserver_Release(req_observer);
901 if(NS_FAILED(nsres)) {
902 ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
905 }else if(This->notif_callback) {
906 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
907 if(NS_FAILED(nsres)) {
908 ERR("GetInterface(IID_nsIWebProgress failed: %08x\n", nsres);
912 ERR("no load group nor notif callback\n");
916 nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
917 nsIWebProgress_Release(web_progress);
918 if(NS_FAILED(nsres) || !nswindow) {
919 ERR("GetDOMWindow failed: %08x\n", nsres);
923 window = nswindow_to_window(nswindow);
924 nsIDOMWindow_Release(nswindow);
927 IHTMLWindow2_AddRef(&window->IHTMLWindow2_iface);
929 FIXME("NULL window for %p\n", nswindow);
935 HTMLDocumentNode *doc;
936 nsChannelBSC *bscallback;
937 } start_binding_task_t;
939 static void start_binding_proc(task_t *_task)
941 start_binding_task_t *task = (start_binding_task_t*)_task;
943 start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL);
946 static void start_binding_task_destr(task_t *_task)
948 start_binding_task_t *task = (start_binding_task_t*)_task;
950 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
954 static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
955 nsISupports *context)
957 nsChannelBSC *bscallback;
958 IMoniker *mon = NULL;
961 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
963 WARN("CreateURLMoniker failed: %08x\n", hres);
964 return NS_ERROR_UNEXPECTED;
968 set_current_mon(window, mon);
970 hres = create_channelbsc(mon, NULL, NULL, 0, &bscallback);
971 IMoniker_Release(mon);
973 return NS_ERROR_UNEXPECTED;
975 channelbsc_set_channel(bscallback, This, listener, context);
978 set_window_bscallback(window, bscallback);
979 async_start_doc_binding(window, bscallback);
980 IUnknown_Release((IUnknown*)bscallback);
982 start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t));
984 task->doc = window->doc;
985 task->bscallback = bscallback;
986 push_task(&task->header, start_binding_proc, start_binding_task_destr, window->doc->basedoc.task_magic);
992 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
993 nsISupports *aContext)
995 nsChannel *This = impl_from_nsIHttpChannel(iface);
996 HTMLWindow *window = NULL;
998 nsresult nsres = NS_OK;
1000 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1002 if(!ensure_uri(This->uri))
1003 return NS_ERROR_FAILURE;
1005 if(TRACE_ON(mshtml)) {
1007 IUri_GetDisplayUri(This->uri->uri, &uri_str);
1008 TRACE("opening %s\n", debugstr_w(uri_str));
1009 SysFreeString(uri_str);
1012 if(This->uri->is_doc_uri) {
1013 window = get_channel_window(This);
1015 set_uri_window(This->uri, window);
1016 }else if(This->uri->container) {
1019 /* nscontainer->doc should be NULL which means navigation to a new window */
1020 if(This->uri->container->doc)
1021 FIXME("nscontainer->doc = %p\n", This->uri->container->doc);
1023 nsres = before_async_open(This, This->uri->container, &b);
1024 if(NS_FAILED(nsres))
1027 FIXME("Navigation not cancelled\n");
1028 return NS_ERROR_UNEXPECTED;
1033 if(This->uri->window_ref && This->uri->window_ref->window) {
1034 window = This->uri->window_ref->window;
1035 IHTMLWindow2_AddRef(&window->IHTMLWindow2_iface);
1037 /* FIXME: Analyze removing get_window_from_load_group call */
1038 if(This->load_group)
1039 window = get_window_from_load_group(This);
1041 window = get_channel_window(This);
1043 set_uri_window(This->uri, window);
1048 ERR("window = NULL\n");
1049 return NS_ERROR_UNEXPECTED;
1052 if(This->uri->is_doc_uri && window == window->doc_obj->basedoc.window) {
1053 if(This->uri->channel_bsc) {
1054 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1056 if(window->doc_obj->mime) {
1057 heap_free(This->content_type);
1058 This->content_type = heap_strdupWtoA(window->doc_obj->mime);
1063 nsres = before_async_open(This, window->doc_obj->nscontainer, &cancel);
1064 if(NS_SUCCEEDED(nsres) && cancel) {
1065 TRACE("canceled\n");
1066 nsres = NS_BINDING_ABORTED;
1072 nsres = async_open(This, window, This->uri->is_doc_uri, aListener, aContext);
1074 if(NS_SUCCEEDED(nsres) && This->load_group) {
1075 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1077 if(NS_FAILED(nsres))
1078 ERR("AddRequest failed: %08x\n", nsres);
1081 IHTMLWindow2_Release(&window->IHTMLWindow2_iface);
1085 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1087 nsChannel *This = impl_from_nsIHttpChannel(iface);
1089 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1091 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1095 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1096 const nsACString *aRequestMethod)
1098 nsChannel *This = impl_from_nsIHttpChannel(iface);
1102 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1104 nsACString_GetData(aRequestMethod, &method);
1105 for(i=0; i < sizeof(request_method_strings)/sizeof(*request_method_strings); i++) {
1106 if(!strcasecmp(method, request_method_strings[i])) {
1107 This->request_method = i;
1112 ERR("Invalid method %s\n", debugstr_a(method));
1113 return NS_ERROR_UNEXPECTED;
1116 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1118 nsChannel *This = impl_from_nsIHttpChannel(iface);
1120 TRACE("(%p)->(%p)\n", This, aReferrer);
1123 nsIURI_AddRef(This->referrer);
1124 *aReferrer = This->referrer;
1128 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1130 nsChannel *This = impl_from_nsIHttpChannel(iface);
1132 TRACE("(%p)->(%p)\n", This, aReferrer);
1135 nsIURI_AddRef(aReferrer);
1137 nsIURI_Release(This->referrer);
1138 This->referrer = aReferrer;
1142 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1143 const nsACString *aHeader, nsACString *_retval)
1145 nsChannel *This = impl_from_nsIHttpChannel(iface);
1147 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1149 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1152 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1153 const nsACString *aHeader, const nsACString *aValue, PRBool aMerge)
1155 nsChannel *This = impl_from_nsIHttpChannel(iface);
1157 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1160 FIXME("aMerge not supported\n");
1162 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1165 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1166 nsIHttpHeaderVisitor *aVisitor)
1168 nsChannel *This = impl_from_nsIHttpChannel(iface);
1170 FIXME("(%p)->(%p)\n", This, aVisitor);
1172 return NS_ERROR_NOT_IMPLEMENTED;
1175 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, PRBool *aAllowPipelining)
1177 nsChannel *This = impl_from_nsIHttpChannel(iface);
1179 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1181 return NS_ERROR_NOT_IMPLEMENTED;
1184 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, PRBool aAllowPipelining)
1186 nsChannel *This = impl_from_nsIHttpChannel(iface);
1188 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1190 return NS_ERROR_NOT_IMPLEMENTED;
1193 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, PRUint32 *aRedirectionLimit)
1195 nsChannel *This = impl_from_nsIHttpChannel(iface);
1197 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1199 return NS_ERROR_NOT_IMPLEMENTED;
1202 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, PRUint32 aRedirectionLimit)
1204 nsChannel *This = impl_from_nsIHttpChannel(iface);
1206 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1208 return NS_ERROR_NOT_IMPLEMENTED;
1211 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, PRUint32 *aResponseStatus)
1213 nsChannel *This = impl_from_nsIHttpChannel(iface);
1215 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1217 if(This->response_status) {
1218 *aResponseStatus = This->response_status;
1222 WARN("No response status\n");
1223 return NS_ERROR_UNEXPECTED;
1226 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1227 nsACString *aResponseStatusText)
1229 nsChannel *This = impl_from_nsIHttpChannel(iface);
1231 FIXME("(%p)->(%p)\n", This, aResponseStatusText);
1233 return NS_ERROR_NOT_IMPLEMENTED;
1236 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1237 PRBool *aRequestSucceeded)
1239 nsChannel *This = impl_from_nsIHttpChannel(iface);
1241 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1243 if(!This->response_status)
1244 return NS_ERROR_NOT_AVAILABLE;
1246 *aRequestSucceeded = This->response_status/100 == 2;
1251 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1252 const nsACString *header, nsACString *_retval)
1254 nsChannel *This = impl_from_nsIHttpChannel(iface);
1256 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1258 return get_channel_http_header(&This->response_headers, header, _retval);
1261 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1262 const nsACString *header, const nsACString *value, PRBool merge)
1264 nsChannel *This = impl_from_nsIHttpChannel(iface);
1266 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1268 return NS_ERROR_NOT_IMPLEMENTED;
1271 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1272 nsIHttpHeaderVisitor *aVisitor)
1274 nsChannel *This = impl_from_nsIHttpChannel(iface);
1276 TRACE("(%p)->(%p)\n", This, aVisitor);
1278 return visit_http_headers(&This->response_headers, aVisitor);
1281 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, PRBool *_retval)
1283 nsChannel *This = impl_from_nsIHttpChannel(iface);
1284 http_header_t *header;
1286 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1287 static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};
1289 TRACE("(%p)->(%p)\n", This, _retval);
1291 header = find_http_header(&This->response_headers, cache_controlW, sizeof(cache_controlW)/sizeof(WCHAR));
1292 *_retval = header && !strcmpiW(header->data, no_storeW);
1296 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, PRBool *_retval)
1298 nsChannel *This = impl_from_nsIHttpChannel(iface);
1300 FIXME("(%p)->(%p)\n", This, _retval);
1302 return NS_ERROR_NOT_IMPLEMENTED;
1305 static const nsIHttpChannelVtbl nsChannelVtbl = {
1306 nsChannel_QueryInterface,
1310 nsChannel_IsPending,
1311 nsChannel_GetStatus,
1315 nsChannel_GetLoadGroup,
1316 nsChannel_SetLoadGroup,
1317 nsChannel_GetLoadFlags,
1318 nsChannel_SetLoadFlags,
1319 nsChannel_GetOriginalURI,
1320 nsChannel_SetOriginalURI,
1324 nsChannel_GetNotificationCallbacks,
1325 nsChannel_SetNotificationCallbacks,
1326 nsChannel_GetSecurityInfo,
1327 nsChannel_GetContentType,
1328 nsChannel_SetContentType,
1329 nsChannel_GetContentCharset,
1330 nsChannel_SetContentCharset,
1331 nsChannel_GetContentLength,
1332 nsChannel_SetContentLength,
1334 nsChannel_AsyncOpen,
1335 nsChannel_GetRequestMethod,
1336 nsChannel_SetRequestMethod,
1337 nsChannel_GetReferrer,
1338 nsChannel_SetReferrer,
1339 nsChannel_GetRequestHeader,
1340 nsChannel_SetRequestHeader,
1341 nsChannel_VisitRequestHeaders,
1342 nsChannel_GetAllowPipelining,
1343 nsChannel_SetAllowPipelining,
1344 nsChannel_GetRedirectionLimit,
1345 nsChannel_SetRedirectionLimit,
1346 nsChannel_GetResponseStatus,
1347 nsChannel_GetResponseStatusText,
1348 nsChannel_GetRequestSucceeded,
1349 nsChannel_GetResponseHeader,
1350 nsChannel_SetResponseHeader,
1351 nsChannel_VisitResponseHeaders,
1352 nsChannel_IsNoStoreResponse,
1353 nsChannel_IsNoCacheResponse
1356 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1358 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1361 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1364 nsChannel *This = impl_from_nsIUploadChannel(iface);
1365 return nsIChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1368 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1370 nsChannel *This = impl_from_nsIUploadChannel(iface);
1371 return nsIChannel_AddRef(&This->nsIHttpChannel_iface);
1374 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1376 nsChannel *This = impl_from_nsIUploadChannel(iface);
1377 return nsIChannel_Release(&This->nsIHttpChannel_iface);
1380 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1381 nsIInputStream *aStream, const nsACString *aContentType, PRInt32 aContentLength)
1383 nsChannel *This = impl_from_nsIUploadChannel(iface);
1384 const char *content_type;
1386 static const WCHAR content_typeW[] =
1387 {'C','o','n','t','e','n','t','-','T','y','p','e',0};
1389 TRACE("(%p)->(%p %s %d)\n", This, aStream, debugstr_nsacstr(aContentType), aContentLength);
1391 This->post_data_contains_headers = TRUE;
1394 nsACString_GetData(aContentType, &content_type);
1398 ct = heap_strdupAtoW(content_type);
1400 return NS_ERROR_UNEXPECTED;
1402 set_http_header(&This->request_headers, content_typeW,
1403 sizeof(content_typeW)/sizeof(WCHAR), ct, strlenW(ct));
1405 This->post_data_contains_headers = FALSE;
1409 if(This->post_data_stream)
1410 nsIInputStream_Release(This->post_data_stream);
1412 if(aContentLength != -1)
1413 FIXME("Unsupported acontentLength = %d\n", aContentLength);
1415 if(This->post_data_stream)
1416 nsIInputStream_Release(This->post_data_stream);
1417 This->post_data_stream = aStream;
1419 nsIInputStream_AddRef(aStream);
1421 This->request_method = METHOD_POST;
1425 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1426 nsIInputStream **aUploadStream)
1428 nsChannel *This = impl_from_nsIUploadChannel(iface);
1430 TRACE("(%p)->(%p)\n", This, aUploadStream);
1432 if(This->post_data_stream)
1433 nsIInputStream_AddRef(This->post_data_stream);
1435 *aUploadStream = This->post_data_stream;
1439 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1440 nsUploadChannel_QueryInterface,
1441 nsUploadChannel_AddRef,
1442 nsUploadChannel_Release,
1443 nsUploadChannel_SetUploadStream,
1444 nsUploadChannel_GetUploadStream
1447 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1449 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1452 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1455 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1456 return nsIChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1459 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1461 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1462 return nsIChannel_AddRef(&This->nsIHttpChannel_iface);
1465 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1467 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1468 return nsIChannel_Release(&This->nsIHttpChannel_iface);
1471 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1473 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1475 FIXME("(%p)->()\n", This);
1477 return NS_ERROR_NOT_IMPLEMENTED;
1480 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1482 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1484 FIXME("(%p)->()\n", This);
1486 return NS_ERROR_NOT_IMPLEMENTED;
1489 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
1491 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1493 FIXME("(%p)->()\n", This);
1495 return NS_ERROR_NOT_IMPLEMENTED;
1498 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
1500 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1502 FIXME("(%p)->()\n", This);
1504 return NS_ERROR_NOT_IMPLEMENTED;
1507 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1509 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1511 FIXME("(%p)->()\n", This);
1513 return NS_ERROR_NOT_IMPLEMENTED;
1516 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1518 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1520 FIXME("(%p)->()\n", This);
1522 return NS_ERROR_NOT_IMPLEMENTED;
1525 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool *aForceThirdPartyCookie)
1527 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1529 FIXME("(%p)->()\n", This);
1531 return NS_ERROR_NOT_IMPLEMENTED;
1534 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool aForceThirdPartyCookie)
1536 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1538 FIXME("(%p)->()\n", This);
1540 return NS_ERROR_NOT_IMPLEMENTED;
1543 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, PRBool *aCanceled)
1545 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1547 FIXME("(%p)->(%p)\n", This, aCanceled);
1549 return NS_ERROR_NOT_IMPLEMENTED;
1552 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, PRBool *aCanceled)
1554 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1556 FIXME("(%p)->(%p)\n", This, aCanceled);
1558 return NS_ERROR_NOT_IMPLEMENTED;
1561 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, PRBool aCanceled)
1563 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1565 FIXME("(%p)->(%x)\n", This, aCanceled);
1567 return NS_ERROR_NOT_IMPLEMENTED;
1570 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1572 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1574 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1576 return NS_ERROR_NOT_IMPLEMENTED;
1579 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, PRInt32 *aLocalPort)
1581 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1583 FIXME("(%p)->(%p)\n", This, aLocalPort);
1585 return NS_ERROR_NOT_IMPLEMENTED;
1588 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1590 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1592 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1594 return NS_ERROR_NOT_IMPLEMENTED;
1597 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, PRInt32 *aRemotePort)
1599 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1601 FIXME("(%p)->(%p)\n", This, aRemotePort);
1603 return NS_ERROR_NOT_IMPLEMENTED;
1606 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1608 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1610 FIXME("(%p)->(%p)\n", This, cacheKeys);
1612 return NS_ERROR_NOT_IMPLEMENTED;
1615 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
1616 nsHttpChannelInternal_QueryInterface,
1617 nsHttpChannelInternal_AddRef,
1618 nsHttpChannelInternal_Release,
1619 nsHttpChannelInternal_GetDocumentURI,
1620 nsHttpChannelInternal_SetDocumentURI,
1621 nsHttpChannelInternal_GetRequestVersion,
1622 nsHttpChannelInternal_GetResponseVersion,
1623 nsHttpChannelInternal_SetCookie,
1624 nsHttpChannelInternal_SetupFallbackChannel,
1625 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
1626 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
1627 nsHttpChannelInternal_GetCanceled,
1628 nsHttpChannelInternal_GetChannelIsForDownload,
1629 nsHttpChannelInternal_SetChannelIsForDownload,
1630 nsHttpChannelInternal_GetLocalAddress,
1631 nsHttpChannelInternal_GetLocalPort,
1632 nsHttpChannelInternal_GetRemoteAddress,
1633 nsHttpChannelInternal_GetRemotePort,
1634 nsHttpChannelInternal_SetCacheKeysRedirectChain
1638 static void invalidate_uri(nsWineURI *This)
1641 IUri_Release(This->uri);
1646 static BOOL ensure_uri_builder(nsWineURI *This)
1648 if(!This->uri_builder) {
1651 if(!ensure_uri(This))
1654 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
1656 WARN("CreateIUriBuilder failed: %08x\n", hres);
1661 invalidate_uri(This);
1665 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
1671 if(!ensure_uri(This))
1672 return NS_ERROR_UNEXPECTED;
1674 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
1676 WARN("GetPropertyBSTR failed: %08x\n", hres);
1677 return NS_ERROR_UNEXPECTED;
1680 vala = heap_strdupWtoA(val);
1683 return NS_ERROR_OUT_OF_MEMORY;
1685 TRACE("ret %s\n", debugstr_a(vala));
1686 nsACString_SetData(ret, vala);
1691 static inline nsWineURI *impl_from_nsIURL(nsIURL *iface)
1693 return CONTAINING_RECORD(iface, nsWineURI, nsIURL_iface);
1696 static nsresult NSAPI nsURI_QueryInterface(nsIURL *iface, nsIIDRef riid, void **result)
1698 nsWineURI *This = impl_from_nsIURL(iface);
1702 if(IsEqualGUID(&IID_nsISupports, riid)) {
1703 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
1704 *result = &This->nsIURL_iface;
1705 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
1706 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
1707 *result = &This->nsIURL_iface;
1708 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
1709 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
1710 *result = &This->nsIURL_iface;
1711 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
1712 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
1717 nsIURI_AddRef(&This->nsIURL_iface);
1721 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1722 return This->nsuri ? nsIURI_QueryInterface(This->nsuri, riid, result) : NS_NOINTERFACE;
1725 static nsrefcnt NSAPI nsURI_AddRef(nsIURL *iface)
1727 nsWineURI *This = impl_from_nsIURL(iface);
1728 LONG ref = InterlockedIncrement(&This->ref);
1730 TRACE("(%p) ref=%d\n", This, ref);
1735 static nsrefcnt NSAPI nsURI_Release(nsIURL *iface)
1737 nsWineURI *This = impl_from_nsIURL(iface);
1738 LONG ref = InterlockedDecrement(&This->ref);
1740 TRACE("(%p) ref=%d\n", This, ref);
1743 if(This->window_ref)
1744 windowref_release(This->window_ref);
1746 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
1748 nsIURL_Release(This->nsurl);
1750 nsIURI_Release(This->nsuri);
1752 IUri_Release(This->uri);
1759 static nsresult NSAPI nsURI_GetSpec(nsIURL *iface, nsACString *aSpec)
1761 nsWineURI *This = impl_from_nsIURL(iface);
1763 TRACE("(%p)->(%p)\n", This, aSpec);
1765 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
1768 static nsresult NSAPI nsURI_SetSpec(nsIURL *iface, const nsACString *aSpec)
1770 nsWineURI *This = impl_from_nsIURL(iface);
1776 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
1778 nsACString_GetData(aSpec, &speca);
1779 spec = heap_strdupAtoW(speca);
1781 return NS_ERROR_OUT_OF_MEMORY;
1783 hres = CreateUri(spec, 0, 0, &uri);
1786 WARN("CreateUri failed: %08x\n", hres);
1787 return NS_ERROR_FAILURE;
1790 invalidate_uri(This);
1791 if(This->uri_builder) {
1792 IUriBuilder_Release(This->uri_builder);
1793 This->uri_builder = NULL;
1800 static nsresult NSAPI nsURI_GetPrePath(nsIURL *iface, nsACString *aPrePath)
1802 nsWineURI *This = impl_from_nsIURL(iface);
1804 TRACE("(%p)->(%p)\n", This, aPrePath);
1807 return nsIURI_GetPrePath(This->nsuri, aPrePath);
1809 FIXME("default action not implemented\n");
1810 return NS_ERROR_NOT_IMPLEMENTED;
1813 static nsresult NSAPI nsURI_GetScheme(nsIURL *iface, nsACString *aScheme)
1815 nsWineURI *This = impl_from_nsIURL(iface);
1819 TRACE("(%p)->(%p)\n", This, aScheme);
1821 if(!ensure_uri(This))
1822 return NS_ERROR_UNEXPECTED;
1824 hres = IUri_GetScheme(This->uri, &scheme);
1826 WARN("GetScheme failed: %08x\n", hres);
1827 return NS_ERROR_UNEXPECTED;
1830 if(scheme == URL_SCHEME_ABOUT) {
1831 nsACString_SetData(aScheme, "wine");
1835 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
1838 static nsresult NSAPI nsURI_SetScheme(nsIURL *iface, const nsACString *aScheme)
1840 nsWineURI *This = impl_from_nsIURL(iface);
1841 const char *schemea;
1845 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
1847 if(!ensure_uri_builder(This))
1848 return NS_ERROR_UNEXPECTED;
1850 nsACString_GetData(aScheme, &schemea);
1851 scheme = heap_strdupAtoW(schemea);
1853 return NS_ERROR_OUT_OF_MEMORY;
1855 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
1858 return NS_ERROR_UNEXPECTED;
1863 static nsresult NSAPI nsURI_GetUserPass(nsIURL *iface, nsACString *aUserPass)
1865 nsWineURI *This = impl_from_nsIURL(iface);
1869 TRACE("(%p)->(%p)\n", This, aUserPass);
1871 if(!ensure_uri(This))
1872 return NS_ERROR_UNEXPECTED;
1874 hres = IUri_GetUserName(This->uri, &user);
1876 return NS_ERROR_FAILURE;
1878 hres = IUri_GetPassword(This->uri, &pass);
1880 SysFreeString(user);
1881 return NS_ERROR_FAILURE;
1884 if(*user || *pass) {
1885 FIXME("Construct user:pass string\n");
1887 nsACString_SetData(aUserPass, "");
1890 SysFreeString(user);
1891 SysFreeString(pass);
1895 static nsresult NSAPI nsURI_SetUserPass(nsIURL *iface, const nsACString *aUserPass)
1897 nsWineURI *This = impl_from_nsIURL(iface);
1898 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
1899 const char *user_pass;
1902 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
1904 if(!ensure_uri_builder(This))
1905 return NS_ERROR_UNEXPECTED;
1907 nsACString_GetData(aUserPass, &user_pass);
1911 buf = heap_strdupAtoW(user_pass);
1913 return NS_ERROR_OUT_OF_MEMORY;
1915 ptr = strchrW(buf, ':');
1918 }else if(ptr != buf) {
1928 hres = IUriBuilder_SetUserName(This->uri_builder, user);
1930 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
1933 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
1936 static nsresult NSAPI nsURI_GetUsername(nsIURL *iface, nsACString *aUsername)
1938 nsWineURI *This = impl_from_nsIURL(iface);
1940 TRACE("(%p)->(%p)\n", This, aUsername);
1942 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
1945 static nsresult NSAPI nsURI_SetUsername(nsIURL *iface, const nsACString *aUsername)
1947 nsWineURI *This = impl_from_nsIURL(iface);
1952 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
1954 if(!ensure_uri_builder(This))
1955 return NS_ERROR_UNEXPECTED;
1957 nsACString_GetData(aUsername, &usera);
1958 user = heap_strdupAtoW(usera);
1960 return NS_ERROR_OUT_OF_MEMORY;
1962 hres = IUriBuilder_SetUserName(This->uri_builder, user);
1965 return NS_ERROR_UNEXPECTED;
1970 static nsresult NSAPI nsURI_GetPassword(nsIURL *iface, nsACString *aPassword)
1972 nsWineURI *This = impl_from_nsIURL(iface);
1974 TRACE("(%p)->(%p)\n", This, aPassword);
1976 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
1979 static nsresult NSAPI nsURI_SetPassword(nsIURL *iface, const nsACString *aPassword)
1981 nsWineURI *This = impl_from_nsIURL(iface);
1986 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
1988 if(!ensure_uri_builder(This))
1989 return NS_ERROR_UNEXPECTED;
1991 nsACString_GetData(aPassword, &passa);
1992 pass = heap_strdupAtoW(passa);
1994 return NS_ERROR_OUT_OF_MEMORY;
1996 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
1999 return NS_ERROR_UNEXPECTED;
2004 static nsresult NSAPI nsURI_GetHostPort(nsIURL *iface, nsACString *aHostPort)
2006 nsWineURI *This = impl_from_nsIURL(iface);
2012 TRACE("(%p)->(%p)\n", This, aHostPort);
2014 if(!ensure_uri(This))
2015 return NS_ERROR_UNEXPECTED;
2017 hres = IUri_GetAuthority(This->uri, &val);
2019 WARN("GetAuthority failed: %08x\n", hres);
2020 return NS_ERROR_UNEXPECTED;
2023 ptr = strchrW(val, '@');
2027 vala = heap_strdupWtoA(ptr);
2030 return NS_ERROR_OUT_OF_MEMORY;
2032 TRACE("ret %s\n", debugstr_a(vala));
2033 nsACString_SetData(aHostPort, vala);
2038 static nsresult NSAPI nsURI_SetHostPort(nsIURL *iface, const nsACString *aHostPort)
2040 nsWineURI *This = impl_from_nsIURL(iface);
2042 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2044 /* Not implemented by Gecko */
2045 return NS_ERROR_NOT_IMPLEMENTED;
2048 static nsresult NSAPI nsURI_GetHost(nsIURL *iface, nsACString *aHost)
2050 nsWineURI *This = impl_from_nsIURL(iface);
2052 TRACE("(%p)->(%p)\n", This, aHost);
2054 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2057 static nsresult NSAPI nsURI_SetHost(nsIURL *iface, const nsACString *aHost)
2059 nsWineURI *This = impl_from_nsIURL(iface);
2064 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2066 if(!ensure_uri_builder(This))
2067 return NS_ERROR_UNEXPECTED;
2069 nsACString_GetData(aHost, &hosta);
2070 host = heap_strdupAtoW(hosta);
2072 return NS_ERROR_OUT_OF_MEMORY;
2074 hres = IUriBuilder_SetHost(This->uri_builder, host);
2077 return NS_ERROR_UNEXPECTED;
2082 static nsresult NSAPI nsURI_GetPort(nsIURL *iface, PRInt32 *aPort)
2084 nsWineURI *This = impl_from_nsIURL(iface);
2088 TRACE("(%p)->(%p)\n", This, aPort);
2090 if(!ensure_uri(This))
2091 return NS_ERROR_UNEXPECTED;
2093 hres = IUri_GetPort(This->uri, &port);
2095 WARN("GetPort failed: %08x\n", hres);
2096 return NS_ERROR_UNEXPECTED;
2099 *aPort = port ? port : -1;
2103 static nsresult NSAPI nsURI_SetPort(nsIURL *iface, PRInt32 aPort)
2105 nsWineURI *This = impl_from_nsIURL(iface);
2108 TRACE("(%p)->(%d)\n", This, aPort);
2110 if(!ensure_uri_builder(This))
2111 return NS_ERROR_UNEXPECTED;
2113 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2114 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2117 static nsresult NSAPI nsURI_GetPath(nsIURL *iface, nsACString *aPath)
2119 nsWineURI *This = impl_from_nsIURL(iface);
2121 TRACE("(%p)->(%p)\n", This, aPath);
2123 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2126 static nsresult NSAPI nsURI_SetPath(nsIURL *iface, const nsACString *aPath)
2128 nsWineURI *This = impl_from_nsIURL(iface);
2133 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2135 if(!ensure_uri_builder(This))
2136 return NS_ERROR_UNEXPECTED;
2138 nsACString_GetData(aPath, &patha);
2139 path = heap_strdupAtoW(patha);
2141 return NS_ERROR_OUT_OF_MEMORY;
2143 hres = IUriBuilder_SetPath(This->uri_builder, path);
2146 return NS_ERROR_UNEXPECTED;
2151 static nsresult NSAPI nsURL_GetRef(nsIURL *iface, nsACString *aRef)
2153 nsWineURI *This = impl_from_nsIURL(iface);
2158 TRACE("(%p)->(%p)\n", This, aRef);
2160 if(!ensure_uri(This))
2161 return NS_ERROR_UNEXPECTED;
2163 hres = IUri_GetFragment(This->uri, &ref);
2165 return NS_ERROR_UNEXPECTED;
2167 refa = heap_strdupWtoA(ref);
2170 return NS_ERROR_OUT_OF_MEMORY;
2172 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
2177 static nsresult NSAPI nsURL_SetRef(nsIURL *iface, const nsACString *aRef)
2179 nsWineURI *This = impl_from_nsIURL(iface);
2184 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
2186 if(!ensure_uri_builder(This))
2187 return NS_ERROR_UNEXPECTED;
2189 nsACString_GetData(aRef, &refa);
2190 ref = heap_strdupAtoW(refa);
2192 return NS_ERROR_OUT_OF_MEMORY;
2194 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
2197 return NS_ERROR_UNEXPECTED;
2202 static nsresult NSAPI nsURI_Equals(nsIURL *iface, nsIURI *other, PRBool *_retval)
2204 nsWineURI *This = impl_from_nsIURL(iface);
2205 nsWineURI *other_obj;
2209 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2211 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2212 if(NS_FAILED(nsres)) {
2213 TRACE("Could not get nsWineURI interface\n");
2218 if(ensure_uri(This) && ensure_uri(other_obj)) {
2221 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2222 if(SUCCEEDED(hres)) {
2226 nsres = NS_ERROR_FAILURE;
2229 nsres = NS_ERROR_UNEXPECTED;
2232 nsIURI_Release(&other_obj->nsIURL_iface);
2236 static nsresult NSAPI nsURI_SchemeIs(nsIURL *iface, const char *scheme, PRBool *_retval)
2238 nsWineURI *This = impl_from_nsIURL(iface);
2239 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2243 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2245 if(!ensure_uri(This))
2246 return NS_ERROR_UNEXPECTED;
2248 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2250 return NS_ERROR_UNEXPECTED;
2252 MultiByteToWideChar(CP_ACP, 0, scheme, -1, buf, sizeof(buf)/sizeof(WCHAR));
2253 *_retval = !strcmpW(scheme_name, buf);
2254 SysFreeString(scheme_name);
2258 static nsresult NSAPI nsURI_Clone(nsIURL *iface, nsIURI **_retval)
2260 nsWineURI *This = impl_from_nsIURL(iface);
2261 nsIURI *nsuri = NULL;
2262 nsWineURI *wine_uri;
2265 TRACE("(%p)->(%p)\n", This, _retval);
2267 if(!ensure_uri(This))
2268 return NS_ERROR_UNEXPECTED;
2271 nsres = nsIURI_Clone(This->nsuri, &nsuri);
2272 if(NS_FAILED(nsres)) {
2273 WARN("Clone failed: %08x\n", nsres);
2278 nsres = create_nsuri(This->uri, nsuri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
2279 if(NS_FAILED(nsres)) {
2280 WARN("create_nsuri failed: %08x\n", nsres);
2284 *_retval = (nsIURI*)&wine_uri->nsIURL_iface;
2288 static nsresult NSAPI nsURI_Resolve(nsIURL *iface, const nsACString *aRelativePath,
2289 nsACString *_retval)
2291 nsWineURI *This = impl_from_nsIURL(iface);
2299 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2301 if(!ensure_uri(This))
2302 return NS_ERROR_UNEXPECTED;
2304 nsACString_GetData(aRelativePath, &patha);
2305 path = heap_strdupAtoW(patha);
2307 return NS_ERROR_OUT_OF_MEMORY;
2309 hres = CoInternetCombineUrlEx(This->uri, path, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, &new_uri, 0);
2312 ERR("CoIntenetCombineUrlEx failed: %08x\n", hres);
2313 return NS_ERROR_FAILURE;
2316 hres = IUri_GetDisplayUri(new_uri, &ret);
2317 IUri_Release(new_uri);
2319 return NS_ERROR_FAILURE;
2321 reta = heap_strdupWtoA(ret);
2324 return NS_ERROR_OUT_OF_MEMORY;
2326 TRACE("returning %s\n", debugstr_a(reta));
2327 nsACString_SetData(_retval, reta);
2332 static nsresult NSAPI nsURI_GetAsciiSpec(nsIURL *iface, nsACString *aAsciiSpec)
2334 nsWineURI *This = impl_from_nsIURL(iface);
2336 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2338 return nsIURI_GetSpec(&This->nsIURL_iface, aAsciiSpec);
2341 static nsresult NSAPI nsURI_GetAsciiHost(nsIURL *iface, nsACString *aAsciiHost)
2343 nsWineURI *This = impl_from_nsIURL(iface);
2345 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2347 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
2350 static nsresult NSAPI nsURI_GetOriginCharset(nsIURL *iface, nsACString *aOriginCharset)
2352 nsWineURI *This = impl_from_nsIURL(iface);
2354 TRACE("(%p)->(%p)\n", This, aOriginCharset);
2357 return nsIURI_GetOriginCharset(This->nsuri, aOriginCharset);
2359 FIXME("default action not implemented\n");
2360 return NS_ERROR_NOT_IMPLEMENTED;
2363 static nsresult NSAPI nsURI_EqualsExceptRef(nsIURL *iface, nsIURI *other, PRBool *_retval)
2365 nsWineURI *This = impl_from_nsIURL(iface);
2366 nsWineURI *other_obj;
2369 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2371 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2372 if(NS_FAILED(nsres)) {
2373 TRACE("Could not get nsWineURI interface\n");
2378 if(ensure_uri(This) && ensure_uri(other_obj)) {
2379 *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
2382 nsres = NS_ERROR_UNEXPECTED;
2385 nsIURI_Release(&other_obj->nsIURL_iface);
2389 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIURL *iface, nsIURI **_retval)
2391 nsWineURI *This = impl_from_nsIURL(iface);
2392 nsWineURI *wine_uri;
2396 TRACE("(%p)->(%p)\n", This, _retval);
2398 if(!ensure_uri(This))
2399 return NS_ERROR_UNEXPECTED;
2401 uri = get_uri_nofrag(This->uri);
2403 return NS_ERROR_FAILURE;
2405 nsres = create_nsuri(uri, NULL, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
2407 if(NS_FAILED(nsres)) {
2408 WARN("create_nsuri failed: %08x\n", nsres);
2412 *_retval = (nsIURI*)&wine_uri->nsIURL_iface;
2416 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIURL *iface, nsACString *aSpecIgnoringRef)
2418 nsWineURI *This = impl_from_nsIURL(iface);
2420 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
2422 return nsIURL_GetSpec(&This->nsIURL_iface, aSpecIgnoringRef);
2425 static nsresult NSAPI nsURI_GetHasRef(nsIURL *iface, PRBool *aHasRef)
2427 nsWineURI *This = impl_from_nsIURL(iface);
2431 TRACE("(%p)->(%p)\n", This, aHasRef);
2433 if(!ensure_uri(This))
2434 return NS_ERROR_UNEXPECTED;
2436 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
2438 return NS_ERROR_FAILURE;
2444 static nsresult NSAPI nsURL_GetFilePath(nsIURL *iface, nsACString *aFilePath)
2446 nsWineURI *This = impl_from_nsIURL(iface);
2448 TRACE("(%p)->(%p)\n", This, aFilePath);
2450 return nsIURL_GetPath(&This->nsIURL_iface, aFilePath);
2453 static nsresult NSAPI nsURL_SetFilePath(nsIURL *iface, const nsACString *aFilePath)
2455 nsWineURI *This = impl_from_nsIURL(iface);
2457 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
2459 return nsIURL_SetPath(&This->nsIURL_iface, aFilePath);
2462 static nsresult NSAPI nsURL_GetParam(nsIURL *iface, nsACString *aParam)
2464 nsWineURI *This = impl_from_nsIURL(iface);
2466 WARN("(%p)->(%p)\n", This, aParam);
2468 /* This is a leftover of ';' special handling in URLs. It will be removed from Gecko soon */
2469 nsACString_SetData(aParam, "");
2473 static nsresult NSAPI nsURL_SetParam(nsIURL *iface, const nsACString *aParam)
2475 nsWineURI *This = impl_from_nsIURL(iface);
2477 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aParam));
2479 /* Not implemented by Gecko */
2480 return NS_ERROR_NOT_IMPLEMENTED;
2483 static nsresult NSAPI nsURL_GetQuery(nsIURL *iface, nsACString *aQuery)
2485 nsWineURI *This = impl_from_nsIURL(iface);
2487 TRACE("(%p)->(%p)\n", This, aQuery);
2489 return get_uri_string(This, Uri_PROPERTY_QUERY, aQuery);
2492 static nsresult NSAPI nsURL_SetQuery(nsIURL *iface, const nsACString *aQuery)
2494 nsWineURI *This = impl_from_nsIURL(iface);
2499 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
2501 if(!ensure_uri_builder(This))
2502 return NS_ERROR_UNEXPECTED;
2504 nsACString_GetData(aQuery, &querya);
2505 query = heap_strdupAtoW(querya);
2507 return NS_ERROR_OUT_OF_MEMORY;
2509 hres = IUriBuilder_SetQuery(This->uri_builder, query);
2512 return NS_ERROR_UNEXPECTED;
2517 static nsresult NSAPI nsURL_GetDirectory(nsIURL *iface, nsACString *aDirectory)
2519 nsWineURI *This = impl_from_nsIURL(iface);
2525 TRACE("(%p)->(%p)\n", This, aDirectory);
2527 if(!ensure_uri(This))
2528 return NS_ERROR_UNEXPECTED;
2530 hres = IUri_GetPath(This->uri, &path);
2532 return NS_ERROR_FAILURE;
2534 ptr = strrchrW(path, '/');
2538 dir = heap_strdupWtoA(path);
2540 SysFreeString(path);
2541 return NS_ERROR_OUT_OF_MEMORY;
2545 SysFreeString(path);
2546 TRACE("ret %s\n", debugstr_a(dir));
2547 nsACString_SetData(aDirectory, dir ? dir : "");
2552 static nsresult NSAPI nsURL_SetDirectory(nsIURL *iface, const nsACString *aDirectory)
2554 nsWineURI *This = impl_from_nsIURL(iface);
2556 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
2558 /* Not implemented by Gecko */
2559 return NS_ERROR_NOT_IMPLEMENTED;
2562 static nsresult NSAPI nsURL_GetFileName(nsIURL *iface, nsACString *aFileName)
2564 nsWineURI *This = impl_from_nsIURL(iface);
2566 TRACE("(%p)->(%p)\n", This, aFileName);
2569 return nsIURL_GetFileName(This->nsurl, aFileName);
2571 FIXME("default action not implemented\n");
2572 return NS_ERROR_NOT_IMPLEMENTED;
2575 static nsresult NSAPI nsURL_SetFileName(nsIURL *iface, const nsACString *aFileName)
2577 nsWineURI *This = impl_from_nsIURL(iface);
2579 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
2582 invalidate_uri(This);
2583 return nsIURL_SetFileName(This->nsurl, aFileName);
2586 FIXME("default action not implemented\n");
2587 return NS_ERROR_NOT_IMPLEMENTED;
2590 static nsresult NSAPI nsURL_GetFileBaseName(nsIURL *iface, nsACString *aFileBaseName)
2592 nsWineURI *This = impl_from_nsIURL(iface);
2594 TRACE("(%p)->(%p)\n", This, aFileBaseName);
2597 return nsIURL_GetFileBaseName(This->nsurl, aFileBaseName);
2599 FIXME("default action not implemented\n");
2600 return NS_ERROR_NOT_IMPLEMENTED;
2603 static nsresult NSAPI nsURL_SetFileBaseName(nsIURL *iface, const nsACString *aFileBaseName)
2605 nsWineURI *This = impl_from_nsIURL(iface);
2607 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
2610 invalidate_uri(This);
2611 return nsIURL_SetFileBaseName(This->nsurl, aFileBaseName);
2614 FIXME("default action not implemented\n");
2615 return NS_ERROR_NOT_IMPLEMENTED;
2618 static nsresult NSAPI nsURL_GetFileExtension(nsIURL *iface, nsACString *aFileExtension)
2620 nsWineURI *This = impl_from_nsIURL(iface);
2622 TRACE("(%p)->(%p)\n", This, aFileExtension);
2624 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
2627 static nsresult NSAPI nsURL_SetFileExtension(nsIURL *iface, const nsACString *aFileExtension)
2629 nsWineURI *This = impl_from_nsIURL(iface);
2631 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
2634 invalidate_uri(This);
2635 return nsIURL_SetFileExtension(This->nsurl, aFileExtension);
2638 FIXME("default action not implemented\n");
2639 return NS_ERROR_NOT_IMPLEMENTED;
2642 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
2644 nsWineURI *This = impl_from_nsIURL(iface);
2646 TRACE("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
2649 return nsIURL_GetCommonBaseSpec(This->nsurl, aURIToCompare, _retval);
2651 FIXME("default action not implemented\n");
2652 return NS_ERROR_NOT_IMPLEMENTED;
2655 static nsresult NSAPI nsURL_GetRelativeSpec(nsIURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
2657 nsWineURI *This = impl_from_nsIURL(iface);
2659 TRACE("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
2662 return nsIURL_GetRelativeSpec(This->nsurl, aURIToCompare, _retval);
2664 FIXME("default action not implemented\n");
2665 return NS_ERROR_NOT_IMPLEMENTED;
2668 static const nsIURLVtbl nsURLVtbl = {
2669 nsURI_QueryInterface,
2697 nsURI_GetOriginCharset,
2700 nsURI_EqualsExceptRef,
2701 nsURI_CloneIgnoreRef,
2702 nsURI_GetSpecIgnoringRef,
2714 nsURL_GetFileBaseName,
2715 nsURL_SetFileBaseName,
2716 nsURL_GetFileExtension,
2717 nsURL_SetFileExtension,
2718 nsURL_GetCommonBaseSpec,
2719 nsURL_GetRelativeSpec
2722 static nsresult create_nsuri(IUri *iuri, nsIURI *nsuri, HTMLWindow *window, NSContainer *container, nsWineURI **_retval)
2724 nsWineURI *ret = heap_alloc_zero(sizeof(nsWineURI));
2726 ret->nsIURL_iface.lpVtbl = &nsURLVtbl;
2730 set_uri_nscontainer(ret, container);
2731 set_uri_window(ret, window);
2737 nsIURI_QueryInterface(nsuri, &IID_nsIURL, (void**)&ret->nsurl);
2739 TRACE("retval=%p\n", ret);
2744 HRESULT create_doc_uri(HTMLWindow *window, WCHAR *url, nsWineURI **ret)
2751 hres = CreateUri(url, 0, 0, &iuri);
2755 nsres = create_nsuri(iuri, NULL, window, window->doc_obj->nscontainer, &uri);
2757 if(NS_FAILED(nsres))
2760 uri->is_doc_uri = TRUE;
2766 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
2771 if(!ensure_uri(uri))
2772 return NS_ERROR_UNEXPECTED;
2774 channel = heap_alloc_zero(sizeof(nsChannel));
2776 return NS_ERROR_OUT_OF_MEMORY;
2778 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
2779 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
2780 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
2782 channel->request_method = METHOD_GET;
2783 list_init(&channel->response_headers);
2784 list_init(&channel->request_headers);
2786 nsIURL_AddRef(&uri->nsIURL_iface);
2789 hres = IUri_GetScheme(uri->uri, &channel->url_scheme);
2791 channel->url_scheme = URL_SCHEME_UNKNOWN;
2797 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
2799 HTMLWindow *window = NULL;
2806 hres = CreateUri(url, 0, 0, &iuri);
2810 if(orig_channel->uri->window_ref)
2811 window = orig_channel->uri->window_ref->window;
2812 nsres = create_nsuri(iuri, NULL, window, NULL, &uri);
2814 if(NS_FAILED(nsres))
2817 nsres = create_nschannel(uri, &channel);
2818 nsIURL_Release(&uri->nsIURL_iface);
2819 if(NS_FAILED(nsres))
2822 if(orig_channel->load_group) {
2823 nsILoadGroup_AddRef(orig_channel->load_group);
2824 channel->load_group = orig_channel->load_group;
2827 if(orig_channel->notif_callback) {
2828 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
2829 channel->notif_callback = orig_channel->notif_callback;
2832 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
2834 if(orig_channel->request_method == METHOD_POST)
2835 FIXME("unsupported POST method\n");
2837 if(orig_channel->original_uri) {
2838 nsIURI_AddRef(orig_channel->original_uri);
2839 channel->original_uri = orig_channel->original_uri;
2842 if(orig_channel->referrer) {
2843 nsIURI_AddRef(orig_channel->referrer);
2844 channel->referrer = orig_channel->referrer;
2852 nsIProtocolHandler nsIProtocolHandler_iface;
2856 nsIProtocolHandler *nshandler;
2857 } nsProtocolHandler;
2859 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
2861 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
2864 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
2867 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2871 if(IsEqualGUID(&IID_nsISupports, riid)) {
2872 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2873 *result = &This->nsIProtocolHandler_iface;
2874 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
2875 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
2876 *result = &This->nsIProtocolHandler_iface;
2877 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
2878 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
2879 return NS_NOINTERFACE;
2883 nsISupports_AddRef((nsISupports*)*result);
2887 WARN("(%s %p)\n", debugstr_guid(riid), result);
2888 return NS_NOINTERFACE;
2891 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
2893 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2894 LONG ref = InterlockedIncrement(&This->ref);
2896 TRACE("(%p) ref=%d\n", This, ref);
2901 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
2903 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2904 LONG ref = InterlockedDecrement(&This->ref);
2906 TRACE("(%p) ref=%d\n", This, ref);
2910 nsIProtocolHandler_Release(This->nshandler);
2917 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
2919 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2921 TRACE("(%p)->(%p)\n", This, aScheme);
2924 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
2925 return NS_ERROR_NOT_IMPLEMENTED;
2928 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
2929 PRInt32 *aDefaultPort)
2931 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2933 TRACE("(%p)->(%p)\n", This, aDefaultPort);
2936 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
2937 return NS_ERROR_NOT_IMPLEMENTED;
2940 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
2941 PRUint32 *aProtocolFlags)
2943 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2945 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
2948 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
2949 return NS_ERROR_NOT_IMPLEMENTED;
2952 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
2953 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
2955 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2957 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
2961 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
2962 return NS_ERROR_NOT_IMPLEMENTED;
2965 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
2966 nsIURI *aURI, nsIChannel **_retval)
2968 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2970 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
2973 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
2974 return NS_ERROR_NOT_IMPLEMENTED;
2977 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
2978 PRInt32 port, const char *scheme, PRBool *_retval)
2980 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2982 TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
2985 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
2986 return NS_ERROR_NOT_IMPLEMENTED;
2989 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
2990 nsProtocolHandler_QueryInterface,
2991 nsProtocolHandler_AddRef,
2992 nsProtocolHandler_Release,
2993 nsProtocolHandler_GetScheme,
2994 nsProtocolHandler_GetDefaultPort,
2995 nsProtocolHandler_GetProtocolFlags,
2996 nsProtocolHandler_NewURI,
2997 nsProtocolHandler_NewChannel,
2998 nsProtocolHandler_AllowPort
3001 static nsIProtocolHandler *create_protocol_handler(nsIProtocolHandler *nshandler)
3003 nsProtocolHandler *ret = heap_alloc(sizeof(nsProtocolHandler));
3005 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3007 ret->nshandler = nshandler;
3009 return &ret->nsIProtocolHandler_iface;
3012 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService*,nsIIDRef,void**);
3014 static nsrefcnt NSAPI nsIOService_AddRef(nsIIOService *iface)
3019 static nsrefcnt NSAPI nsIOService_Release(nsIIOService *iface)
3024 static nsresult NSAPI nsIOService_GetProtocolHandler(nsIIOService *iface, const char *aScheme,
3025 nsIProtocolHandler **_retval)
3027 nsIExternalProtocolHandler *nsexthandler;
3028 nsIProtocolHandler *nshandler;
3031 TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
3033 nsres = nsIIOService_GetProtocolHandler(nsio, aScheme, &nshandler);
3034 if(NS_FAILED(nsres)) {
3035 WARN("GetProtocolHandler failed: %08x\n", nsres);
3039 nsres = nsIProtocolHandler_QueryInterface(nshandler, &IID_nsIExternalProtocolHandler,
3040 (void**)&nsexthandler);
3041 if(NS_FAILED(nsres)) {
3042 *_retval = nshandler;
3046 nsIExternalProtocolHandler_Release(nsexthandler);
3047 *_retval = create_protocol_handler(nshandler);
3048 TRACE("return %p\n", *_retval);
3052 static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const char *aScheme,
3055 TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
3056 return nsIIOService_GetProtocolFlags(nsio, aScheme, _retval);
3059 static BOOL is_gecko_special_uri(const char *spec)
3061 static const char *special_schemes[] = {"chrome:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"};
3064 for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
3065 if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
3069 if(!strncasecmp(spec, "file:", 5)) {
3070 const char *ptr = spec+5;
3073 return is_gecko_path(ptr);
3079 static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *aSpec,
3080 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3082 nsWineURI *wine_uri, *base_wine_uri = NULL;
3083 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3084 HTMLWindow *window = NULL;
3085 const char *spec = NULL;
3091 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3094 nsACString_GetData(aSpec, &spec);
3095 if(is_gecko_special_uri(spec))
3096 return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3098 if(!strncmp(spec, "wine:", 5))
3102 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3103 if(NS_SUCCEEDED(nsres)) {
3104 if(!ensure_uri(base_wine_uri))
3105 return NS_ERROR_UNEXPECTED;
3106 if(base_wine_uri->window_ref)
3107 window = base_wine_uri->window_ref->window;
3109 WARN("Could not get base nsWineURI: %08x\n", nsres);
3113 MultiByteToWideChar(CP_ACP, 0, spec, -1, new_spec, sizeof(new_spec)/sizeof(WCHAR));
3116 hres = CoInternetCombineUrlEx(base_wine_uri->uri, new_spec, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
3119 WARN("CoInternetCombineUrlEx failed: %08x\n", hres);
3121 hres = CreateUri(new_spec, 0, 0, &urlmon_uri);
3123 WARN("CreateUri failed: %08x\n", hres);
3126 nsres = nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, &uri);
3127 if(NS_FAILED(nsres))
3128 TRACE("NewURI failed: %08x\n", nsres);
3135 nsres = create_nsuri(urlmon_uri, uri, window, NULL, &wine_uri);
3136 IUri_Release(urlmon_uri);
3138 nsIURI_Release(&base_wine_uri->nsIURL_iface);
3139 if(NS_FAILED(nsres))
3142 *_retval = (nsIURI*)&wine_uri->nsIURL_iface;
3146 static nsresult NSAPI nsIOService_NewFileURI(nsIIOService *iface, nsIFile *aFile,
3149 TRACE("(%p %p)\n", aFile, _retval);
3150 return nsIIOService_NewFileURI(nsio, aFile, _retval);
3153 static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI *aURI,
3154 nsIChannel **_retval)
3156 nsWineURI *wine_uri;
3160 TRACE("(%p %p)\n", aURI, _retval);
3162 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3163 if(NS_FAILED(nsres)) {
3164 TRACE("Could not get nsWineURI: %08x\n", nsres);
3165 return nsIIOService_NewChannelFromURI(nsio, aURI, _retval);
3168 nsres = create_nschannel(wine_uri, &ret);
3169 nsIURL_Release(&wine_uri->nsIURL_iface);
3170 if(NS_FAILED(nsres))
3173 nsIURI_AddRef(aURI);
3174 ret->original_uri = aURI;
3176 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3180 static nsresult NSAPI nsIOService_NewChannel(nsIIOService *iface, const nsACString *aSpec,
3181 const char *aOriginCharset, nsIURI *aBaseURI, nsIChannel **_retval)
3183 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI, _retval);
3184 return nsIIOService_NewChannel(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3187 static nsresult NSAPI nsIOService_GetOffline(nsIIOService *iface, PRBool *aOffline)
3189 TRACE("(%p)\n", aOffline);
3190 return nsIIOService_GetOffline(nsio, aOffline);
3193 static nsresult NSAPI nsIOService_SetOffline(nsIIOService *iface, PRBool aOffline)
3195 TRACE("(%x)\n", aOffline);
3196 return nsIIOService_SetOffline(nsio, aOffline);
3199 static nsresult NSAPI nsIOService_AllowPort(nsIIOService *iface, PRInt32 aPort,
3200 const char *aScheme, PRBool *_retval)
3202 TRACE("(%d %s %p)\n", aPort, debugstr_a(aScheme), _retval);
3203 return nsIIOService_AllowPort(nsio, aPort, debugstr_a(aScheme), _retval);
3206 static nsresult NSAPI nsIOService_ExtractScheme(nsIIOService *iface, const nsACString *urlString,
3207 nsACString * _retval)
3209 TRACE("(%s %p)\n", debugstr_nsacstr(urlString), _retval);
3210 return nsIIOService_ExtractScheme(nsio, urlString, _retval);
3213 static const nsIIOServiceVtbl nsIOServiceVtbl = {
3214 nsIOService_QueryInterface,
3216 nsIOService_Release,
3217 nsIOService_GetProtocolHandler,
3218 nsIOService_GetProtocolFlags,
3220 nsIOService_NewFileURI,
3221 nsIOService_NewChannelFromURI,
3222 nsIOService_NewChannel,
3223 nsIOService_GetOffline,
3224 nsIOService_SetOffline,
3225 nsIOService_AllowPort,
3226 nsIOService_ExtractScheme
3229 static nsIIOService nsIOService = { &nsIOServiceVtbl };
3231 static nsresult NSAPI nsNetUtil_QueryInterface(nsINetUtil *iface, nsIIDRef riid,
3234 return nsIIOService_QueryInterface(&nsIOService, riid, result);
3237 static nsrefcnt NSAPI nsNetUtil_AddRef(nsINetUtil *iface)
3242 static nsrefcnt NSAPI nsNetUtil_Release(nsINetUtil *iface)
3247 static nsresult NSAPI nsNetUtil_ParseContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
3248 nsACString *aCharset, PRBool *aHadCharset, nsACString *aContentType)
3250 TRACE("(%s %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aHadCharset, aContentType);
3252 return nsINetUtil_ParseContentType(net_util, aTypeHeader, aCharset, aHadCharset, aContentType);
3255 static nsresult NSAPI nsNetUtil_ProtocolHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
3259 return nsINetUtil_ProtocolHasFlags(net_util, aURI, aFlags, _retval);
3262 static nsresult NSAPI nsNetUtil_URIChainHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
3264 TRACE("(%p %08x %p)\n", aURI, aFlags, _retval);
3266 if(aFlags == (1<<11)) {
3271 return nsINetUtil_URIChainHasFlags(net_util, aURI, aFlags, _retval);
3274 static nsresult NSAPI nsNetUtil_ToImmutableURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
3276 TRACE("(%p %p)\n", aURI, _retval);
3278 return nsINetUtil_ToImmutableURI(net_util, aURI, _retval);
3281 static nsresult NSAPI nsNetUtil_NewSimpleNestedURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
3283 TRACE("(%p %p)\n", aURI, _retval);
3285 return nsINetUtil_NewSimpleNestedURI(net_util, aURI, _retval);
3288 static nsresult NSAPI nsNetUtil_EscapeString(nsINetUtil *iface, const nsACString *aString,
3289 PRUint32 aEscapeType, nsACString *_retval)
3291 TRACE("(%s %x %p)\n", debugstr_nsacstr(aString), aEscapeType, _retval);
3293 return nsINetUtil_EscapeString(net_util, aString, aEscapeType, _retval);
3296 static nsresult NSAPI nsNetUtil_EscapeURL(nsINetUtil *iface, const nsACString *aStr, PRUint32 aFlags,
3297 nsACString *_retval)
3299 TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval);
3301 return nsINetUtil_EscapeURL(net_util, aStr, aFlags, _retval);
3304 static nsresult NSAPI nsNetUtil_UnescapeString(nsINetUtil *iface, const nsACString *aStr,
3305 PRUint32 aFlags, nsACString *_retval)
3307 TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval);
3309 return nsINetUtil_UnescapeString(net_util, aStr, aFlags, _retval);
3312 static nsresult NSAPI nsNetUtil_ExtractCharsetFromContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
3313 nsACString *aCharset, PRInt32 *aCharsetStart, PRInt32 *aCharsetEnd, PRBool *_retval)
3315 TRACE("(%s %p %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aCharsetStart,
3316 aCharsetEnd, _retval);
3318 return nsINetUtil_ExtractCharsetFromContentType(net_util, aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
3321 static const nsINetUtilVtbl nsNetUtilVtbl = {
3322 nsNetUtil_QueryInterface,
3325 nsNetUtil_ParseContentType,
3326 nsNetUtil_ProtocolHasFlags,
3327 nsNetUtil_URIChainHasFlags,
3328 nsNetUtil_ToImmutableURI,
3329 nsNetUtil_NewSimpleNestedURI,
3330 nsNetUtil_EscapeString,
3331 nsNetUtil_EscapeURL,
3332 nsNetUtil_UnescapeString,
3333 nsNetUtil_ExtractCharsetFromContentType
3336 static nsINetUtil nsNetUtil = { &nsNetUtilVtbl };
3338 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService *iface, nsIIDRef riid,
3343 if(IsEqualGUID(&IID_nsISupports, riid))
3344 *result = &nsIOService;
3345 else if(IsEqualGUID(&IID_nsIIOService, riid))
3346 *result = &nsIOService;
3347 else if(IsEqualGUID(&IID_nsINetUtil, riid))
3348 *result = &nsNetUtil;
3351 nsISupports_AddRef((nsISupports*)*result);
3355 FIXME("(%s %p)\n", debugstr_guid(riid), result);
3356 return NS_NOINTERFACE;
3359 static nsresult NSAPI nsIOServiceFactory_QueryInterface(nsIFactory *iface, nsIIDRef riid,
3364 if(IsEqualGUID(&IID_nsISupports, riid)) {
3365 TRACE("(IID_nsISupports %p)\n", result);
3367 }else if(IsEqualGUID(&IID_nsIFactory, riid)) {
3368 TRACE("(IID_nsIFactory %p)\n", result);
3373 nsIFactory_AddRef(iface);
3377 WARN("(%s %p)\n", debugstr_guid(riid), result);
3378 return NS_NOINTERFACE;
3381 static nsrefcnt NSAPI nsIOServiceFactory_AddRef(nsIFactory *iface)
3386 static nsrefcnt NSAPI nsIOServiceFactory_Release(nsIFactory *iface)
3391 static nsresult NSAPI nsIOServiceFactory_CreateInstance(nsIFactory *iface,
3392 nsISupports *aOuter, const nsIID *iid, void **result)
3394 return nsIIOService_QueryInterface(&nsIOService, iid, result);
3397 static nsresult NSAPI nsIOServiceFactory_LockFactory(nsIFactory *iface, PRBool lock)
3399 WARN("(%x)\n", lock);
3403 static const nsIFactoryVtbl nsIOServiceFactoryVtbl = {
3404 nsIOServiceFactory_QueryInterface,
3405 nsIOServiceFactory_AddRef,
3406 nsIOServiceFactory_Release,
3407 nsIOServiceFactory_CreateInstance,
3408 nsIOServiceFactory_LockFactory
3411 static nsIFactory nsIOServiceFactory = { &nsIOServiceFactoryVtbl };
3413 static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri)
3415 OLECHAR *new_url = NULL;
3420 if(!doc->hostui || !ensure_uri(uri))
3423 hres = IUri_GetDisplayUri(uri->uri, &url);
3427 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
3428 if(hres == S_OK && new_url) {
3429 if(strcmpW(url, new_url)) {
3430 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
3433 CoTaskMemFree(new_url);
3440 nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, PRBool *_retval)
3442 nsWineURI *wine_uri;
3447 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
3448 if(NS_FAILED(nsres)) {
3449 WARN("Could not get nsWineURI: %08x\n", nsres);
3450 return NS_ERROR_NOT_IMPLEMENTED;
3453 if(!wine_uri->is_doc_uri) {
3454 wine_uri->is_doc_uri = TRUE;
3456 if(!wine_uri->container) {
3457 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
3458 wine_uri->container = nscontainer;
3461 if(nscontainer->doc)
3462 *_retval = translate_url(nscontainer->doc, wine_uri);
3465 nsIURI_Release(&wine_uri->nsIURL_iface);
3469 void init_nsio(nsIComponentManager *component_manager, nsIComponentRegistrar *registrar)
3471 nsIFactory *old_factory = NULL;
3474 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
3475 &IID_nsIFactory, (void**)&old_factory);
3476 if(NS_FAILED(nsres)) {
3477 ERR("Could not get factory: %08x\n", nsres);
3481 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
3482 if(NS_FAILED(nsres)) {
3483 ERR("Couldn not create nsIOService instance %08x\n", nsres);
3484 nsIFactory_Release(old_factory);
3488 nsres = nsIIOService_QueryInterface(nsio, &IID_nsINetUtil, (void**)&net_util);
3489 if(NS_FAILED(nsres)) {
3490 WARN("Could not get nsINetUtil interface: %08x\n", nsres);
3491 nsIIOService_Release(nsio);
3495 nsres = nsIComponentRegistrar_UnregisterFactory(registrar, &NS_IOSERVICE_CID, old_factory);
3496 nsIFactory_Release(old_factory);
3497 if(NS_FAILED(nsres))
3498 ERR("UnregisterFactory failed: %08x\n", nsres);
3500 nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_IOSERVICE_CID,
3501 NS_IOSERVICE_CLASSNAME, NS_IOSERVICE_CONTRACTID, &nsIOServiceFactory);
3502 if(NS_FAILED(nsres))
3503 ERR("RegisterFactory failed: %08x\n", nsres);
3506 void release_nsio(void)
3509 nsINetUtil_Release(net_util);
3514 nsIIOService_Release(nsio);