mshtml: Wine Gecko 1.5 release.
[wine/multimedia.git] / dlls / mshtml / nsio.c
blob7fd1c575afa9ca1aaeb8b7b4fa8d4b1e97d33624
1 /*
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
19 #include "config.h"
21 #include <stdarg.h>
22 #include <assert.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "ole2.h"
31 #include "shlguid.h"
32 #include "wininet.h"
33 #include "shlwapi.h"
35 #include "wine/debug.h"
37 #include "mshtml_private.h"
38 #include "binding.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"};
55 struct nsWineURI {
56 nsIURL nsIURL_iface;
57 nsIStandardURL nsIStandardURL_iface;
59 LONG ref;
61 NSContainer *container;
62 windowref_t *window_ref;
63 nsChannelBSC *channel_bsc;
64 IUri *uri;
65 IUriBuilder *uri_builder;
66 BOOL is_doc_uri;
67 BOOL is_mutable;
70 static BOOL ensure_uri(nsWineURI *This)
72 HRESULT hres;
74 assert(This->uri || This->uri_builder);
76 if(!This->uri) {
77 hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
78 if(FAILED(hres)) {
79 WARN("CreateUriSimple failed: %08x\n", hres);
80 return FALSE;
84 return TRUE;
87 IUri *nsuri_get_uri(nsWineURI *nsuri)
89 if(!ensure_uri(nsuri))
90 return NULL;
92 IUri_AddRef(nsuri->uri);
93 return nsuri->uri;
96 static IUri *get_uri_nofrag(IUri *uri)
98 IUriBuilder *uri_builder;
99 IUri *ret;
100 BOOL b;
101 HRESULT hres;
103 hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
104 if(SUCCEEDED(hres) && !b) {
105 IUri_AddRef(uri);
106 return uri;
109 hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
110 if(FAILED(hres))
111 return NULL;
113 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
114 if(SUCCEEDED(hres))
115 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
116 IUriBuilder_Release(uri_builder);
117 if(FAILED(hres))
118 return NULL;
120 return ret;
123 BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
125 IUri *uri_nofrag1, *uri_nofrag2;
126 BOOL ret = FALSE;
128 uri_nofrag1 = get_uri_nofrag(uri1);
129 if(!uri_nofrag1)
130 return FALSE;
132 uri_nofrag2 = get_uri_nofrag(uri2);
133 if(uri_nofrag2) {
134 IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
135 IUri_Release(uri_nofrag2);
138 IUri_Release(uri_nofrag1);
139 return ret;
142 static nsresult create_nsuri(IUri*,HTMLWindow*,NSContainer*,nsWineURI**);
144 static const char *debugstr_nsacstr(const nsACString *nsstr)
146 const char *data;
148 nsACString_GetData(nsstr, &data);
149 return debugstr_a(data);
152 static nsresult return_wstr_nsacstr(nsACString *ret_str, const WCHAR *str, int len)
154 char *stra;
155 int lena;
157 TRACE("returning %s\n", debugstr_wn(str, len));
159 if(!*str) {
160 nsACString_SetData(ret_str, "");
161 return NS_OK;
164 lena = WideCharToMultiByte(CP_ACP, 0, str, len, NULL, 0, NULL, NULL);
165 stra = heap_alloc(lena+1);
166 if(!stra)
167 return NS_ERROR_OUT_OF_MEMORY;
169 WideCharToMultiByte(CP_ACP, 0, str, len, stra, lena, NULL, NULL);
170 stra[lena] = 0;
172 nsACString_SetData(ret_str, stra);
173 heap_free(stra);
174 return NS_OK;
177 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
179 const WCHAR *ptr = nsuri;
181 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
183 if(!strncmpW(nsuri, wine_prefixW, sizeof(wine_prefixW)/sizeof(WCHAR)))
184 ptr += sizeof(wine_prefixW)/sizeof(WCHAR);
186 if(*ptr || ret_empty) {
187 *ret = SysAllocString(ptr);
188 if(!*ret)
189 return E_OUTOFMEMORY;
190 }else {
191 *ret = NULL;
194 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
195 return S_OK;
198 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
200 IOleCommandTarget *cmdtrg = NULL;
201 HRESULT hres;
203 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
204 if(SUCCEEDED(hres)) {
205 VARIANT varUrl, varRes;
207 V_VT(&varUrl) = VT_BSTR;
208 V_BSTR(&varUrl) = url;
209 V_VT(&varRes) = VT_BOOL;
211 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
213 IOleCommandTarget_Release(cmdtrg);
215 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
216 TRACE("got VARIANT_FALSE, do not load\n");
217 return FALSE;
221 return TRUE;
224 static nsresult before_async_open(nsChannel *channel, NSContainer *container, BOOL *cancel)
226 HTMLDocumentObj *doc = container->doc;
227 BSTR display_uri;
228 DWORD hlnf = 0;
229 HRESULT hres;
231 if(!doc) {
232 NSContainer *container_iter = container;
234 hlnf = HLNF_OPENINNEWWINDOW;
235 while(!container_iter->doc)
236 container_iter = container_iter->parent;
237 doc = container_iter->doc;
240 if(!doc->client) {
241 *cancel = TRUE;
242 return NS_OK;
245 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
246 if(FAILED(hres))
247 return NS_ERROR_FAILURE;
249 if(!hlnf) {
250 BOOL b;
252 b = !exec_shldocvw_67(doc, display_uri);
253 if(b) {
254 SysFreeString(display_uri);
255 *cancel = FALSE;
256 return NS_OK;
260 hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, hlnf, cancel);
261 SysFreeString(display_uri);
262 if(FAILED(hres))
263 *cancel = TRUE;
264 return NS_OK;
267 HRESULT load_nsuri(HTMLWindow *window, nsWineURI *uri, nsChannelBSC *channelbsc, DWORD flags)
269 nsIWebNavigation *web_navigation;
270 nsIDocShell *doc_shell;
271 HTMLDocumentNode *doc;
272 nsresult nsres;
274 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
275 if(NS_FAILED(nsres)) {
276 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
277 return E_FAIL;
280 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
281 nsIWebNavigation_Release(web_navigation);
282 if(NS_FAILED(nsres)) {
283 ERR("Could not get nsIDocShell: %08x\n", nsres);
284 return E_FAIL;
287 uri->channel_bsc = channelbsc;
288 doc = window->doc;
289 doc->skip_mutation_notif = TRUE;
290 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIURL_iface, NULL, flags, FALSE);
291 if(doc == window->doc)
292 doc->skip_mutation_notif = FALSE;
293 uri->channel_bsc = NULL;
294 nsIDocShell_Release(doc_shell);
295 if(NS_FAILED(nsres)) {
296 WARN("LoadURI failed: %08x\n", nsres);
297 return E_FAIL;
300 return S_OK;
303 static void set_uri_nscontainer(nsWineURI *This, NSContainer *nscontainer)
305 if(This->container) {
306 if(This->container == nscontainer)
307 return;
308 TRACE("Changing %p -> %p\n", This->container, nscontainer);
309 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
312 if(nscontainer)
313 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
314 This->container = nscontainer;
317 static void set_uri_window(nsWineURI *This, HTMLWindow *window)
319 if(This->window_ref) {
320 if(This->window_ref->window == window)
321 return;
322 TRACE("Changing %p -> %p\n", This->window_ref->window, window);
323 windowref_release(This->window_ref);
326 if(window) {
327 windowref_addref(window->window_ref);
328 This->window_ref = window->window_ref;
330 if(window->doc_obj)
331 set_uri_nscontainer(This, window->doc_obj->nscontainer);
332 }else {
333 This->window_ref = NULL;
337 static inline BOOL is_http_channel(nsChannel *This)
339 return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTPS;
342 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
344 http_header_t *iter;
346 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
347 if(!strcmpiW(iter->header, name))
348 return iter;
351 return NULL;
354 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
355 nsACString *_retval)
357 const char *header_namea;
358 http_header_t *header;
359 WCHAR *header_name;
360 char *data;
362 nsACString_GetData(header_name_str, &header_namea);
363 header_name = heap_strdupAtoW(header_namea);
364 if(!header_name)
365 return NS_ERROR_UNEXPECTED;
367 header = find_http_header(headers, header_name, strlenW(header_name));
368 heap_free(header_name);
369 if(!header)
370 return NS_ERROR_NOT_AVAILABLE;
372 data = heap_strdupWtoA(header->data);
373 if(!data)
374 return NS_ERROR_UNEXPECTED;
376 TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
377 nsACString_SetData(_retval, data);
378 heap_free(data);
379 return NS_OK;
382 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
383 const WCHAR *value, int value_len)
385 http_header_t *header;
387 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
389 header = find_http_header(headers, name, name_len);
390 if(header) {
391 WCHAR *new_data;
393 new_data = heap_strndupW(value, value_len);
394 if(!new_data)
395 return E_OUTOFMEMORY;
397 heap_free(header->data);
398 header->data = new_data;
399 }else {
400 header = heap_alloc(sizeof(http_header_t));
401 if(!header)
402 return E_OUTOFMEMORY;
404 header->header = heap_strndupW(name, name_len);
405 header->data = heap_strndupW(value, value_len);
406 if(!header->header || !header->data) {
407 heap_free(header->header);
408 heap_free(header->data);
409 heap_free(header);
410 return E_OUTOFMEMORY;
413 list_add_tail(headers, &header->entry);
416 return S_OK;
419 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
420 const nsACString *value_str)
422 const char *namea, *valuea;
423 WCHAR *name, *value;
424 HRESULT hres;
426 nsACString_GetData(name_str, &namea);
427 name = heap_strdupAtoW(namea);
428 if(!name)
429 return NS_ERROR_UNEXPECTED;
431 nsACString_GetData(value_str, &valuea);
432 value = heap_strdupAtoW(valuea);
433 if(!value) {
434 heap_free(name);
435 return NS_ERROR_UNEXPECTED;
438 hres = set_http_header(headers, name, strlenW(name), value, strlenW(value));
440 heap_free(name);
441 heap_free(value);
442 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
445 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
447 nsACString header_str, value_str;
448 char *header, *value;
449 http_header_t *iter;
450 nsresult nsres;
452 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
453 header = heap_strdupWtoA(iter->header);
454 if(!header)
455 return NS_ERROR_OUT_OF_MEMORY;
457 value = heap_strdupWtoA(iter->data);
458 if(!value) {
459 heap_free(header);
460 return NS_ERROR_OUT_OF_MEMORY;
463 nsACString_InitDepend(&header_str, header);
464 nsACString_InitDepend(&value_str, value);
465 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
466 nsACString_Finish(&header_str);
467 nsACString_Finish(&value_str);
468 heap_free(header);
469 heap_free(value);
470 if(NS_FAILED(nsres))
471 break;
474 return NS_OK;
477 static void free_http_headers(struct list *list)
479 http_header_t *iter, *iter_next;
481 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
482 list_remove(&iter->entry);
483 heap_free(iter->header);
484 heap_free(iter->data);
485 heap_free(iter);
489 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
491 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
494 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
496 nsChannel *This = impl_from_nsIHttpChannel(iface);
498 if(IsEqualGUID(&IID_nsISupports, riid)) {
499 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
500 *result = &This->nsIHttpChannel_iface;
501 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
502 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
503 *result = &This->nsIHttpChannel_iface;
504 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
505 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
506 *result = &This->nsIHttpChannel_iface;
507 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
508 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
509 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
510 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
511 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
512 *result = &This->nsIUploadChannel_iface;
513 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
514 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
515 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
516 }else {
517 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
518 *result = NULL;
521 if(*result) {
522 nsIChannel_AddRef(&This->nsIHttpChannel_iface);
523 return NS_OK;
526 return NS_NOINTERFACE;
529 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
531 nsChannel *This = impl_from_nsIHttpChannel(iface);
532 nsrefcnt ref = InterlockedIncrement(&This->ref);
534 TRACE("(%p) ref=%d\n", This, ref);
536 return ref;
539 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
541 nsChannel *This = impl_from_nsIHttpChannel(iface);
542 LONG ref = InterlockedDecrement(&This->ref);
544 if(!ref) {
545 nsIURI_Release(&This->uri->nsIURL_iface);
546 if(This->owner)
547 nsISupports_Release(This->owner);
548 if(This->post_data_stream)
549 nsIInputStream_Release(This->post_data_stream);
550 if(This->load_group)
551 nsILoadGroup_Release(This->load_group);
552 if(This->notif_callback)
553 nsIInterfaceRequestor_Release(This->notif_callback);
554 if(This->original_uri)
555 nsIURI_Release(This->original_uri);
556 if(This->referrer)
557 nsIURI_Release(This->referrer);
559 free_http_headers(&This->response_headers);
560 free_http_headers(&This->request_headers);
562 heap_free(This->content_type);
563 heap_free(This->charset);
564 heap_free(This);
567 return ref;
570 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
572 nsChannel *This = impl_from_nsIHttpChannel(iface);
574 TRACE("(%p)->(%p)\n", This, aName);
576 return nsIURI_GetSpec(&This->uri->nsIURL_iface, aName);
579 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, PRBool *_retval)
581 nsChannel *This = impl_from_nsIHttpChannel(iface);
583 FIXME("(%p)->(%p)\n", This, _retval);
585 return NS_ERROR_NOT_IMPLEMENTED;
588 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
590 nsChannel *This = impl_from_nsIHttpChannel(iface);
592 WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
594 return *aStatus = NS_OK;
597 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
599 nsChannel *This = impl_from_nsIHttpChannel(iface);
601 FIXME("(%p)->(%08x)\n", This, aStatus);
603 return NS_ERROR_NOT_IMPLEMENTED;
606 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
608 nsChannel *This = impl_from_nsIHttpChannel(iface);
610 FIXME("(%p)\n", This);
612 return NS_ERROR_NOT_IMPLEMENTED;
615 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
617 nsChannel *This = impl_from_nsIHttpChannel(iface);
619 FIXME("(%p)\n", This);
621 return NS_ERROR_NOT_IMPLEMENTED;
624 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
626 nsChannel *This = impl_from_nsIHttpChannel(iface);
628 TRACE("(%p)->(%p)\n", This, aLoadGroup);
630 if(This->load_group)
631 nsILoadGroup_AddRef(This->load_group);
633 *aLoadGroup = This->load_group;
634 return NS_OK;
637 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
639 nsChannel *This = impl_from_nsIHttpChannel(iface);
641 TRACE("(%p)->(%p)\n", This, aLoadGroup);
643 if(This->load_group)
644 nsILoadGroup_Release(This->load_group);
645 if(aLoadGroup)
646 nsILoadGroup_AddRef(aLoadGroup);
647 This->load_group = aLoadGroup;
649 return NS_OK;
652 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
654 nsChannel *This = impl_from_nsIHttpChannel(iface);
656 TRACE("(%p)->(%p)\n", This, aLoadFlags);
658 *aLoadFlags = This->load_flags;
659 return NS_OK;
662 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
664 nsChannel *This = impl_from_nsIHttpChannel(iface);
666 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
668 This->load_flags = aLoadFlags;
669 return NS_OK;
672 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
674 nsChannel *This = impl_from_nsIHttpChannel(iface);
676 TRACE("(%p)->(%p)\n", This, aOriginalURI);
678 if(This->original_uri)
679 nsIURI_AddRef(This->original_uri);
681 *aOriginalURI = This->original_uri;
682 return NS_OK;
685 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
687 nsChannel *This = impl_from_nsIHttpChannel(iface);
689 TRACE("(%p)->(%p)\n", This, aOriginalURI);
691 if(This->original_uri)
692 nsIURI_Release(This->original_uri);
694 nsIURI_AddRef(aOriginalURI);
695 This->original_uri = aOriginalURI;
696 return NS_OK;
699 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
701 nsChannel *This = impl_from_nsIHttpChannel(iface);
703 TRACE("(%p)->(%p)\n", This, aURI);
705 nsIURI_AddRef(&This->uri->nsIURL_iface);
706 *aURI = (nsIURI*)This->uri;
708 return NS_OK;
711 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
713 nsChannel *This = impl_from_nsIHttpChannel(iface);
715 TRACE("(%p)->(%p)\n", This, aOwner);
717 if(This->owner)
718 nsISupports_AddRef(This->owner);
719 *aOwner = This->owner;
721 return NS_OK;
724 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
726 nsChannel *This = impl_from_nsIHttpChannel(iface);
728 TRACE("(%p)->(%p)\n", This, aOwner);
730 if(aOwner)
731 nsISupports_AddRef(aOwner);
732 if(This->owner)
733 nsISupports_Release(This->owner);
734 This->owner = aOwner;
736 return NS_OK;
739 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
740 nsIInterfaceRequestor **aNotificationCallbacks)
742 nsChannel *This = impl_from_nsIHttpChannel(iface);
744 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
746 if(This->notif_callback)
747 nsIInterfaceRequestor_AddRef(This->notif_callback);
748 *aNotificationCallbacks = This->notif_callback;
750 return NS_OK;
753 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
754 nsIInterfaceRequestor *aNotificationCallbacks)
756 nsChannel *This = impl_from_nsIHttpChannel(iface);
758 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
760 if(This->notif_callback)
761 nsIInterfaceRequestor_Release(This->notif_callback);
762 if(aNotificationCallbacks)
763 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
765 This->notif_callback = aNotificationCallbacks;
767 return NS_OK;
770 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
772 nsChannel *This = impl_from_nsIHttpChannel(iface);
774 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
776 return NS_ERROR_NOT_IMPLEMENTED;
779 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
781 nsChannel *This = impl_from_nsIHttpChannel(iface);
783 TRACE("(%p)->(%p)\n", This, aContentType);
785 if(This->content_type) {
786 nsACString_SetData(aContentType, This->content_type);
787 return S_OK;
790 if(This->uri->is_doc_uri) {
791 WARN("Document channel with no MIME set. Assuming text/html\n");
792 nsACString_SetData(aContentType, "text/html");
793 return S_OK;
796 WARN("unknown type\n");
797 return NS_ERROR_FAILURE;
800 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
801 const nsACString *aContentType)
803 nsChannel *This = impl_from_nsIHttpChannel(iface);
804 const char *content_type;
806 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
808 nsACString_GetData(aContentType, &content_type);
809 heap_free(This->content_type);
810 This->content_type = heap_strdupA(content_type);
812 return NS_OK;
815 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
816 nsACString *aContentCharset)
818 nsChannel *This = impl_from_nsIHttpChannel(iface);
820 TRACE("(%p)->(%p)\n", This, aContentCharset);
822 if(This->charset) {
823 nsACString_SetData(aContentCharset, This->charset);
824 return NS_OK;
827 nsACString_SetData(aContentCharset, "");
828 return NS_OK;
831 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
832 const nsACString *aContentCharset)
834 nsChannel *This = impl_from_nsIHttpChannel(iface);
835 const char *data;
836 char *charset;
838 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
840 nsACString_GetData(aContentCharset, &data);
841 charset = heap_strdupA(data);
842 if(!charset)
843 return NS_ERROR_OUT_OF_MEMORY;
845 heap_free(This->charset);
846 This->charset = charset;
847 return NS_OK;
850 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, PRInt32 *aContentLength)
852 nsChannel *This = impl_from_nsIHttpChannel(iface);
854 FIXME("(%p)->(%p)\n", This, aContentLength);
856 return NS_ERROR_NOT_IMPLEMENTED;
859 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, PRInt32 aContentLength)
861 nsChannel *This = impl_from_nsIHttpChannel(iface);
863 FIXME("(%p)->(%d)\n", This, aContentLength);
865 return NS_ERROR_NOT_IMPLEMENTED;
868 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
870 nsChannel *This = impl_from_nsIHttpChannel(iface);
872 FIXME("(%p)->(%p)\n", This, _retval);
874 return NS_ERROR_NOT_IMPLEMENTED;
877 static HTMLWindow *get_window_from_load_group(nsChannel *This)
879 HTMLWindow *window;
880 nsIChannel *channel;
881 nsIRequest *req;
882 nsWineURI *wine_uri;
883 nsIURI *uri;
884 nsresult nsres;
886 nsres = nsILoadGroup_GetDefaultLoadRequest(This->load_group, &req);
887 if(NS_FAILED(nsres)) {
888 ERR("GetDefaultLoadRequest failed: %08x\n", nsres);
889 return NULL;
892 if(!req)
893 return NULL;
895 nsres = nsIRequest_QueryInterface(req, &IID_nsIChannel, (void**)&channel);
896 nsIRequest_Release(req);
897 if(NS_FAILED(nsres)) {
898 WARN("Could not get nsIChannel interface: %08x\n", nsres);
899 return NULL;
902 nsres = nsIChannel_GetURI(channel, &uri);
903 nsIChannel_Release(channel);
904 if(NS_FAILED(nsres)) {
905 ERR("GetURI failed: %08x\n", nsres);
906 return NULL;
909 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
910 nsIURI_Release(uri);
911 if(NS_FAILED(nsres)) {
912 TRACE("Could not get nsWineURI: %08x\n", nsres);
913 return NULL;
916 window = wine_uri->window_ref ? wine_uri->window_ref->window : NULL;
917 if(window)
918 IHTMLWindow2_AddRef(&window->IHTMLWindow2_iface);
919 nsIURI_Release(&wine_uri->nsIURL_iface);
921 return window;
924 static HTMLWindow *get_channel_window(nsChannel *This)
926 nsIWebProgress *web_progress;
927 nsIDOMWindow *nswindow;
928 HTMLWindow *window;
929 nsresult nsres;
931 if(This->load_group) {
932 nsIRequestObserver *req_observer;
934 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
935 if(NS_FAILED(nsres) || !req_observer) {
936 ERR("GetGroupObserver failed: %08x\n", nsres);
937 return NULL;
940 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
941 nsIRequestObserver_Release(req_observer);
942 if(NS_FAILED(nsres)) {
943 ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
944 return NULL;
946 }else if(This->notif_callback) {
947 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
948 if(NS_FAILED(nsres)) {
949 ERR("GetInterface(IID_nsIWebProgress failed: %08x\n", nsres);
950 return NULL;
952 }else {
953 ERR("no load group nor notif callback\n");
954 return NULL;
957 nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
958 nsIWebProgress_Release(web_progress);
959 if(NS_FAILED(nsres) || !nswindow) {
960 ERR("GetDOMWindow failed: %08x\n", nsres);
961 return NULL;
964 window = nswindow_to_window(nswindow);
965 nsIDOMWindow_Release(nswindow);
967 if(window)
968 IHTMLWindow2_AddRef(&window->IHTMLWindow2_iface);
969 else
970 FIXME("NULL window for %p\n", nswindow);
971 return window;
974 typedef struct {
975 task_t header;
976 HTMLDocumentNode *doc;
977 nsChannelBSC *bscallback;
978 } start_binding_task_t;
980 static void start_binding_proc(task_t *_task)
982 start_binding_task_t *task = (start_binding_task_t*)_task;
984 start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL);
987 static void start_binding_task_destr(task_t *_task)
989 start_binding_task_t *task = (start_binding_task_t*)_task;
991 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
992 heap_free(task);
995 static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
996 nsISupports *context)
998 nsChannelBSC *bscallback;
999 IMoniker *mon = NULL;
1000 HRESULT hres;
1002 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
1003 if(FAILED(hres)) {
1004 WARN("CreateURLMoniker failed: %08x\n", hres);
1005 return NS_ERROR_UNEXPECTED;
1008 if(is_doc_channel)
1009 set_current_mon(window, mon);
1011 hres = create_channelbsc(mon, NULL, NULL, 0, &bscallback);
1012 IMoniker_Release(mon);
1013 if(FAILED(hres))
1014 return NS_ERROR_UNEXPECTED;
1016 channelbsc_set_channel(bscallback, This, listener, context);
1018 if(is_doc_channel) {
1019 set_window_bscallback(window, bscallback);
1020 async_start_doc_binding(window, bscallback);
1021 IUnknown_Release((IUnknown*)bscallback);
1022 }else {
1023 start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t));
1025 task->doc = window->doc;
1026 task->bscallback = bscallback;
1027 push_task(&task->header, start_binding_proc, start_binding_task_destr, window->doc->basedoc.task_magic);
1030 return NS_OK;
1033 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
1034 nsISupports *aContext)
1036 nsChannel *This = impl_from_nsIHttpChannel(iface);
1037 HTMLWindow *window = NULL;
1038 BOOL cancel = FALSE;
1039 nsresult nsres = NS_OK;
1041 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1043 if(!ensure_uri(This->uri))
1044 return NS_ERROR_FAILURE;
1046 if(TRACE_ON(mshtml)) {
1047 BSTR uri_str;
1048 IUri_GetDisplayUri(This->uri->uri, &uri_str);
1049 TRACE("opening %s\n", debugstr_w(uri_str));
1050 SysFreeString(uri_str);
1053 if(This->uri->is_doc_uri) {
1054 window = get_channel_window(This);
1055 if(window) {
1056 set_uri_window(This->uri, window);
1057 }else if(This->uri->container) {
1058 BOOL b;
1060 /* nscontainer->doc should be NULL which means navigation to a new window */
1061 if(This->uri->container->doc)
1062 FIXME("nscontainer->doc = %p\n", This->uri->container->doc);
1064 nsres = before_async_open(This, This->uri->container, &b);
1065 if(NS_FAILED(nsres))
1066 return nsres;
1067 if(b)
1068 FIXME("Navigation not cancelled\n");
1069 return NS_ERROR_UNEXPECTED;
1073 if(!window) {
1074 if(This->uri->window_ref && This->uri->window_ref->window) {
1075 window = This->uri->window_ref->window;
1076 IHTMLWindow2_AddRef(&window->IHTMLWindow2_iface);
1077 }else {
1078 /* FIXME: Analyze removing get_window_from_load_group call */
1079 if(This->load_group)
1080 window = get_window_from_load_group(This);
1081 if(!window)
1082 window = get_channel_window(This);
1083 if(window)
1084 set_uri_window(This->uri, window);
1088 if(!window) {
1089 ERR("window = NULL\n");
1090 return NS_ERROR_UNEXPECTED;
1093 if(This->uri->is_doc_uri && window == window->doc_obj->basedoc.window) {
1094 if(This->uri->channel_bsc) {
1095 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1097 if(window->doc_obj->mime) {
1098 heap_free(This->content_type);
1099 This->content_type = heap_strdupWtoA(window->doc_obj->mime);
1102 cancel = TRUE;
1103 }else {
1104 nsres = before_async_open(This, window->doc_obj->nscontainer, &cancel);
1105 if(NS_SUCCEEDED(nsres) && cancel) {
1106 TRACE("canceled\n");
1107 nsres = NS_BINDING_ABORTED;
1112 if(!cancel)
1113 nsres = async_open(This, window, This->uri->is_doc_uri, aListener, aContext);
1115 if(NS_SUCCEEDED(nsres) && This->load_group) {
1116 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1117 aContext);
1118 if(NS_FAILED(nsres))
1119 ERR("AddRequest failed: %08x\n", nsres);
1122 IHTMLWindow2_Release(&window->IHTMLWindow2_iface);
1123 return nsres;
1126 static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, PRUint32 *aContentDisposition)
1128 nsChannel *This = impl_from_nsIHttpChannel(iface);
1129 FIXME("(%p)->(%p)\n", This, aContentDisposition);
1130 return NS_ERROR_NOT_IMPLEMENTED;
1133 static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
1135 nsChannel *This = impl_from_nsIHttpChannel(iface);
1136 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1137 return NS_ERROR_NOT_IMPLEMENTED;
1140 static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
1142 nsChannel *This = impl_from_nsIHttpChannel(iface);
1143 FIXME("(%p)->(%p)\n", This, aContentDispositionHeader);
1144 return NS_ERROR_NOT_IMPLEMENTED;
1147 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1149 nsChannel *This = impl_from_nsIHttpChannel(iface);
1151 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1153 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1154 return NS_OK;
1157 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1158 const nsACString *aRequestMethod)
1160 nsChannel *This = impl_from_nsIHttpChannel(iface);
1161 const char *method;
1162 unsigned i;
1164 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1166 nsACString_GetData(aRequestMethod, &method);
1167 for(i=0; i < sizeof(request_method_strings)/sizeof(*request_method_strings); i++) {
1168 if(!strcasecmp(method, request_method_strings[i])) {
1169 This->request_method = i;
1170 return NS_OK;
1174 ERR("Invalid method %s\n", debugstr_a(method));
1175 return NS_ERROR_UNEXPECTED;
1178 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1180 nsChannel *This = impl_from_nsIHttpChannel(iface);
1182 TRACE("(%p)->(%p)\n", This, aReferrer);
1184 if(This->referrer)
1185 nsIURI_AddRef(This->referrer);
1186 *aReferrer = This->referrer;
1187 return NS_OK;
1190 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1192 nsChannel *This = impl_from_nsIHttpChannel(iface);
1194 TRACE("(%p)->(%p)\n", This, aReferrer);
1196 if(aReferrer)
1197 nsIURI_AddRef(aReferrer);
1198 if(This->referrer)
1199 nsIURI_Release(This->referrer);
1200 This->referrer = aReferrer;
1201 return NS_OK;
1204 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1205 const nsACString *aHeader, nsACString *_retval)
1207 nsChannel *This = impl_from_nsIHttpChannel(iface);
1209 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1211 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1214 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1215 const nsACString *aHeader, const nsACString *aValue, PRBool aMerge)
1217 nsChannel *This = impl_from_nsIHttpChannel(iface);
1219 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1221 if(aMerge)
1222 FIXME("aMerge not supported\n");
1224 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1227 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1228 nsIHttpHeaderVisitor *aVisitor)
1230 nsChannel *This = impl_from_nsIHttpChannel(iface);
1232 FIXME("(%p)->(%p)\n", This, aVisitor);
1234 return NS_ERROR_NOT_IMPLEMENTED;
1237 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, PRBool *aAllowPipelining)
1239 nsChannel *This = impl_from_nsIHttpChannel(iface);
1241 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1243 return NS_ERROR_NOT_IMPLEMENTED;
1246 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, PRBool aAllowPipelining)
1248 nsChannel *This = impl_from_nsIHttpChannel(iface);
1250 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1252 return NS_ERROR_NOT_IMPLEMENTED;
1255 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, PRUint32 *aRedirectionLimit)
1257 nsChannel *This = impl_from_nsIHttpChannel(iface);
1259 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1261 return NS_ERROR_NOT_IMPLEMENTED;
1264 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, PRUint32 aRedirectionLimit)
1266 nsChannel *This = impl_from_nsIHttpChannel(iface);
1268 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1270 return NS_ERROR_NOT_IMPLEMENTED;
1273 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, PRUint32 *aResponseStatus)
1275 nsChannel *This = impl_from_nsIHttpChannel(iface);
1277 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1279 if(This->response_status) {
1280 *aResponseStatus = This->response_status;
1281 return NS_OK;
1284 WARN("No response status\n");
1285 return NS_ERROR_UNEXPECTED;
1288 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1289 nsACString *aResponseStatusText)
1291 nsChannel *This = impl_from_nsIHttpChannel(iface);
1293 FIXME("(%p)->(%p)\n", This, aResponseStatusText);
1295 return NS_ERROR_NOT_IMPLEMENTED;
1298 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1299 PRBool *aRequestSucceeded)
1301 nsChannel *This = impl_from_nsIHttpChannel(iface);
1303 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1305 if(!This->response_status)
1306 return NS_ERROR_NOT_AVAILABLE;
1308 *aRequestSucceeded = This->response_status/100 == 2;
1310 return NS_OK;
1313 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1314 const nsACString *header, nsACString *_retval)
1316 nsChannel *This = impl_from_nsIHttpChannel(iface);
1318 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1320 return get_channel_http_header(&This->response_headers, header, _retval);
1323 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1324 const nsACString *header, const nsACString *value, PRBool merge)
1326 nsChannel *This = impl_from_nsIHttpChannel(iface);
1328 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1330 return NS_ERROR_NOT_IMPLEMENTED;
1333 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1334 nsIHttpHeaderVisitor *aVisitor)
1336 nsChannel *This = impl_from_nsIHttpChannel(iface);
1338 TRACE("(%p)->(%p)\n", This, aVisitor);
1340 return visit_http_headers(&This->response_headers, aVisitor);
1343 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, PRBool *_retval)
1345 nsChannel *This = impl_from_nsIHttpChannel(iface);
1346 http_header_t *header;
1348 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1349 static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};
1351 TRACE("(%p)->(%p)\n", This, _retval);
1353 header = find_http_header(&This->response_headers, cache_controlW, sizeof(cache_controlW)/sizeof(WCHAR));
1354 *_retval = header && !strcmpiW(header->data, no_storeW);
1355 return NS_OK;
1358 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, PRBool *_retval)
1360 nsChannel *This = impl_from_nsIHttpChannel(iface);
1362 FIXME("(%p)->(%p)\n", This, _retval);
1364 return NS_ERROR_NOT_IMPLEMENTED;
1367 static const nsIHttpChannelVtbl nsChannelVtbl = {
1368 nsChannel_QueryInterface,
1369 nsChannel_AddRef,
1370 nsChannel_Release,
1371 nsChannel_GetName,
1372 nsChannel_IsPending,
1373 nsChannel_GetStatus,
1374 nsChannel_Cancel,
1375 nsChannel_Suspend,
1376 nsChannel_Resume,
1377 nsChannel_GetLoadGroup,
1378 nsChannel_SetLoadGroup,
1379 nsChannel_GetLoadFlags,
1380 nsChannel_SetLoadFlags,
1381 nsChannel_GetOriginalURI,
1382 nsChannel_SetOriginalURI,
1383 nsChannel_GetURI,
1384 nsChannel_GetOwner,
1385 nsChannel_SetOwner,
1386 nsChannel_GetNotificationCallbacks,
1387 nsChannel_SetNotificationCallbacks,
1388 nsChannel_GetSecurityInfo,
1389 nsChannel_GetContentType,
1390 nsChannel_SetContentType,
1391 nsChannel_GetContentCharset,
1392 nsChannel_SetContentCharset,
1393 nsChannel_GetContentLength,
1394 nsChannel_SetContentLength,
1395 nsChannel_Open,
1396 nsChannel_AsyncOpen,
1397 nsChannel_GetContentDisposition,
1398 nsChannel_GetContentDispositionFilename,
1399 nsChannel_GetContentDispositionHeader,
1400 nsChannel_GetRequestMethod,
1401 nsChannel_SetRequestMethod,
1402 nsChannel_GetReferrer,
1403 nsChannel_SetReferrer,
1404 nsChannel_GetRequestHeader,
1405 nsChannel_SetRequestHeader,
1406 nsChannel_VisitRequestHeaders,
1407 nsChannel_GetAllowPipelining,
1408 nsChannel_SetAllowPipelining,
1409 nsChannel_GetRedirectionLimit,
1410 nsChannel_SetRedirectionLimit,
1411 nsChannel_GetResponseStatus,
1412 nsChannel_GetResponseStatusText,
1413 nsChannel_GetRequestSucceeded,
1414 nsChannel_GetResponseHeader,
1415 nsChannel_SetResponseHeader,
1416 nsChannel_VisitResponseHeaders,
1417 nsChannel_IsNoStoreResponse,
1418 nsChannel_IsNoCacheResponse
1421 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1423 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1426 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1427 void **result)
1429 nsChannel *This = impl_from_nsIUploadChannel(iface);
1430 return nsIChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1433 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1435 nsChannel *This = impl_from_nsIUploadChannel(iface);
1436 return nsIChannel_AddRef(&This->nsIHttpChannel_iface);
1439 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1441 nsChannel *This = impl_from_nsIUploadChannel(iface);
1442 return nsIChannel_Release(&This->nsIHttpChannel_iface);
1445 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1446 nsIInputStream *aStream, const nsACString *aContentType, PRInt32 aContentLength)
1448 nsChannel *This = impl_from_nsIUploadChannel(iface);
1449 const char *content_type;
1451 static const WCHAR content_typeW[] =
1452 {'C','o','n','t','e','n','t','-','T','y','p','e',0};
1454 TRACE("(%p)->(%p %s %d)\n", This, aStream, debugstr_nsacstr(aContentType), aContentLength);
1456 This->post_data_contains_headers = TRUE;
1458 if(aContentType) {
1459 nsACString_GetData(aContentType, &content_type);
1460 if(*content_type) {
1461 WCHAR *ct;
1463 ct = heap_strdupAtoW(content_type);
1464 if(!ct)
1465 return NS_ERROR_UNEXPECTED;
1467 set_http_header(&This->request_headers, content_typeW,
1468 sizeof(content_typeW)/sizeof(WCHAR), ct, strlenW(ct));
1469 heap_free(ct);
1470 This->post_data_contains_headers = FALSE;
1474 if(This->post_data_stream)
1475 nsIInputStream_Release(This->post_data_stream);
1477 if(aContentLength != -1)
1478 FIXME("Unsupported acontentLength = %d\n", aContentLength);
1480 if(This->post_data_stream)
1481 nsIInputStream_Release(This->post_data_stream);
1482 This->post_data_stream = aStream;
1483 if(aStream)
1484 nsIInputStream_AddRef(aStream);
1486 This->request_method = METHOD_POST;
1487 return NS_OK;
1490 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1491 nsIInputStream **aUploadStream)
1493 nsChannel *This = impl_from_nsIUploadChannel(iface);
1495 TRACE("(%p)->(%p)\n", This, aUploadStream);
1497 if(This->post_data_stream)
1498 nsIInputStream_AddRef(This->post_data_stream);
1500 *aUploadStream = This->post_data_stream;
1501 return NS_OK;
1504 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1505 nsUploadChannel_QueryInterface,
1506 nsUploadChannel_AddRef,
1507 nsUploadChannel_Release,
1508 nsUploadChannel_SetUploadStream,
1509 nsUploadChannel_GetUploadStream
1512 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1514 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1517 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1518 void **result)
1520 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1521 return nsIChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1524 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1526 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1527 return nsIChannel_AddRef(&This->nsIHttpChannel_iface);
1530 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1532 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1533 return nsIChannel_Release(&This->nsIHttpChannel_iface);
1536 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1538 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1540 FIXME("(%p)->()\n", This);
1542 return NS_ERROR_NOT_IMPLEMENTED;
1545 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1547 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1549 FIXME("(%p)->()\n", This);
1551 return NS_ERROR_NOT_IMPLEMENTED;
1554 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
1556 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1558 FIXME("(%p)->()\n", This);
1560 return NS_ERROR_NOT_IMPLEMENTED;
1563 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
1565 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1567 FIXME("(%p)->()\n", This);
1569 return NS_ERROR_NOT_IMPLEMENTED;
1572 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1574 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1576 FIXME("(%p)->()\n", This);
1578 return NS_ERROR_NOT_IMPLEMENTED;
1581 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1583 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1585 FIXME("(%p)->()\n", This);
1587 return NS_ERROR_NOT_IMPLEMENTED;
1590 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool *aForceThirdPartyCookie)
1592 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1594 FIXME("(%p)->()\n", This);
1596 return NS_ERROR_NOT_IMPLEMENTED;
1599 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool aForceThirdPartyCookie)
1601 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1603 FIXME("(%p)->()\n", This);
1605 return NS_ERROR_NOT_IMPLEMENTED;
1608 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, PRBool *aCanceled)
1610 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1612 FIXME("(%p)->(%p)\n", This, aCanceled);
1614 return NS_ERROR_NOT_IMPLEMENTED;
1617 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, PRBool *aCanceled)
1619 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1621 FIXME("(%p)->(%p)\n", This, aCanceled);
1623 return NS_ERROR_NOT_IMPLEMENTED;
1626 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, PRBool aCanceled)
1628 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1630 FIXME("(%p)->(%x)\n", This, aCanceled);
1632 return NS_ERROR_NOT_IMPLEMENTED;
1635 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1637 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1639 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1641 return NS_ERROR_NOT_IMPLEMENTED;
1644 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, PRInt32 *aLocalPort)
1646 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1648 FIXME("(%p)->(%p)\n", This, aLocalPort);
1650 return NS_ERROR_NOT_IMPLEMENTED;
1653 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1655 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1657 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1659 return NS_ERROR_NOT_IMPLEMENTED;
1662 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, PRInt32 *aRemotePort)
1664 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1666 FIXME("(%p)->(%p)\n", This, aRemotePort);
1668 return NS_ERROR_NOT_IMPLEMENTED;
1671 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1673 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1675 FIXME("(%p)->(%p)\n", This, cacheKeys);
1677 return NS_ERROR_NOT_IMPLEMENTED;
1680 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1681 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1683 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1684 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1685 return NS_ERROR_NOT_IMPLEMENTED;
1688 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, PRBool *aAllowSpdy)
1690 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1691 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
1692 return NS_ERROR_NOT_IMPLEMENTED;
1695 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, PRBool aAllowSpdy)
1697 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1698 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
1699 return NS_ERROR_NOT_IMPLEMENTED;
1702 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
1703 nsHttpChannelInternal_QueryInterface,
1704 nsHttpChannelInternal_AddRef,
1705 nsHttpChannelInternal_Release,
1706 nsHttpChannelInternal_GetDocumentURI,
1707 nsHttpChannelInternal_SetDocumentURI,
1708 nsHttpChannelInternal_GetRequestVersion,
1709 nsHttpChannelInternal_GetResponseVersion,
1710 nsHttpChannelInternal_SetCookie,
1711 nsHttpChannelInternal_SetupFallbackChannel,
1712 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
1713 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
1714 nsHttpChannelInternal_GetCanceled,
1715 nsHttpChannelInternal_GetChannelIsForDownload,
1716 nsHttpChannelInternal_SetChannelIsForDownload,
1717 nsHttpChannelInternal_GetLocalAddress,
1718 nsHttpChannelInternal_GetLocalPort,
1719 nsHttpChannelInternal_GetRemoteAddress,
1720 nsHttpChannelInternal_GetRemotePort,
1721 nsHttpChannelInternal_SetCacheKeysRedirectChain,
1722 nsHttpChannelInternal_HTTPUpgrade,
1723 nsHttpChannelInternal_GetAllowSpdy,
1724 nsHttpChannelInternal_SetAllowSpdy
1728 static void invalidate_uri(nsWineURI *This)
1730 if(This->uri) {
1731 IUri_Release(This->uri);
1732 This->uri = NULL;
1736 static BOOL ensure_uri_builder(nsWineURI *This)
1738 if(!This->is_mutable) {
1739 WARN("Not mutable URI\n");
1740 return FALSE;
1743 if(!This->uri_builder) {
1744 HRESULT hres;
1746 if(!ensure_uri(This))
1747 return FALSE;
1749 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
1750 if(FAILED(hres)) {
1751 WARN("CreateIUriBuilder failed: %08x\n", hres);
1752 return FALSE;
1756 invalidate_uri(This);
1757 return TRUE;
1760 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
1762 char *vala;
1763 BSTR val;
1764 HRESULT hres;
1766 if(!ensure_uri(This))
1767 return NS_ERROR_UNEXPECTED;
1769 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
1770 if(FAILED(hres)) {
1771 WARN("GetPropertyBSTR failed: %08x\n", hres);
1772 return NS_ERROR_UNEXPECTED;
1775 vala = heap_strdupWtoA(val);
1776 SysFreeString(val);
1777 if(!vala)
1778 return NS_ERROR_OUT_OF_MEMORY;
1780 TRACE("ret %s\n", debugstr_a(vala));
1781 nsACString_SetData(ret, vala);
1782 heap_free(vala);
1783 return NS_OK;
1786 static inline nsWineURI *impl_from_nsIURL(nsIURL *iface)
1788 return CONTAINING_RECORD(iface, nsWineURI, nsIURL_iface);
1791 static nsresult NSAPI nsURI_QueryInterface(nsIURL *iface, nsIIDRef riid, void **result)
1793 nsWineURI *This = impl_from_nsIURL(iface);
1795 *result = NULL;
1797 if(IsEqualGUID(&IID_nsISupports, riid)) {
1798 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
1799 *result = &This->nsIURL_iface;
1800 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
1801 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
1802 *result = &This->nsIURL_iface;
1803 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
1804 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
1805 *result = &This->nsIURL_iface;
1806 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
1807 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
1808 *result = &This->nsIStandardURL_iface;
1809 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
1810 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
1811 *result = &This->nsIStandardURL_iface;
1812 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
1813 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
1814 *result = This;
1817 if(*result) {
1818 nsIURI_AddRef(&This->nsIURL_iface);
1819 return NS_OK;
1822 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1823 return NS_NOINTERFACE;
1826 static nsrefcnt NSAPI nsURI_AddRef(nsIURL *iface)
1828 nsWineURI *This = impl_from_nsIURL(iface);
1829 LONG ref = InterlockedIncrement(&This->ref);
1831 TRACE("(%p) ref=%d\n", This, ref);
1833 return ref;
1836 static nsrefcnt NSAPI nsURI_Release(nsIURL *iface)
1838 nsWineURI *This = impl_from_nsIURL(iface);
1839 LONG ref = InterlockedDecrement(&This->ref);
1841 TRACE("(%p) ref=%d\n", This, ref);
1843 if(!ref) {
1844 if(This->window_ref)
1845 windowref_release(This->window_ref);
1846 if(This->container)
1847 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
1848 if(This->uri)
1849 IUri_Release(This->uri);
1850 heap_free(This);
1853 return ref;
1856 static nsresult NSAPI nsURI_GetSpec(nsIURL *iface, nsACString *aSpec)
1858 nsWineURI *This = impl_from_nsIURL(iface);
1860 TRACE("(%p)->(%p)\n", This, aSpec);
1862 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
1865 static nsresult NSAPI nsURI_SetSpec(nsIURL *iface, const nsACString *aSpec)
1867 nsWineURI *This = impl_from_nsIURL(iface);
1868 const char *speca;
1869 WCHAR *spec;
1870 IUri *uri;
1871 HRESULT hres;
1873 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
1875 if(!This->is_mutable)
1876 return NS_ERROR_UNEXPECTED;
1878 nsACString_GetData(aSpec, &speca);
1879 spec = heap_strdupAtoW(speca);
1880 if(!spec)
1881 return NS_ERROR_OUT_OF_MEMORY;
1883 hres = CreateUri(spec, 0, 0, &uri);
1884 heap_free(spec);
1885 if(FAILED(hres)) {
1886 WARN("CreateUri failed: %08x\n", hres);
1887 return NS_ERROR_FAILURE;
1890 invalidate_uri(This);
1891 if(This->uri_builder) {
1892 IUriBuilder_Release(This->uri_builder);
1893 This->uri_builder = NULL;
1896 This->uri = uri;
1897 return NS_OK;
1900 static nsresult NSAPI nsURI_GetPrePath(nsIURL *iface, nsACString *aPrePath)
1902 nsWineURI *This = impl_from_nsIURL(iface);
1903 FIXME("(%p)->(%p)\n", This, aPrePath);
1904 return NS_ERROR_NOT_IMPLEMENTED;
1907 static nsresult NSAPI nsURI_GetScheme(nsIURL *iface, nsACString *aScheme)
1909 nsWineURI *This = impl_from_nsIURL(iface);
1910 DWORD scheme;
1911 HRESULT hres;
1913 TRACE("(%p)->(%p)\n", This, aScheme);
1915 if(!ensure_uri(This))
1916 return NS_ERROR_UNEXPECTED;
1918 hres = IUri_GetScheme(This->uri, &scheme);
1919 if(FAILED(hres)) {
1920 WARN("GetScheme failed: %08x\n", hres);
1921 return NS_ERROR_UNEXPECTED;
1924 if(scheme == URL_SCHEME_ABOUT) {
1925 nsACString_SetData(aScheme, "wine");
1926 return NS_OK;
1929 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
1932 static nsresult NSAPI nsURI_SetScheme(nsIURL *iface, const nsACString *aScheme)
1934 nsWineURI *This = impl_from_nsIURL(iface);
1935 const char *schemea;
1936 WCHAR *scheme;
1937 HRESULT hres;
1939 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
1941 if(!ensure_uri_builder(This))
1942 return NS_ERROR_UNEXPECTED;
1944 nsACString_GetData(aScheme, &schemea);
1945 scheme = heap_strdupAtoW(schemea);
1946 if(!scheme)
1947 return NS_ERROR_OUT_OF_MEMORY;
1949 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
1950 heap_free(scheme);
1951 if(FAILED(hres))
1952 return NS_ERROR_UNEXPECTED;
1954 return NS_OK;
1957 static nsresult NSAPI nsURI_GetUserPass(nsIURL *iface, nsACString *aUserPass)
1959 nsWineURI *This = impl_from_nsIURL(iface);
1960 BSTR user, pass;
1961 HRESULT hres;
1963 TRACE("(%p)->(%p)\n", This, aUserPass);
1965 if(!ensure_uri(This))
1966 return NS_ERROR_UNEXPECTED;
1968 hres = IUri_GetUserName(This->uri, &user);
1969 if(FAILED(hres))
1970 return NS_ERROR_FAILURE;
1972 hres = IUri_GetPassword(This->uri, &pass);
1973 if(FAILED(hres)) {
1974 SysFreeString(user);
1975 return NS_ERROR_FAILURE;
1978 if(*user || *pass) {
1979 FIXME("Construct user:pass string\n");
1980 }else {
1981 nsACString_SetData(aUserPass, "");
1984 SysFreeString(user);
1985 SysFreeString(pass);
1986 return NS_OK;
1989 static nsresult NSAPI nsURI_SetUserPass(nsIURL *iface, const nsACString *aUserPass)
1991 nsWineURI *This = impl_from_nsIURL(iface);
1992 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
1993 const char *user_pass;
1994 HRESULT hres;
1996 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
1998 if(!ensure_uri_builder(This))
1999 return NS_ERROR_UNEXPECTED;
2001 nsACString_GetData(aUserPass, &user_pass);
2002 if(*user_pass) {
2003 WCHAR *ptr;
2005 buf = heap_strdupAtoW(user_pass);
2006 if(!buf)
2007 return NS_ERROR_OUT_OF_MEMORY;
2009 ptr = strchrW(buf, ':');
2010 if(!ptr) {
2011 user = buf;
2012 }else if(ptr != buf) {
2013 *ptr++ = 0;
2014 user = buf;
2015 if(*ptr)
2016 pass = ptr;
2017 }else {
2018 pass = buf+1;
2022 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2023 if(SUCCEEDED(hres))
2024 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2026 heap_free(buf);
2027 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2030 static nsresult NSAPI nsURI_GetUsername(nsIURL *iface, nsACString *aUsername)
2032 nsWineURI *This = impl_from_nsIURL(iface);
2034 TRACE("(%p)->(%p)\n", This, aUsername);
2036 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2039 static nsresult NSAPI nsURI_SetUsername(nsIURL *iface, const nsACString *aUsername)
2041 nsWineURI *This = impl_from_nsIURL(iface);
2042 const char *usera;
2043 WCHAR *user;
2044 HRESULT hres;
2046 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2048 if(!ensure_uri_builder(This))
2049 return NS_ERROR_UNEXPECTED;
2051 nsACString_GetData(aUsername, &usera);
2052 user = heap_strdupAtoW(usera);
2053 if(!user)
2054 return NS_ERROR_OUT_OF_MEMORY;
2056 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2057 heap_free(user);
2058 if(FAILED(hres))
2059 return NS_ERROR_UNEXPECTED;
2061 return NS_OK;
2064 static nsresult NSAPI nsURI_GetPassword(nsIURL *iface, nsACString *aPassword)
2066 nsWineURI *This = impl_from_nsIURL(iface);
2068 TRACE("(%p)->(%p)\n", This, aPassword);
2070 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2073 static nsresult NSAPI nsURI_SetPassword(nsIURL *iface, const nsACString *aPassword)
2075 nsWineURI *This = impl_from_nsIURL(iface);
2076 const char *passa;
2077 WCHAR *pass;
2078 HRESULT hres;
2080 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2082 if(!ensure_uri_builder(This))
2083 return NS_ERROR_UNEXPECTED;
2085 nsACString_GetData(aPassword, &passa);
2086 pass = heap_strdupAtoW(passa);
2087 if(!pass)
2088 return NS_ERROR_OUT_OF_MEMORY;
2090 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2091 heap_free(pass);
2092 if(FAILED(hres))
2093 return NS_ERROR_UNEXPECTED;
2095 return NS_OK;
2098 static nsresult NSAPI nsURI_GetHostPort(nsIURL *iface, nsACString *aHostPort)
2100 nsWineURI *This = impl_from_nsIURL(iface);
2101 const WCHAR *ptr;
2102 char *vala;
2103 BSTR val;
2104 HRESULT hres;
2106 TRACE("(%p)->(%p)\n", This, aHostPort);
2108 if(!ensure_uri(This))
2109 return NS_ERROR_UNEXPECTED;
2111 hres = IUri_GetAuthority(This->uri, &val);
2112 if(FAILED(hres)) {
2113 WARN("GetAuthority failed: %08x\n", hres);
2114 return NS_ERROR_UNEXPECTED;
2117 ptr = strchrW(val, '@');
2118 if(!ptr)
2119 ptr = val;
2121 vala = heap_strdupWtoA(ptr);
2122 SysFreeString(val);
2123 if(!vala)
2124 return NS_ERROR_OUT_OF_MEMORY;
2126 TRACE("ret %s\n", debugstr_a(vala));
2127 nsACString_SetData(aHostPort, vala);
2128 heap_free(vala);
2129 return NS_OK;
2132 static nsresult NSAPI nsURI_SetHostPort(nsIURL *iface, const nsACString *aHostPort)
2134 nsWineURI *This = impl_from_nsIURL(iface);
2136 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2138 /* Not implemented by Gecko */
2139 return NS_ERROR_NOT_IMPLEMENTED;
2142 static nsresult NSAPI nsURI_GetHost(nsIURL *iface, nsACString *aHost)
2144 nsWineURI *This = impl_from_nsIURL(iface);
2146 TRACE("(%p)->(%p)\n", This, aHost);
2148 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2151 static nsresult NSAPI nsURI_SetHost(nsIURL *iface, const nsACString *aHost)
2153 nsWineURI *This = impl_from_nsIURL(iface);
2154 const char *hosta;
2155 WCHAR *host;
2156 HRESULT hres;
2158 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2160 if(!ensure_uri_builder(This))
2161 return NS_ERROR_UNEXPECTED;
2163 nsACString_GetData(aHost, &hosta);
2164 host = heap_strdupAtoW(hosta);
2165 if(!host)
2166 return NS_ERROR_OUT_OF_MEMORY;
2168 hres = IUriBuilder_SetHost(This->uri_builder, host);
2169 heap_free(host);
2170 if(FAILED(hres))
2171 return NS_ERROR_UNEXPECTED;
2173 return NS_OK;
2176 static nsresult NSAPI nsURI_GetPort(nsIURL *iface, PRInt32 *aPort)
2178 nsWineURI *This = impl_from_nsIURL(iface);
2179 DWORD port;
2180 HRESULT hres;
2182 TRACE("(%p)->(%p)\n", This, aPort);
2184 if(!ensure_uri(This))
2185 return NS_ERROR_UNEXPECTED;
2187 hres = IUri_GetPort(This->uri, &port);
2188 if(FAILED(hres)) {
2189 WARN("GetPort failed: %08x\n", hres);
2190 return NS_ERROR_UNEXPECTED;
2193 *aPort = port ? port : -1;
2194 return NS_OK;
2197 static nsresult NSAPI nsURI_SetPort(nsIURL *iface, PRInt32 aPort)
2199 nsWineURI *This = impl_from_nsIURL(iface);
2200 HRESULT hres;
2202 TRACE("(%p)->(%d)\n", This, aPort);
2204 if(!ensure_uri_builder(This))
2205 return NS_ERROR_UNEXPECTED;
2207 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2208 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2211 static nsresult NSAPI nsURI_GetPath(nsIURL *iface, nsACString *aPath)
2213 nsWineURI *This = impl_from_nsIURL(iface);
2215 TRACE("(%p)->(%p)\n", This, aPath);
2217 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2220 static nsresult NSAPI nsURI_SetPath(nsIURL *iface, const nsACString *aPath)
2222 nsWineURI *This = impl_from_nsIURL(iface);
2223 const char *patha;
2224 WCHAR *path;
2225 HRESULT hres;
2227 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2229 if(!ensure_uri_builder(This))
2230 return NS_ERROR_UNEXPECTED;
2232 nsACString_GetData(aPath, &patha);
2233 path = heap_strdupAtoW(patha);
2234 if(!path)
2235 return NS_ERROR_OUT_OF_MEMORY;
2237 hres = IUriBuilder_SetPath(This->uri_builder, path);
2238 heap_free(path);
2239 if(FAILED(hres))
2240 return NS_ERROR_UNEXPECTED;
2242 return NS_OK;
2245 static nsresult NSAPI nsURI_Equals(nsIURL *iface, nsIURI *other, PRBool *_retval)
2247 nsWineURI *This = impl_from_nsIURL(iface);
2248 nsWineURI *other_obj;
2249 nsresult nsres;
2250 HRESULT hres;
2252 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2254 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2255 if(NS_FAILED(nsres)) {
2256 TRACE("Could not get nsWineURI interface\n");
2257 *_retval = FALSE;
2258 return NS_OK;
2261 if(ensure_uri(This) && ensure_uri(other_obj)) {
2262 BOOL b;
2264 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2265 if(SUCCEEDED(hres)) {
2266 *_retval = b;
2267 nsres = NS_OK;
2268 }else {
2269 nsres = NS_ERROR_FAILURE;
2271 }else {
2272 nsres = NS_ERROR_UNEXPECTED;
2275 nsIURI_Release(&other_obj->nsIURL_iface);
2276 return nsres;
2279 static nsresult NSAPI nsURI_SchemeIs(nsIURL *iface, const char *scheme, PRBool *_retval)
2281 nsWineURI *This = impl_from_nsIURL(iface);
2282 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2283 BSTR scheme_name;
2284 HRESULT hres;
2286 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2288 if(!ensure_uri(This))
2289 return NS_ERROR_UNEXPECTED;
2291 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2292 if(FAILED(hres))
2293 return NS_ERROR_UNEXPECTED;
2295 MultiByteToWideChar(CP_ACP, 0, scheme, -1, buf, sizeof(buf)/sizeof(WCHAR));
2296 *_retval = !strcmpW(scheme_name, buf);
2297 SysFreeString(scheme_name);
2298 return NS_OK;
2301 static nsresult NSAPI nsURI_Clone(nsIURL *iface, nsIURI **_retval)
2303 nsWineURI *This = impl_from_nsIURL(iface);
2304 nsWineURI *wine_uri;
2305 nsresult nsres;
2307 TRACE("(%p)->(%p)\n", This, _retval);
2309 if(!ensure_uri(This))
2310 return NS_ERROR_UNEXPECTED;
2312 nsres = create_nsuri(This->uri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
2313 if(NS_FAILED(nsres)) {
2314 WARN("create_nsuri failed: %08x\n", nsres);
2315 return nsres;
2318 *_retval = (nsIURI*)&wine_uri->nsIURL_iface;
2319 return NS_OK;
2322 static nsresult NSAPI nsURI_Resolve(nsIURL *iface, const nsACString *aRelativePath,
2323 nsACString *_retval)
2325 nsWineURI *This = impl_from_nsIURL(iface);
2326 const char *patha;
2327 IUri *new_uri;
2328 WCHAR *path;
2329 char *reta;
2330 BSTR ret;
2331 HRESULT hres;
2333 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2335 if(!ensure_uri(This))
2336 return NS_ERROR_UNEXPECTED;
2338 nsACString_GetData(aRelativePath, &patha);
2339 path = heap_strdupAtoW(patha);
2340 if(!path)
2341 return NS_ERROR_OUT_OF_MEMORY;
2343 hres = CoInternetCombineUrlEx(This->uri, path, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, &new_uri, 0);
2344 heap_free(path);
2345 if(FAILED(hres)) {
2346 ERR("CoIntenetCombineUrlEx failed: %08x\n", hres);
2347 return NS_ERROR_FAILURE;
2350 hres = IUri_GetDisplayUri(new_uri, &ret);
2351 IUri_Release(new_uri);
2352 if(FAILED(hres))
2353 return NS_ERROR_FAILURE;
2355 reta = heap_strdupWtoA(ret);
2356 SysFreeString(ret);
2357 if(!reta)
2358 return NS_ERROR_OUT_OF_MEMORY;
2360 TRACE("returning %s\n", debugstr_a(reta));
2361 nsACString_SetData(_retval, reta);
2362 heap_free(reta);
2363 return NS_OK;
2366 static nsresult NSAPI nsURI_GetAsciiSpec(nsIURL *iface, nsACString *aAsciiSpec)
2368 nsWineURI *This = impl_from_nsIURL(iface);
2370 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2372 return nsIURI_GetSpec(&This->nsIURL_iface, aAsciiSpec);
2375 static nsresult NSAPI nsURI_GetAsciiHost(nsIURL *iface, nsACString *aAsciiHost)
2377 nsWineURI *This = impl_from_nsIURL(iface);
2379 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2381 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
2384 static nsresult NSAPI nsURI_GetOriginCharset(nsIURL *iface, nsACString *aOriginCharset)
2386 nsWineURI *This = impl_from_nsIURL(iface);
2387 FIXME("(%p)->(%p)\n", This, aOriginCharset);
2388 return NS_ERROR_NOT_IMPLEMENTED;
2391 static nsresult NSAPI nsURL_GetRef(nsIURL *iface, nsACString *aRef)
2393 nsWineURI *This = impl_from_nsIURL(iface);
2394 char *refa = NULL;
2395 BSTR ref;
2396 HRESULT hres;
2398 TRACE("(%p)->(%p)\n", This, aRef);
2400 if(!ensure_uri(This))
2401 return NS_ERROR_UNEXPECTED;
2403 hres = IUri_GetFragment(This->uri, &ref);
2404 if(FAILED(hres))
2405 return NS_ERROR_UNEXPECTED;
2407 refa = heap_strdupWtoA(ref);
2408 SysFreeString(ref);
2409 if(ref && !refa)
2410 return NS_ERROR_OUT_OF_MEMORY;
2412 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
2413 heap_free(refa);
2414 return NS_OK;
2417 static nsresult NSAPI nsURL_SetRef(nsIURL *iface, const nsACString *aRef)
2419 nsWineURI *This = impl_from_nsIURL(iface);
2420 const char *refa;
2421 WCHAR *ref;
2422 HRESULT hres;
2424 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
2426 if(!ensure_uri_builder(This))
2427 return NS_ERROR_UNEXPECTED;
2429 nsACString_GetData(aRef, &refa);
2430 ref = heap_strdupAtoW(refa);
2431 if(!ref)
2432 return NS_ERROR_OUT_OF_MEMORY;
2434 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
2435 heap_free(ref);
2436 if(FAILED(hres))
2437 return NS_ERROR_UNEXPECTED;
2439 return NS_OK;
2442 static nsresult NSAPI nsURI_EqualsExceptRef(nsIURL *iface, nsIURI *other, PRBool *_retval)
2444 nsWineURI *This = impl_from_nsIURL(iface);
2445 nsWineURI *other_obj;
2446 nsresult nsres;
2448 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2450 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2451 if(NS_FAILED(nsres)) {
2452 TRACE("Could not get nsWineURI interface\n");
2453 *_retval = FALSE;
2454 return NS_OK;
2457 if(ensure_uri(This) && ensure_uri(other_obj)) {
2458 *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
2459 nsres = NS_OK;
2460 }else {
2461 nsres = NS_ERROR_UNEXPECTED;
2464 nsIURI_Release(&other_obj->nsIURL_iface);
2465 return nsres;
2468 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIURL *iface, nsIURI **_retval)
2470 nsWineURI *This = impl_from_nsIURL(iface);
2471 nsWineURI *wine_uri;
2472 IUri *uri;
2473 nsresult nsres;
2475 TRACE("(%p)->(%p)\n", This, _retval);
2477 if(!ensure_uri(This))
2478 return NS_ERROR_UNEXPECTED;
2480 uri = get_uri_nofrag(This->uri);
2481 if(!uri)
2482 return NS_ERROR_FAILURE;
2484 nsres = create_nsuri(uri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
2485 IUri_Release(uri);
2486 if(NS_FAILED(nsres)) {
2487 WARN("create_nsuri failed: %08x\n", nsres);
2488 return nsres;
2491 *_retval = (nsIURI*)&wine_uri->nsIURL_iface;
2492 return NS_OK;
2495 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIURL *iface, nsACString *aSpecIgnoringRef)
2497 nsWineURI *This = impl_from_nsIURL(iface);
2499 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
2501 return nsIURL_GetSpec(&This->nsIURL_iface, aSpecIgnoringRef);
2504 static nsresult NSAPI nsURI_GetHasRef(nsIURL *iface, PRBool *aHasRef)
2506 nsWineURI *This = impl_from_nsIURL(iface);
2507 BOOL b;
2508 HRESULT hres;
2510 TRACE("(%p)->(%p)\n", This, aHasRef);
2512 if(!ensure_uri(This))
2513 return NS_ERROR_UNEXPECTED;
2515 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
2516 if(FAILED(hres))
2517 return NS_ERROR_FAILURE;
2519 *aHasRef = b;
2520 return NS_OK;
2523 static nsresult NSAPI nsURL_GetFilePath(nsIURL *iface, nsACString *aFilePath)
2525 nsWineURI *This = impl_from_nsIURL(iface);
2527 TRACE("(%p)->(%p)\n", This, aFilePath);
2529 return nsIURL_GetPath(&This->nsIURL_iface, aFilePath);
2532 static nsresult NSAPI nsURL_SetFilePath(nsIURL *iface, const nsACString *aFilePath)
2534 nsWineURI *This = impl_from_nsIURL(iface);
2536 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
2538 if(!This->is_mutable)
2539 return NS_ERROR_UNEXPECTED;
2541 return nsIURL_SetPath(&This->nsIURL_iface, aFilePath);
2544 static nsresult NSAPI nsURL_GetQuery(nsIURL *iface, nsACString *aQuery)
2546 nsWineURI *This = impl_from_nsIURL(iface);
2548 TRACE("(%p)->(%p)\n", This, aQuery);
2550 return get_uri_string(This, Uri_PROPERTY_QUERY, aQuery);
2553 static nsresult NSAPI nsURL_SetQuery(nsIURL *iface, const nsACString *aQuery)
2555 nsWineURI *This = impl_from_nsIURL(iface);
2556 const char *querya;
2557 WCHAR *query;
2558 HRESULT hres;
2560 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
2562 if(!ensure_uri_builder(This))
2563 return NS_ERROR_UNEXPECTED;
2565 nsACString_GetData(aQuery, &querya);
2566 query = heap_strdupAtoW(querya);
2567 if(!query)
2568 return NS_ERROR_OUT_OF_MEMORY;
2570 hres = IUriBuilder_SetQuery(This->uri_builder, query);
2571 heap_free(query);
2572 if(FAILED(hres))
2573 return NS_ERROR_UNEXPECTED;
2575 return NS_OK;
2578 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
2580 const WCHAR *ptr;
2581 HRESULT hres;
2583 if(!ensure_uri(This))
2584 return NS_ERROR_UNEXPECTED;
2586 hres = IUri_GetPath(This->uri, path);
2587 if(FAILED(hres))
2588 return NS_ERROR_FAILURE;
2590 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
2591 if(*ptr == '/' || *ptr == '\\')
2592 ptr++;
2593 *file = ptr;
2595 if(ext) {
2596 ptr = strrchrW(ptr, '.');
2597 if(!ptr)
2598 ptr = *path + SysStringLen(*path);
2599 *ext = ptr;
2602 return NS_OK;
2605 static nsresult NSAPI nsURL_GetDirectory(nsIURL *iface, nsACString *aDirectory)
2607 nsWineURI *This = impl_from_nsIURL(iface);
2608 const WCHAR *file;
2609 BSTR path;
2610 nsresult nsres;
2612 TRACE("(%p)->(%p)\n", This, aDirectory);
2614 nsres = get_uri_path(This, &path, &file, NULL);
2615 if(NS_FAILED(nsres))
2616 return nsres;
2618 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
2619 SysFreeString(path);
2620 return nsres;
2623 static nsresult NSAPI nsURL_SetDirectory(nsIURL *iface, const nsACString *aDirectory)
2625 nsWineURI *This = impl_from_nsIURL(iface);
2627 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
2629 /* Not implemented by Gecko */
2630 return NS_ERROR_NOT_IMPLEMENTED;
2633 static nsresult NSAPI nsURL_GetFileName(nsIURL *iface, nsACString *aFileName)
2635 nsWineURI *This = impl_from_nsIURL(iface);
2636 const WCHAR *file;
2637 BSTR path;
2638 nsresult nsres;
2640 TRACE("(%p)->(%p)\n", This, aFileName);
2642 nsres = get_uri_path(This, &path, &file, NULL);
2643 if(NS_FAILED(nsres))
2644 return nsres;
2646 nsres = return_wstr_nsacstr(aFileName, file, -1);
2647 SysFreeString(path);
2648 return nsres;
2651 static nsresult NSAPI nsURL_SetFileName(nsIURL *iface, const nsACString *aFileName)
2653 nsWineURI *This = impl_from_nsIURL(iface);
2654 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
2655 return NS_ERROR_NOT_IMPLEMENTED;
2658 static nsresult NSAPI nsURL_GetFileBaseName(nsIURL *iface, nsACString *aFileBaseName)
2660 nsWineURI *This = impl_from_nsIURL(iface);
2661 const WCHAR *file, *ext;
2662 BSTR path;
2663 nsresult nsres;
2665 TRACE("(%p)->(%p)\n", This, aFileBaseName);
2667 nsres = get_uri_path(This, &path, &file, &ext);
2668 if(NS_FAILED(nsres))
2669 return nsres;
2671 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
2672 SysFreeString(path);
2673 return nsres;
2676 static nsresult NSAPI nsURL_SetFileBaseName(nsIURL *iface, const nsACString *aFileBaseName)
2678 nsWineURI *This = impl_from_nsIURL(iface);
2679 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
2680 return NS_ERROR_NOT_IMPLEMENTED;
2683 static nsresult NSAPI nsURL_GetFileExtension(nsIURL *iface, nsACString *aFileExtension)
2685 nsWineURI *This = impl_from_nsIURL(iface);
2687 TRACE("(%p)->(%p)\n", This, aFileExtension);
2689 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
2692 static nsresult NSAPI nsURL_SetFileExtension(nsIURL *iface, const nsACString *aFileExtension)
2694 nsWineURI *This = impl_from_nsIURL(iface);
2695 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
2696 return NS_ERROR_NOT_IMPLEMENTED;
2699 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
2701 nsWineURI *This = impl_from_nsIURL(iface);
2702 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
2703 return NS_ERROR_NOT_IMPLEMENTED;
2706 static nsresult NSAPI nsURL_GetRelativeSpec(nsIURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
2708 nsWineURI *This = impl_from_nsIURL(iface);
2709 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
2710 return NS_ERROR_NOT_IMPLEMENTED;
2713 static const nsIURLVtbl nsURLVtbl = {
2714 nsURI_QueryInterface,
2715 nsURI_AddRef,
2716 nsURI_Release,
2717 nsURI_GetSpec,
2718 nsURI_SetSpec,
2719 nsURI_GetPrePath,
2720 nsURI_GetScheme,
2721 nsURI_SetScheme,
2722 nsURI_GetUserPass,
2723 nsURI_SetUserPass,
2724 nsURI_GetUsername,
2725 nsURI_SetUsername,
2726 nsURI_GetPassword,
2727 nsURI_SetPassword,
2728 nsURI_GetHostPort,
2729 nsURI_SetHostPort,
2730 nsURI_GetHost,
2731 nsURI_SetHost,
2732 nsURI_GetPort,
2733 nsURI_SetPort,
2734 nsURI_GetPath,
2735 nsURI_SetPath,
2736 nsURI_Equals,
2737 nsURI_SchemeIs,
2738 nsURI_Clone,
2739 nsURI_Resolve,
2740 nsURI_GetAsciiSpec,
2741 nsURI_GetAsciiHost,
2742 nsURI_GetOriginCharset,
2743 nsURL_GetRef,
2744 nsURL_SetRef,
2745 nsURI_EqualsExceptRef,
2746 nsURI_CloneIgnoreRef,
2747 nsURI_GetSpecIgnoringRef,
2748 nsURI_GetHasRef,
2749 nsURL_GetFilePath,
2750 nsURL_SetFilePath,
2751 nsURL_GetQuery,
2752 nsURL_SetQuery,
2753 nsURL_GetDirectory,
2754 nsURL_SetDirectory,
2755 nsURL_GetFileName,
2756 nsURL_SetFileName,
2757 nsURL_GetFileBaseName,
2758 nsURL_SetFileBaseName,
2759 nsURL_GetFileExtension,
2760 nsURL_SetFileExtension,
2761 nsURL_GetCommonBaseSpec,
2762 nsURL_GetRelativeSpec
2765 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
2767 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
2770 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
2771 void **result)
2773 nsWineURI *This = impl_from_nsIStandardURL(iface);
2774 return nsIURL_QueryInterface(&This->nsIURL_iface, riid, result);
2777 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
2779 nsWineURI *This = impl_from_nsIStandardURL(iface);
2780 return nsIURL_AddRef(&This->nsIURL_iface);
2783 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
2785 nsWineURI *This = impl_from_nsIStandardURL(iface);
2786 return nsIURL_Release(&This->nsIURL_iface);
2789 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, PRBool *aMutable)
2791 nsWineURI *This = impl_from_nsIStandardURL(iface);
2793 TRACE("(%p)->(%p)\n", This, aMutable);
2795 *aMutable = This->is_mutable;
2796 return NS_OK;
2799 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, PRBool aMutable)
2801 nsWineURI *This = impl_from_nsIStandardURL(iface);
2803 TRACE("(%p)->(%x)\n", This, aMutable);
2805 This->is_mutable = aMutable;
2806 return NS_OK;
2809 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, PRUint32 aUrlType, PRInt32 aDefaultPort,
2810 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
2812 nsWineURI *This = impl_from_nsIStandardURL(iface);
2813 FIXME("(%p)->(%d %d %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
2814 return NS_ERROR_NOT_IMPLEMENTED;
2817 static const nsIStandardURLVtbl nsStandardURLVtbl = {
2818 nsStandardURL_QueryInterface,
2819 nsStandardURL_AddRef,
2820 nsStandardURL_Release,
2821 nsStandardURL_GetMutable,
2822 nsStandardURL_SetMutable,
2823 nsStandardURL_Init
2826 static nsresult create_nsuri(IUri *iuri, HTMLWindow *window, NSContainer *container, nsWineURI **_retval)
2828 nsWineURI *ret = heap_alloc_zero(sizeof(nsWineURI));
2830 ret->nsIURL_iface.lpVtbl = &nsURLVtbl;
2831 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
2832 ret->ref = 1;
2833 ret->is_mutable = TRUE;
2835 set_uri_nscontainer(ret, container);
2836 set_uri_window(ret, window);
2838 IUri_AddRef(iuri);
2839 ret->uri = iuri;
2841 TRACE("retval=%p\n", ret);
2842 *_retval = ret;
2843 return NS_OK;
2846 HRESULT create_doc_uri(HTMLWindow *window, WCHAR *url, nsWineURI **ret)
2848 nsWineURI *uri;
2849 IUri *iuri;
2850 nsresult nsres;
2851 HRESULT hres;
2853 hres = CreateUri(url, 0, 0, &iuri);
2854 if(FAILED(hres))
2855 return hres;
2857 nsres = create_nsuri(iuri, window, window->doc_obj->nscontainer, &uri);
2858 IUri_Release(iuri);
2859 if(NS_FAILED(nsres))
2860 return E_FAIL;
2862 uri->is_doc_uri = TRUE;
2864 *ret = uri;
2865 return S_OK;
2868 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
2870 nsChannel *channel;
2871 HRESULT hres;
2873 if(!ensure_uri(uri))
2874 return NS_ERROR_UNEXPECTED;
2876 channel = heap_alloc_zero(sizeof(nsChannel));
2877 if(!channel)
2878 return NS_ERROR_OUT_OF_MEMORY;
2880 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
2881 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
2882 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
2883 channel->ref = 1;
2884 channel->request_method = METHOD_GET;
2885 list_init(&channel->response_headers);
2886 list_init(&channel->request_headers);
2888 nsIURL_AddRef(&uri->nsIURL_iface);
2889 channel->uri = uri;
2891 hres = IUri_GetScheme(uri->uri, &channel->url_scheme);
2892 if(FAILED(hres))
2893 channel->url_scheme = URL_SCHEME_UNKNOWN;
2895 *ret = channel;
2896 return NS_OK;
2899 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
2901 HTMLWindow *window = NULL;
2902 nsChannel *channel;
2903 nsWineURI *uri;
2904 IUri *iuri;
2905 nsresult nsres;
2906 HRESULT hres;
2908 hres = CreateUri(url, 0, 0, &iuri);
2909 if(FAILED(hres))
2910 return hres;
2912 if(orig_channel->uri->window_ref)
2913 window = orig_channel->uri->window_ref->window;
2914 nsres = create_nsuri(iuri, window, NULL, &uri);
2915 IUri_Release(iuri);
2916 if(NS_FAILED(nsres))
2917 return E_FAIL;
2919 nsres = create_nschannel(uri, &channel);
2920 nsIURL_Release(&uri->nsIURL_iface);
2921 if(NS_FAILED(nsres))
2922 return E_FAIL;
2924 if(orig_channel->load_group) {
2925 nsILoadGroup_AddRef(orig_channel->load_group);
2926 channel->load_group = orig_channel->load_group;
2929 if(orig_channel->notif_callback) {
2930 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
2931 channel->notif_callback = orig_channel->notif_callback;
2934 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
2936 if(orig_channel->request_method == METHOD_POST)
2937 FIXME("unsupported POST method\n");
2939 if(orig_channel->original_uri) {
2940 nsIURI_AddRef(orig_channel->original_uri);
2941 channel->original_uri = orig_channel->original_uri;
2944 if(orig_channel->referrer) {
2945 nsIURI_AddRef(orig_channel->referrer);
2946 channel->referrer = orig_channel->referrer;
2949 *ret = channel;
2950 return S_OK;
2953 typedef struct {
2954 nsIProtocolHandler nsIProtocolHandler_iface;
2956 LONG ref;
2958 nsIProtocolHandler *nshandler;
2959 } nsProtocolHandler;
2961 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
2963 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
2966 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
2967 void **result)
2969 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2971 *result = NULL;
2973 if(IsEqualGUID(&IID_nsISupports, riid)) {
2974 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2975 *result = &This->nsIProtocolHandler_iface;
2976 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
2977 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
2978 *result = &This->nsIProtocolHandler_iface;
2979 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
2980 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
2981 return NS_NOINTERFACE;
2984 if(*result) {
2985 nsISupports_AddRef((nsISupports*)*result);
2986 return NS_OK;
2989 WARN("(%s %p)\n", debugstr_guid(riid), result);
2990 return NS_NOINTERFACE;
2993 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
2995 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
2996 LONG ref = InterlockedIncrement(&This->ref);
2998 TRACE("(%p) ref=%d\n", This, ref);
3000 return ref;
3003 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3005 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3006 LONG ref = InterlockedDecrement(&This->ref);
3008 TRACE("(%p) ref=%d\n", This, ref);
3010 if(!ref) {
3011 if(This->nshandler)
3012 nsIProtocolHandler_Release(This->nshandler);
3013 heap_free(This);
3016 return ref;
3019 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3021 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3023 TRACE("(%p)->(%p)\n", This, aScheme);
3025 if(This->nshandler)
3026 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3027 return NS_ERROR_NOT_IMPLEMENTED;
3030 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3031 PRInt32 *aDefaultPort)
3033 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3035 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3037 if(This->nshandler)
3038 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3039 return NS_ERROR_NOT_IMPLEMENTED;
3042 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3043 PRUint32 *aProtocolFlags)
3045 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3047 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3049 if(This->nshandler)
3050 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3051 return NS_ERROR_NOT_IMPLEMENTED;
3054 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3055 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3057 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3059 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3060 aBaseURI, _retval);
3062 if(This->nshandler)
3063 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3064 return NS_ERROR_NOT_IMPLEMENTED;
3067 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3068 nsIURI *aURI, nsIChannel **_retval)
3070 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3072 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3074 if(This->nshandler)
3075 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3076 return NS_ERROR_NOT_IMPLEMENTED;
3079 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3080 PRInt32 port, const char *scheme, PRBool *_retval)
3082 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3084 TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
3086 if(This->nshandler)
3087 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3088 return NS_ERROR_NOT_IMPLEMENTED;
3091 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3092 nsProtocolHandler_QueryInterface,
3093 nsProtocolHandler_AddRef,
3094 nsProtocolHandler_Release,
3095 nsProtocolHandler_GetScheme,
3096 nsProtocolHandler_GetDefaultPort,
3097 nsProtocolHandler_GetProtocolFlags,
3098 nsProtocolHandler_NewURI,
3099 nsProtocolHandler_NewChannel,
3100 nsProtocolHandler_AllowPort
3103 static nsIProtocolHandler *create_protocol_handler(nsIProtocolHandler *nshandler)
3105 nsProtocolHandler *ret = heap_alloc(sizeof(nsProtocolHandler));
3107 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3108 ret->ref = 1;
3109 ret->nshandler = nshandler;
3111 return &ret->nsIProtocolHandler_iface;
3114 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService*,nsIIDRef,void**);
3116 static nsrefcnt NSAPI nsIOService_AddRef(nsIIOService *iface)
3118 return 2;
3121 static nsrefcnt NSAPI nsIOService_Release(nsIIOService *iface)
3123 return 1;
3126 static nsresult NSAPI nsIOService_GetProtocolHandler(nsIIOService *iface, const char *aScheme,
3127 nsIProtocolHandler **_retval)
3129 nsIExternalProtocolHandler *nsexthandler;
3130 nsIProtocolHandler *nshandler;
3131 nsresult nsres;
3133 TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
3135 nsres = nsIIOService_GetProtocolHandler(nsio, aScheme, &nshandler);
3136 if(NS_FAILED(nsres)) {
3137 WARN("GetProtocolHandler failed: %08x\n", nsres);
3138 return nsres;
3141 nsres = nsIProtocolHandler_QueryInterface(nshandler, &IID_nsIExternalProtocolHandler,
3142 (void**)&nsexthandler);
3143 if(NS_FAILED(nsres)) {
3144 *_retval = nshandler;
3145 return NS_OK;
3148 nsIExternalProtocolHandler_Release(nsexthandler);
3149 *_retval = create_protocol_handler(nshandler);
3150 TRACE("return %p\n", *_retval);
3151 return NS_OK;
3154 static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const char *aScheme,
3155 PRUint32 *_retval)
3157 TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
3158 return nsIIOService_GetProtocolFlags(nsio, aScheme, _retval);
3161 static BOOL is_gecko_special_uri(const char *spec)
3163 static const char *special_schemes[] = {"chrome:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"};
3164 int i;
3166 for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
3167 if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
3168 return TRUE;
3171 if(!strncasecmp(spec, "file:", 5)) {
3172 const char *ptr = spec+5;
3173 while(*ptr == '/')
3174 ptr++;
3175 return is_gecko_path(ptr);
3178 return FALSE;
3181 static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *aSpec,
3182 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3184 nsWineURI *wine_uri, *base_wine_uri = NULL;
3185 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3186 HTMLWindow *window = NULL;
3187 const char *spec = NULL;
3188 IUri *urlmon_uri;
3189 nsresult nsres;
3190 HRESULT hres;
3192 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3193 aBaseURI, _retval);
3195 nsACString_GetData(aSpec, &spec);
3196 if(is_gecko_special_uri(spec))
3197 return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3199 if(!strncmp(spec, "wine:", 5))
3200 spec += 5;
3202 if(aBaseURI) {
3203 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3204 if(NS_SUCCEEDED(nsres)) {
3205 if(!ensure_uri(base_wine_uri))
3206 return NS_ERROR_UNEXPECTED;
3207 if(base_wine_uri->window_ref)
3208 window = base_wine_uri->window_ref->window;
3209 }else {
3210 WARN("Could not get base nsWineURI: %08x\n", nsres);
3214 MultiByteToWideChar(CP_ACP, 0, spec, -1, new_spec, sizeof(new_spec)/sizeof(WCHAR));
3216 if(base_wine_uri) {
3217 hres = CoInternetCombineUrlEx(base_wine_uri->uri, new_spec, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
3218 &urlmon_uri, 0);
3219 if(FAILED(hres))
3220 WARN("CoInternetCombineUrlEx failed: %08x\n", hres);
3221 }else {
3222 hres = CreateUri(new_spec, 0, 0, &urlmon_uri);
3223 if(FAILED(hres))
3224 WARN("CreateUri failed: %08x\n", hres);
3227 if(FAILED(hres))
3228 return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3230 nsres = create_nsuri(urlmon_uri, window, NULL, &wine_uri);
3231 IUri_Release(urlmon_uri);
3232 if(base_wine_uri)
3233 nsIURI_Release(&base_wine_uri->nsIURL_iface);
3234 if(NS_FAILED(nsres))
3235 return nsres;
3237 *_retval = (nsIURI*)&wine_uri->nsIURL_iface;
3238 return nsres;
3241 static nsresult NSAPI nsIOService_NewFileURI(nsIIOService *iface, nsIFile *aFile,
3242 nsIURI **_retval)
3244 TRACE("(%p %p)\n", aFile, _retval);
3245 return nsIIOService_NewFileURI(nsio, aFile, _retval);
3248 static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI *aURI,
3249 nsIChannel **_retval)
3251 nsWineURI *wine_uri;
3252 nsChannel *ret;
3253 nsresult nsres;
3255 TRACE("(%p %p)\n", aURI, _retval);
3257 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3258 if(NS_FAILED(nsres)) {
3259 TRACE("Could not get nsWineURI: %08x\n", nsres);
3260 return nsIIOService_NewChannelFromURI(nsio, aURI, _retval);
3263 nsres = create_nschannel(wine_uri, &ret);
3264 nsIURL_Release(&wine_uri->nsIURL_iface);
3265 if(NS_FAILED(nsres))
3266 return nsres;
3268 nsIURI_AddRef(aURI);
3269 ret->original_uri = aURI;
3271 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3272 return NS_OK;
3275 static nsresult NSAPI nsIOService_NewChannel(nsIIOService *iface, const nsACString *aSpec,
3276 const char *aOriginCharset, nsIURI *aBaseURI, nsIChannel **_retval)
3278 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI, _retval);
3279 return nsIIOService_NewChannel(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3282 static nsresult NSAPI nsIOService_GetOffline(nsIIOService *iface, PRBool *aOffline)
3284 TRACE("(%p)\n", aOffline);
3285 return nsIIOService_GetOffline(nsio, aOffline);
3288 static nsresult NSAPI nsIOService_SetOffline(nsIIOService *iface, PRBool aOffline)
3290 TRACE("(%x)\n", aOffline);
3291 return nsIIOService_SetOffline(nsio, aOffline);
3294 static nsresult NSAPI nsIOService_AllowPort(nsIIOService *iface, PRInt32 aPort,
3295 const char *aScheme, PRBool *_retval)
3297 TRACE("(%d %s %p)\n", aPort, debugstr_a(aScheme), _retval);
3298 return nsIIOService_AllowPort(nsio, aPort, debugstr_a(aScheme), _retval);
3301 static nsresult NSAPI nsIOService_ExtractScheme(nsIIOService *iface, const nsACString *urlString,
3302 nsACString * _retval)
3304 TRACE("(%s %p)\n", debugstr_nsacstr(urlString), _retval);
3305 return nsIIOService_ExtractScheme(nsio, urlString, _retval);
3308 static const nsIIOServiceVtbl nsIOServiceVtbl = {
3309 nsIOService_QueryInterface,
3310 nsIOService_AddRef,
3311 nsIOService_Release,
3312 nsIOService_GetProtocolHandler,
3313 nsIOService_GetProtocolFlags,
3314 nsIOService_NewURI,
3315 nsIOService_NewFileURI,
3316 nsIOService_NewChannelFromURI,
3317 nsIOService_NewChannel,
3318 nsIOService_GetOffline,
3319 nsIOService_SetOffline,
3320 nsIOService_AllowPort,
3321 nsIOService_ExtractScheme
3324 static nsIIOService nsIOService = { &nsIOServiceVtbl };
3326 static nsresult NSAPI nsNetUtil_QueryInterface(nsINetUtil *iface, nsIIDRef riid,
3327 void **result)
3329 return nsIIOService_QueryInterface(&nsIOService, riid, result);
3332 static nsrefcnt NSAPI nsNetUtil_AddRef(nsINetUtil *iface)
3334 return 2;
3337 static nsrefcnt NSAPI nsNetUtil_Release(nsINetUtil *iface)
3339 return 1;
3342 static nsresult NSAPI nsNetUtil_ParseContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
3343 nsACString *aCharset, PRBool *aHadCharset, nsACString *aContentType)
3345 TRACE("(%s %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aHadCharset, aContentType);
3347 return nsINetUtil_ParseContentType(net_util, aTypeHeader, aCharset, aHadCharset, aContentType);
3350 static nsresult NSAPI nsNetUtil_ProtocolHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
3352 TRACE("()\n");
3354 return nsINetUtil_ProtocolHasFlags(net_util, aURI, aFlags, _retval);
3357 static nsresult NSAPI nsNetUtil_URIChainHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
3359 TRACE("(%p %08x %p)\n", aURI, aFlags, _retval);
3361 if(aFlags == (1<<11)) {
3362 *_retval = FALSE;
3363 return NS_OK;
3366 return nsINetUtil_URIChainHasFlags(net_util, aURI, aFlags, _retval);
3369 static nsresult NSAPI nsNetUtil_ToImmutableURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
3371 TRACE("(%p %p)\n", aURI, _retval);
3373 return nsINetUtil_ToImmutableURI(net_util, aURI, _retval);
3376 static nsresult NSAPI nsNetUtil_NewSimpleNestedURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
3378 TRACE("(%p %p)\n", aURI, _retval);
3380 return nsINetUtil_NewSimpleNestedURI(net_util, aURI, _retval);
3383 static nsresult NSAPI nsNetUtil_EscapeString(nsINetUtil *iface, const nsACString *aString,
3384 PRUint32 aEscapeType, nsACString *_retval)
3386 TRACE("(%s %x %p)\n", debugstr_nsacstr(aString), aEscapeType, _retval);
3388 return nsINetUtil_EscapeString(net_util, aString, aEscapeType, _retval);
3391 static nsresult NSAPI nsNetUtil_EscapeURL(nsINetUtil *iface, const nsACString *aStr, PRUint32 aFlags,
3392 nsACString *_retval)
3394 TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval);
3396 return nsINetUtil_EscapeURL(net_util, aStr, aFlags, _retval);
3399 static nsresult NSAPI nsNetUtil_UnescapeString(nsINetUtil *iface, const nsACString *aStr,
3400 PRUint32 aFlags, nsACString *_retval)
3402 TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval);
3404 return nsINetUtil_UnescapeString(net_util, aStr, aFlags, _retval);
3407 static nsresult NSAPI nsNetUtil_ExtractCharsetFromContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
3408 nsACString *aCharset, PRInt32 *aCharsetStart, PRInt32 *aCharsetEnd, PRBool *_retval)
3410 TRACE("(%s %p %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aCharsetStart,
3411 aCharsetEnd, _retval);
3413 return nsINetUtil_ExtractCharsetFromContentType(net_util, aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
3416 static const nsINetUtilVtbl nsNetUtilVtbl = {
3417 nsNetUtil_QueryInterface,
3418 nsNetUtil_AddRef,
3419 nsNetUtil_Release,
3420 nsNetUtil_ParseContentType,
3421 nsNetUtil_ProtocolHasFlags,
3422 nsNetUtil_URIChainHasFlags,
3423 nsNetUtil_ToImmutableURI,
3424 nsNetUtil_NewSimpleNestedURI,
3425 nsNetUtil_EscapeString,
3426 nsNetUtil_EscapeURL,
3427 nsNetUtil_UnescapeString,
3428 nsNetUtil_ExtractCharsetFromContentType
3431 static nsINetUtil nsNetUtil = { &nsNetUtilVtbl };
3433 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService *iface, nsIIDRef riid,
3434 void **result)
3436 *result = NULL;
3438 if(IsEqualGUID(&IID_nsISupports, riid))
3439 *result = &nsIOService;
3440 else if(IsEqualGUID(&IID_nsIIOService, riid))
3441 *result = &nsIOService;
3442 else if(IsEqualGUID(&IID_nsINetUtil, riid))
3443 *result = &nsNetUtil;
3445 if(*result) {
3446 nsISupports_AddRef((nsISupports*)*result);
3447 return NS_OK;
3450 FIXME("(%s %p)\n", debugstr_guid(riid), result);
3451 return NS_NOINTERFACE;
3454 static nsresult NSAPI nsIOServiceFactory_QueryInterface(nsIFactory *iface, nsIIDRef riid,
3455 void **result)
3457 *result = NULL;
3459 if(IsEqualGUID(&IID_nsISupports, riid)) {
3460 TRACE("(IID_nsISupports %p)\n", result);
3461 *result = iface;
3462 }else if(IsEqualGUID(&IID_nsIFactory, riid)) {
3463 TRACE("(IID_nsIFactory %p)\n", result);
3464 *result = iface;
3467 if(*result) {
3468 nsIFactory_AddRef(iface);
3469 return NS_OK;
3472 WARN("(%s %p)\n", debugstr_guid(riid), result);
3473 return NS_NOINTERFACE;
3476 static nsrefcnt NSAPI nsIOServiceFactory_AddRef(nsIFactory *iface)
3478 return 2;
3481 static nsrefcnt NSAPI nsIOServiceFactory_Release(nsIFactory *iface)
3483 return 1;
3486 static nsresult NSAPI nsIOServiceFactory_CreateInstance(nsIFactory *iface,
3487 nsISupports *aOuter, const nsIID *iid, void **result)
3489 return nsIIOService_QueryInterface(&nsIOService, iid, result);
3492 static nsresult NSAPI nsIOServiceFactory_LockFactory(nsIFactory *iface, PRBool lock)
3494 WARN("(%x)\n", lock);
3495 return NS_OK;
3498 static const nsIFactoryVtbl nsIOServiceFactoryVtbl = {
3499 nsIOServiceFactory_QueryInterface,
3500 nsIOServiceFactory_AddRef,
3501 nsIOServiceFactory_Release,
3502 nsIOServiceFactory_CreateInstance,
3503 nsIOServiceFactory_LockFactory
3506 static nsIFactory nsIOServiceFactory = { &nsIOServiceFactoryVtbl };
3508 static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri)
3510 OLECHAR *new_url = NULL;
3511 WCHAR *url;
3512 BOOL ret = FALSE;
3513 HRESULT hres;
3515 if(!doc->hostui || !ensure_uri(uri))
3516 return FALSE;
3518 hres = IUri_GetDisplayUri(uri->uri, &url);
3519 if(FAILED(hres))
3520 return FALSE;
3522 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
3523 if(hres == S_OK && new_url) {
3524 if(strcmpW(url, new_url)) {
3525 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
3526 ret = TRUE;
3528 CoTaskMemFree(new_url);
3531 SysFreeString(url);
3532 return ret;
3535 nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, PRBool *_retval)
3537 nsWineURI *wine_uri;
3538 nsresult nsres;
3540 *_retval = FALSE;
3542 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
3543 if(NS_FAILED(nsres)) {
3544 WARN("Could not get nsWineURI: %08x\n", nsres);
3545 return NS_ERROR_NOT_IMPLEMENTED;
3548 if(!wine_uri->is_doc_uri) {
3549 wine_uri->is_doc_uri = TRUE;
3551 if(!wine_uri->container) {
3552 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
3553 wine_uri->container = nscontainer;
3556 if(nscontainer->doc)
3557 *_retval = translate_url(nscontainer->doc, wine_uri);
3560 nsIURI_Release(&wine_uri->nsIURL_iface);
3561 return NS_OK;
3564 void init_nsio(nsIComponentManager *component_manager, nsIComponentRegistrar *registrar)
3566 nsIFactory *old_factory = NULL;
3567 nsresult nsres;
3569 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
3570 &IID_nsIFactory, (void**)&old_factory);
3571 if(NS_FAILED(nsres)) {
3572 ERR("Could not get factory: %08x\n", nsres);
3573 return;
3576 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
3577 if(NS_FAILED(nsres)) {
3578 ERR("Couldn not create nsIOService instance %08x\n", nsres);
3579 nsIFactory_Release(old_factory);
3580 return;
3583 nsres = nsIIOService_QueryInterface(nsio, &IID_nsINetUtil, (void**)&net_util);
3584 if(NS_FAILED(nsres)) {
3585 WARN("Could not get nsINetUtil interface: %08x\n", nsres);
3586 nsIIOService_Release(nsio);
3587 return;
3590 nsres = nsIComponentRegistrar_UnregisterFactory(registrar, &NS_IOSERVICE_CID, old_factory);
3591 nsIFactory_Release(old_factory);
3592 if(NS_FAILED(nsres))
3593 ERR("UnregisterFactory failed: %08x\n", nsres);
3595 nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_IOSERVICE_CID,
3596 NS_IOSERVICE_CLASSNAME, NS_IOSERVICE_CONTRACTID, &nsIOServiceFactory);
3597 if(NS_FAILED(nsres))
3598 ERR("RegisterFactory failed: %08x\n", nsres);
3601 void release_nsio(void)
3603 if(net_util) {
3604 nsINetUtil_Release(net_util);
3605 net_util = NULL;
3608 if(nsio) {
3609 nsIIOService_Release(nsio);
3610 nsio = NULL;