gphoto2.ds: Set supported groups.
[wine.git] / dlls / mshtml / nsio.c
blobbc1dae9f681c19f0bdcd91d12b76ca647fdb46bf
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;
52 static const char *request_method_strings[] = {"GET", "PUT", "POST"};
54 struct nsWineURI {
55 nsIFileURL nsIFileURL_iface; /* For non-file URL objects, it's just nsIURL */
56 nsIStandardURL nsIStandardURL_iface;
58 LONG ref;
60 NSContainer *container;
61 windowref_t *window_ref;
62 nsChannelBSC *channel_bsc;
63 IUri *uri;
64 IUriBuilder *uri_builder;
65 char *origin_charset;
66 BOOL is_doc_uri;
67 BOOL is_mutable;
68 DWORD scheme;
71 static BOOL ensure_uri(nsWineURI *This)
73 HRESULT hres;
75 assert(This->uri || This->uri_builder);
77 if(!This->uri) {
78 hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
79 if(FAILED(hres)) {
80 WARN("CreateUriSimple failed: %08x\n", hres);
81 return FALSE;
85 return TRUE;
88 IUri *nsuri_get_uri(nsWineURI *nsuri)
90 if(!ensure_uri(nsuri))
91 return NULL;
93 IUri_AddRef(nsuri->uri);
94 return nsuri->uri;
97 IUri *get_uri_nofrag(IUri *uri)
99 IUriBuilder *uri_builder;
100 IUri *ret;
101 BOOL b;
102 HRESULT hres;
104 hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
105 if(SUCCEEDED(hres) && !b) {
106 IUri_AddRef(uri);
107 return uri;
110 hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
111 if(FAILED(hres))
112 return NULL;
114 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
115 if(SUCCEEDED(hres))
116 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
117 IUriBuilder_Release(uri_builder);
118 if(FAILED(hres))
119 return NULL;
121 return ret;
124 static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
126 IUri *uri_nofrag1, *uri_nofrag2;
127 BOOL ret = FALSE;
129 uri_nofrag1 = get_uri_nofrag(uri1);
130 if(!uri_nofrag1)
131 return FALSE;
133 uri_nofrag2 = get_uri_nofrag(uri2);
134 if(uri_nofrag2) {
135 IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
136 IUri_Release(uri_nofrag2);
139 IUri_Release(uri_nofrag1);
140 return ret;
143 static HRESULT combine_url(IUri *base_uri, const WCHAR *rel_url, IUri **ret)
145 IUri *uri_nofrag;
146 HRESULT hres;
148 uri_nofrag = get_uri_nofrag(base_uri);
149 if(!uri_nofrag)
150 return E_FAIL;
152 hres = CoInternetCombineUrlEx(uri_nofrag, rel_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
153 ret, 0);
154 IUri_Release(uri_nofrag);
155 if(FAILED(hres))
156 WARN("CoInternetCombineUrlEx failed: %08x\n", hres);
157 return hres;
160 static nsresult create_nsuri(IUri*,HTMLOuterWindow*,NSContainer*,const char*,nsWineURI**);
162 static const char *debugstr_nsacstr(const nsACString *nsstr)
164 const char *data;
166 nsACString_GetData(nsstr, &data);
167 return debugstr_a(data);
170 static nsresult return_wstr_nsacstr(nsACString *ret_str, const WCHAR *str, int len)
172 char *stra;
173 int lena;
175 TRACE("returning %s\n", debugstr_wn(str, len));
177 if(!*str) {
178 nsACString_SetData(ret_str, "");
179 return NS_OK;
182 lena = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
183 stra = heap_alloc(lena+1);
184 if(!stra)
185 return NS_ERROR_OUT_OF_MEMORY;
187 WideCharToMultiByte(CP_UTF8, 0, str, len, stra, lena, NULL, NULL);
188 stra[lena] = 0;
190 nsACString_SetData(ret_str, stra);
191 heap_free(stra);
192 return NS_OK;
195 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
197 const WCHAR *ptr = nsuri;
199 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
201 if(!strncmpW(nsuri, wine_prefixW, sizeof(wine_prefixW)/sizeof(WCHAR)))
202 ptr += sizeof(wine_prefixW)/sizeof(WCHAR);
204 if(*ptr || ret_empty) {
205 *ret = SysAllocString(ptr);
206 if(!*ret)
207 return E_OUTOFMEMORY;
208 }else {
209 *ret = NULL;
212 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
213 return S_OK;
216 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
218 IOleCommandTarget *cmdtrg = NULL;
219 HRESULT hres;
221 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
222 if(SUCCEEDED(hres)) {
223 VARIANT varUrl, varRes;
225 V_VT(&varUrl) = VT_BSTR;
226 V_BSTR(&varUrl) = url;
227 V_VT(&varRes) = VT_BOOL;
229 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
231 IOleCommandTarget_Release(cmdtrg);
233 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
234 TRACE("got VARIANT_FALSE, do not load\n");
235 return FALSE;
239 return TRUE;
242 static nsresult before_async_open(nsChannel *channel, NSContainer *container, BOOL *cancel)
244 HTMLDocumentObj *doc = container->doc;
245 BSTR display_uri;
246 HRESULT hres;
248 if(!doc->client) {
249 *cancel = TRUE;
250 return NS_OK;
253 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
254 if(FAILED(hres))
255 return NS_ERROR_FAILURE;
257 if(!exec_shldocvw_67(doc, display_uri)) {
258 SysFreeString(display_uri);
259 *cancel = FALSE;
260 return NS_OK;
263 hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, 0, cancel);
264 SysFreeString(display_uri);
265 if(FAILED(hres))
266 *cancel = TRUE;
267 return NS_OK;
270 HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsIInputStream *post_stream,
271 nsChannelBSC *channelbsc, DWORD flags)
273 nsIWebNavigation *web_navigation;
274 nsIDocShellLoadInfo *load_info;
275 nsIDocShell *doc_shell;
276 HTMLDocumentNode *doc;
277 nsresult nsres;
279 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
280 if(NS_FAILED(nsres)) {
281 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
282 return E_FAIL;
285 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
286 nsIWebNavigation_Release(web_navigation);
287 if(NS_FAILED(nsres)) {
288 ERR("Could not get nsIDocShell: %08x\n", nsres);
289 return E_FAIL;
292 nsres = nsIDocShell_CreateLoadInfo(doc_shell, &load_info);
293 if(NS_FAILED(nsres)) {
294 nsIDocShell_Release(doc_shell);
295 return E_FAIL;
298 nsres = nsIDocShellLoadInfo_SetLoadType(load_info, (flags & LOAD_FLAGS_BYPASS_CACHE) ? loadNormalBypassCache : loadNormal);
299 assert(nsres == NS_OK);
301 if(post_stream) {
302 nsres = nsIDocShellLoadInfo_SetPostDataStream(load_info, post_stream);
303 assert(nsres == NS_OK);
306 if(window->uri_nofrag) {
307 nsWineURI *referrer_uri;
308 nsres = create_nsuri(window->uri_nofrag, window, window->doc_obj ? window->doc_obj->nscontainer : NULL, NULL, &referrer_uri);
309 if(NS_SUCCEEDED(nsres)) {
310 nsres = nsIDocShellLoadInfo_SetReferrer(load_info, (nsIURI*)&referrer_uri->nsIFileURL_iface);
311 assert(nsres == NS_OK);
312 nsIFileURL_Release(&referrer_uri->nsIFileURL_iface);
316 uri->channel_bsc = channelbsc;
317 doc = window->base.inner_window->doc;
318 doc->skip_mutation_notif = TRUE;
319 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, load_info, flags, FALSE);
320 if(doc == window->base.inner_window->doc)
321 doc->skip_mutation_notif = FALSE;
322 uri->channel_bsc = NULL;
323 nsIDocShell_Release(doc_shell);
324 nsIDocShellLoadInfo_Release(load_info);
325 if(NS_FAILED(nsres)) {
326 WARN("LoadURI failed: %08x\n", nsres);
327 return E_FAIL;
330 return S_OK;
333 static void set_uri_nscontainer(nsWineURI *This, NSContainer *nscontainer)
335 if(This->container) {
336 if(This->container == nscontainer)
337 return;
338 TRACE("Changing %p -> %p\n", This->container, nscontainer);
339 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
342 if(nscontainer)
343 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
344 This->container = nscontainer;
347 static void set_uri_window(nsWineURI *This, HTMLOuterWindow *window)
349 if(This->window_ref) {
350 if(This->window_ref->window == window)
351 return;
352 TRACE("Changing %p -> %p\n", This->window_ref->window, window);
353 windowref_release(This->window_ref);
356 if(window) {
357 windowref_addref(window->window_ref);
358 This->window_ref = window->window_ref;
360 if(window->doc_obj)
361 set_uri_nscontainer(This, window->doc_obj->nscontainer);
362 }else {
363 This->window_ref = NULL;
367 static inline BOOL is_http_channel(nsChannel *This)
369 return This->uri->scheme == URL_SCHEME_HTTP || This->uri->scheme == URL_SCHEME_HTTPS;
372 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
374 http_header_t *iter;
376 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
377 if(!strncmpiW(iter->header, name, len) && !iter->header[len])
378 return iter;
381 return NULL;
384 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
385 nsACString *_retval)
387 const char *header_namea;
388 http_header_t *header;
389 WCHAR *header_name;
390 char *data;
392 nsACString_GetData(header_name_str, &header_namea);
393 header_name = heap_strdupAtoW(header_namea);
394 if(!header_name)
395 return NS_ERROR_UNEXPECTED;
397 header = find_http_header(headers, header_name, strlenW(header_name));
398 heap_free(header_name);
399 if(!header)
400 return NS_ERROR_NOT_AVAILABLE;
402 data = heap_strdupWtoA(header->data);
403 if(!data)
404 return NS_ERROR_UNEXPECTED;
406 TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
407 nsACString_SetData(_retval, data);
408 heap_free(data);
409 return NS_OK;
412 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
413 const WCHAR *value, int value_len)
415 http_header_t *header;
417 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
419 header = find_http_header(headers, name, name_len);
420 if(header) {
421 WCHAR *new_data;
423 new_data = heap_strndupW(value, value_len);
424 if(!new_data)
425 return E_OUTOFMEMORY;
427 heap_free(header->data);
428 header->data = new_data;
429 }else {
430 header = heap_alloc(sizeof(http_header_t));
431 if(!header)
432 return E_OUTOFMEMORY;
434 header->header = heap_strndupW(name, name_len);
435 header->data = heap_strndupW(value, value_len);
436 if(!header->header || !header->data) {
437 heap_free(header->header);
438 heap_free(header->data);
439 heap_free(header);
440 return E_OUTOFMEMORY;
443 list_add_tail(headers, &header->entry);
446 return S_OK;
449 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
450 const nsACString *value_str)
452 const char *namea, *valuea;
453 WCHAR *name, *value;
454 HRESULT hres;
456 nsACString_GetData(name_str, &namea);
457 name = heap_strdupAtoW(namea);
458 if(!name)
459 return NS_ERROR_UNEXPECTED;
461 nsACString_GetData(value_str, &valuea);
462 value = heap_strdupAtoW(valuea);
463 if(!value) {
464 heap_free(name);
465 return NS_ERROR_UNEXPECTED;
468 hres = set_http_header(headers, name, strlenW(name), value, strlenW(value));
470 heap_free(name);
471 heap_free(value);
472 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
475 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
477 nsACString header_str, value_str;
478 char *header, *value;
479 http_header_t *iter;
480 nsresult nsres;
482 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
483 header = heap_strdupWtoA(iter->header);
484 if(!header)
485 return NS_ERROR_OUT_OF_MEMORY;
487 value = heap_strdupWtoA(iter->data);
488 if(!value) {
489 heap_free(header);
490 return NS_ERROR_OUT_OF_MEMORY;
493 nsACString_InitDepend(&header_str, header);
494 nsACString_InitDepend(&value_str, value);
495 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
496 nsACString_Finish(&header_str);
497 nsACString_Finish(&value_str);
498 heap_free(header);
499 heap_free(value);
500 if(NS_FAILED(nsres))
501 break;
504 return NS_OK;
507 static void free_http_headers(struct list *list)
509 http_header_t *iter, *iter_next;
511 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
512 list_remove(&iter->entry);
513 heap_free(iter->header);
514 heap_free(iter->data);
515 heap_free(iter);
519 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
521 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
524 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
526 nsChannel *This = impl_from_nsIHttpChannel(iface);
528 if(IsEqualGUID(&IID_nsISupports, riid)) {
529 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
530 *result = &This->nsIHttpChannel_iface;
531 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
532 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
533 *result = &This->nsIHttpChannel_iface;
534 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
535 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
536 *result = &This->nsIHttpChannel_iface;
537 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
538 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
539 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
540 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
541 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
542 *result = &This->nsIUploadChannel_iface;
543 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
544 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
545 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
546 }else {
547 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
548 *result = NULL;
551 if(*result) {
552 nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
553 return NS_OK;
556 return NS_NOINTERFACE;
559 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
561 nsChannel *This = impl_from_nsIHttpChannel(iface);
562 nsrefcnt ref = InterlockedIncrement(&This->ref);
564 TRACE("(%p) ref=%d\n", This, ref);
566 return ref;
569 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
571 nsChannel *This = impl_from_nsIHttpChannel(iface);
572 LONG ref = InterlockedDecrement(&This->ref);
574 if(!ref) {
575 nsIFileURL_Release(&This->uri->nsIFileURL_iface);
576 if(This->owner)
577 nsISupports_Release(This->owner);
578 if(This->post_data_stream)
579 nsIInputStream_Release(This->post_data_stream);
580 if(This->load_group)
581 nsILoadGroup_Release(This->load_group);
582 if(This->notif_callback)
583 nsIInterfaceRequestor_Release(This->notif_callback);
584 if(This->original_uri)
585 nsIURI_Release(This->original_uri);
586 if(This->referrer)
587 nsIURI_Release(This->referrer);
589 free_http_headers(&This->response_headers);
590 free_http_headers(&This->request_headers);
592 heap_free(This->content_type);
593 heap_free(This->charset);
594 heap_free(This);
597 return ref;
600 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
602 nsChannel *This = impl_from_nsIHttpChannel(iface);
604 TRACE("(%p)->(%p)\n", This, aName);
606 return nsIFileURL_GetSpec(&This->uri->nsIFileURL_iface, aName);
609 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, cpp_bool *_retval)
611 nsChannel *This = impl_from_nsIHttpChannel(iface);
613 FIXME("(%p)->(%p)\n", This, _retval);
615 return NS_ERROR_NOT_IMPLEMENTED;
618 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
620 nsChannel *This = impl_from_nsIHttpChannel(iface);
622 WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
624 return *aStatus = NS_OK;
627 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
629 nsChannel *This = impl_from_nsIHttpChannel(iface);
631 TRACE("(%p)->(%08x)\n", This, aStatus);
633 if(This->binding && This->binding->bsc.binding)
634 IBinding_Abort(This->binding->bsc.binding);
635 else
636 WARN("No binding to cancel\n");
637 return NS_OK;
640 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
642 nsChannel *This = impl_from_nsIHttpChannel(iface);
644 FIXME("(%p)\n", This);
646 return NS_ERROR_NOT_IMPLEMENTED;
649 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
651 nsChannel *This = impl_from_nsIHttpChannel(iface);
653 FIXME("(%p)\n", This);
655 return NS_ERROR_NOT_IMPLEMENTED;
658 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
660 nsChannel *This = impl_from_nsIHttpChannel(iface);
662 TRACE("(%p)->(%p)\n", This, aLoadGroup);
664 if(This->load_group)
665 nsILoadGroup_AddRef(This->load_group);
667 *aLoadGroup = This->load_group;
668 return NS_OK;
671 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
673 nsChannel *This = impl_from_nsIHttpChannel(iface);
675 TRACE("(%p)->(%p)\n", This, aLoadGroup);
677 if(This->load_group)
678 nsILoadGroup_Release(This->load_group);
679 if(aLoadGroup)
680 nsILoadGroup_AddRef(aLoadGroup);
681 This->load_group = aLoadGroup;
683 return NS_OK;
686 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
688 nsChannel *This = impl_from_nsIHttpChannel(iface);
690 TRACE("(%p)->(%p)\n", This, aLoadFlags);
692 *aLoadFlags = This->load_flags;
693 return NS_OK;
696 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
698 nsChannel *This = impl_from_nsIHttpChannel(iface);
700 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
702 This->load_flags = aLoadFlags;
703 return NS_OK;
706 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
708 nsChannel *This = impl_from_nsIHttpChannel(iface);
710 TRACE("(%p)->(%p)\n", This, aOriginalURI);
712 if(This->original_uri)
713 nsIURI_AddRef(This->original_uri);
715 *aOriginalURI = This->original_uri;
716 return NS_OK;
719 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
721 nsChannel *This = impl_from_nsIHttpChannel(iface);
723 TRACE("(%p)->(%p)\n", This, aOriginalURI);
725 if(This->original_uri)
726 nsIURI_Release(This->original_uri);
728 nsIURI_AddRef(aOriginalURI);
729 This->original_uri = aOriginalURI;
730 return NS_OK;
733 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
735 nsChannel *This = impl_from_nsIHttpChannel(iface);
737 TRACE("(%p)->(%p)\n", This, aURI);
739 nsIFileURL_AddRef(&This->uri->nsIFileURL_iface);
740 *aURI = (nsIURI*)&This->uri->nsIFileURL_iface;
742 return NS_OK;
745 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
747 nsChannel *This = impl_from_nsIHttpChannel(iface);
749 TRACE("(%p)->(%p)\n", This, aOwner);
751 if(This->owner)
752 nsISupports_AddRef(This->owner);
753 *aOwner = This->owner;
755 return NS_OK;
758 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
760 nsChannel *This = impl_from_nsIHttpChannel(iface);
762 TRACE("(%p)->(%p)\n", This, aOwner);
764 if(aOwner)
765 nsISupports_AddRef(aOwner);
766 if(This->owner)
767 nsISupports_Release(This->owner);
768 This->owner = aOwner;
770 return NS_OK;
773 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
774 nsIInterfaceRequestor **aNotificationCallbacks)
776 nsChannel *This = impl_from_nsIHttpChannel(iface);
778 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
780 if(This->notif_callback)
781 nsIInterfaceRequestor_AddRef(This->notif_callback);
782 *aNotificationCallbacks = This->notif_callback;
784 return NS_OK;
787 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
788 nsIInterfaceRequestor *aNotificationCallbacks)
790 nsChannel *This = impl_from_nsIHttpChannel(iface);
792 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
794 if(This->notif_callback)
795 nsIInterfaceRequestor_Release(This->notif_callback);
796 if(aNotificationCallbacks)
797 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
799 This->notif_callback = aNotificationCallbacks;
801 return NS_OK;
804 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
806 nsChannel *This = impl_from_nsIHttpChannel(iface);
808 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
810 return NS_ERROR_NOT_IMPLEMENTED;
813 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
815 nsChannel *This = impl_from_nsIHttpChannel(iface);
817 TRACE("(%p)->(%p)\n", This, aContentType);
819 if(This->content_type) {
820 nsACString_SetData(aContentType, This->content_type);
821 return S_OK;
824 if(This->uri->is_doc_uri) {
825 WARN("Document channel with no MIME set. Assuming text/html\n");
826 nsACString_SetData(aContentType, "text/html");
827 return S_OK;
830 WARN("unknown type\n");
831 return NS_ERROR_FAILURE;
834 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
835 const nsACString *aContentType)
837 nsChannel *This = impl_from_nsIHttpChannel(iface);
838 const char *content_type;
840 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
842 nsACString_GetData(aContentType, &content_type);
843 heap_free(This->content_type);
844 This->content_type = heap_strdupA(content_type);
846 return NS_OK;
849 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
850 nsACString *aContentCharset)
852 nsChannel *This = impl_from_nsIHttpChannel(iface);
854 TRACE("(%p)->(%p)\n", This, aContentCharset);
856 if(This->charset) {
857 nsACString_SetData(aContentCharset, This->charset);
858 return NS_OK;
861 nsACString_SetData(aContentCharset, "");
862 return NS_OK;
865 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
866 const nsACString *aContentCharset)
868 nsChannel *This = impl_from_nsIHttpChannel(iface);
869 const char *data;
870 char *charset;
872 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
874 nsACString_GetData(aContentCharset, &data);
875 charset = heap_strdupA(data);
876 if(!charset)
877 return NS_ERROR_OUT_OF_MEMORY;
879 heap_free(This->charset);
880 This->charset = charset;
881 return NS_OK;
884 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, INT64 *aContentLength)
886 nsChannel *This = impl_from_nsIHttpChannel(iface);
888 FIXME("(%p)->(%p)\n", This, aContentLength);
890 return NS_ERROR_NOT_IMPLEMENTED;
893 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, INT64 aContentLength)
895 nsChannel *This = impl_from_nsIHttpChannel(iface);
897 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aContentLength));
899 return NS_ERROR_NOT_IMPLEMENTED;
902 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
904 nsChannel *This = impl_from_nsIHttpChannel(iface);
906 FIXME("(%p)->(%p)\n", This, _retval);
908 return NS_ERROR_NOT_IMPLEMENTED;
911 static nsresult NSAPI nsChannel_Open2(nsIHttpChannel *iface, nsIInputStream **_retval)
913 nsChannel *This = impl_from_nsIHttpChannel(iface);
915 FIXME("(%p)->(%p)\n", This, _retval);
917 return NS_ERROR_NOT_IMPLEMENTED;
920 static HTMLOuterWindow *get_window_from_load_group(nsChannel *This)
922 HTMLOuterWindow *window;
923 nsIChannel *channel;
924 nsIRequest *req;
925 nsWineURI *wine_uri;
926 nsIURI *uri;
927 nsresult nsres;
929 nsres = nsILoadGroup_GetDefaultLoadRequest(This->load_group, &req);
930 if(NS_FAILED(nsres)) {
931 ERR("GetDefaultLoadRequest failed: %08x\n", nsres);
932 return NULL;
935 if(!req)
936 return NULL;
938 nsres = nsIRequest_QueryInterface(req, &IID_nsIChannel, (void**)&channel);
939 nsIRequest_Release(req);
940 if(NS_FAILED(nsres)) {
941 WARN("Could not get nsIChannel interface: %08x\n", nsres);
942 return NULL;
945 nsres = nsIChannel_GetURI(channel, &uri);
946 nsIChannel_Release(channel);
947 if(NS_FAILED(nsres)) {
948 ERR("GetURI failed: %08x\n", nsres);
949 return NULL;
952 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
953 nsIURI_Release(uri);
954 if(NS_FAILED(nsres)) {
955 TRACE("Could not get nsWineURI: %08x\n", nsres);
956 return NULL;
959 window = wine_uri->window_ref ? wine_uri->window_ref->window : NULL;
960 if(window)
961 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
962 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
964 return window;
967 static HTMLOuterWindow *get_channel_window(nsChannel *This)
969 nsIWebProgress *web_progress;
970 mozIDOMWindowProxy *mozwindow;
971 HTMLOuterWindow *window;
972 nsresult nsres;
974 if(This->load_group) {
975 nsIRequestObserver *req_observer;
977 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
978 if(NS_FAILED(nsres) || !req_observer) {
979 ERR("GetGroupObserver failed: %08x\n", nsres);
980 return NULL;
983 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
984 nsIRequestObserver_Release(req_observer);
985 if(NS_FAILED(nsres)) {
986 ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
987 return NULL;
989 }else if(This->notif_callback) {
990 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
991 if(NS_FAILED(nsres)) {
992 ERR("GetInterface(IID_nsIWebProgress failed: %08x\n", nsres);
993 return NULL;
995 }else {
996 ERR("no load group nor notif callback\n");
997 return NULL;
1000 nsres = nsIWebProgress_GetDOMWindow(web_progress, &mozwindow);
1001 nsIWebProgress_Release(web_progress);
1002 if(NS_FAILED(nsres) || !mozwindow) {
1003 ERR("GetDOMWindow failed: %08x\n", nsres);
1004 return NULL;
1007 window = mozwindow_to_window(mozwindow);
1008 mozIDOMWindowProxy_Release(mozwindow);
1010 if(window)
1011 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
1012 else
1013 FIXME("NULL window for %p\n", mozwindow);
1014 return window;
1017 typedef struct {
1018 task_t header;
1019 HTMLInnerWindow *window;
1020 nsChannelBSC *bscallback;
1021 } start_binding_task_t;
1023 static void start_binding_proc(task_t *_task)
1025 start_binding_task_t *task = (start_binding_task_t*)_task;
1027 start_binding(task->window, (BSCallback*)task->bscallback, NULL);
1030 static void start_binding_task_destr(task_t *_task)
1032 start_binding_task_t *task = (start_binding_task_t*)_task;
1034 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
1035 heap_free(task);
1038 static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
1039 nsISupports *context)
1041 nsChannelBSC *bscallback;
1042 IMoniker *mon = NULL;
1043 HRESULT hres;
1045 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
1046 if(FAILED(hres)) {
1047 WARN("CreateURLMoniker failed: %08x\n", hres);
1048 return NS_ERROR_UNEXPECTED;
1051 if(is_doc_channel)
1052 set_current_mon(window, mon, BINDING_NAVIGATED);
1054 hres = create_channelbsc(mon, NULL, NULL, 0, is_doc_channel, &bscallback);
1055 IMoniker_Release(mon);
1056 if(FAILED(hres))
1057 return NS_ERROR_UNEXPECTED;
1059 channelbsc_set_channel(bscallback, This, listener, context);
1061 if(is_doc_channel) {
1062 hres = create_pending_window(window, bscallback);
1063 if(SUCCEEDED(hres))
1064 async_start_doc_binding(window, window->pending_window);
1065 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1066 if(FAILED(hres))
1067 return NS_ERROR_UNEXPECTED;
1068 }else {
1069 start_binding_task_t *task;
1071 task = heap_alloc(sizeof(start_binding_task_t));
1072 if(!task) {
1073 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1074 return NS_ERROR_OUT_OF_MEMORY;
1077 task->window = window->base.inner_window;
1078 task->bscallback = bscallback;
1079 hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic);
1080 if(FAILED(hres))
1081 return NS_ERROR_OUT_OF_MEMORY;
1084 return NS_OK;
1087 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
1088 nsISupports *aContext)
1090 nsChannel *This = impl_from_nsIHttpChannel(iface);
1091 HTMLOuterWindow *window = NULL;
1092 BOOL cancel = FALSE;
1093 nsresult nsres = NS_OK;
1095 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1097 if(!ensure_uri(This->uri))
1098 return NS_ERROR_FAILURE;
1100 if(TRACE_ON(mshtml)) {
1101 HRESULT hres;
1102 BSTR uri_str;
1104 hres = IUri_GetDisplayUri(This->uri->uri, &uri_str);
1105 if(SUCCEEDED(hres)) {
1106 TRACE("opening %s\n", debugstr_w(uri_str));
1107 SysFreeString(uri_str);
1108 }else {
1109 WARN("GetDisplayUri failed: %08x\n", hres);
1113 if(This->uri->is_doc_uri) {
1114 window = get_channel_window(This);
1115 if(window) {
1116 set_uri_window(This->uri, window);
1117 }else if(This->uri->container) {
1118 BOOL b;
1120 /* nscontainer->doc should be NULL which means navigation to a new window */
1121 if(This->uri->container->doc)
1122 FIXME("nscontainer->doc = %p\n", This->uri->container->doc);
1124 nsres = before_async_open(This, This->uri->container, &b);
1125 if(NS_FAILED(nsres))
1126 return nsres;
1127 if(b)
1128 FIXME("Navigation not cancelled\n");
1129 return NS_ERROR_UNEXPECTED;
1133 if(!window) {
1134 if(This->uri->window_ref && This->uri->window_ref->window) {
1135 window = This->uri->window_ref->window;
1136 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
1137 }else {
1138 /* FIXME: Analyze removing get_window_from_load_group call */
1139 if(This->load_group)
1140 window = get_window_from_load_group(This);
1141 if(!window)
1142 window = get_channel_window(This);
1143 if(window)
1144 set_uri_window(This->uri, window);
1148 if(!window) {
1149 ERR("window = NULL\n");
1150 return NS_ERROR_UNEXPECTED;
1153 if(This->uri->is_doc_uri && window == window->doc_obj->basedoc.window) {
1154 if(This->uri->channel_bsc) {
1155 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1157 if(window->doc_obj->mime) {
1158 heap_free(This->content_type);
1159 This->content_type = heap_strdupWtoA(window->doc_obj->mime);
1162 cancel = TRUE;
1163 }else {
1164 nsres = before_async_open(This, window->doc_obj->nscontainer, &cancel);
1165 if(NS_SUCCEEDED(nsres) && cancel) {
1166 TRACE("canceled\n");
1167 nsres = NS_BINDING_ABORTED;
1172 if(!cancel)
1173 nsres = async_open(This, window, This->uri->is_doc_uri, aListener, aContext);
1175 if(NS_SUCCEEDED(nsres) && This->load_group) {
1176 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1177 aContext);
1178 if(NS_FAILED(nsres))
1179 ERR("AddRequest failed: %08x\n", nsres);
1182 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
1183 return nsres;
1186 static nsresult NSAPI nsChannel_AsyncOpen2(nsIHttpChannel *iface, nsIStreamListener *aListener)
1188 nsChannel *This = impl_from_nsIHttpChannel(iface);
1189 FIXME("(%p)->(%p)\n", This, aListener);
1190 return nsIHttpChannel_AsyncOpen(&This->nsIHttpChannel_iface, aListener, NULL);
1193 static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition)
1195 nsChannel *This = impl_from_nsIHttpChannel(iface);
1196 FIXME("(%p)->(%p)\n", This, aContentDisposition);
1197 return NS_ERROR_NOT_IMPLEMENTED;
1200 static nsresult NSAPI nsChannel_SetContentDisposition(nsIHttpChannel *iface, UINT32 aContentDisposition)
1202 nsChannel *This = impl_from_nsIHttpChannel(iface);
1203 FIXME("(%p)->(%u)\n", This, aContentDisposition);
1204 return NS_ERROR_NOT_IMPLEMENTED;
1207 static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
1209 nsChannel *This = impl_from_nsIHttpChannel(iface);
1210 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1211 return NS_ERROR_NOT_IMPLEMENTED;
1214 static nsresult NSAPI nsChannel_SetContentDispositionFilename(nsIHttpChannel *iface, const nsAString *aContentDispositionFilename)
1216 nsChannel *This = impl_from_nsIHttpChannel(iface);
1217 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1218 return NS_ERROR_NOT_IMPLEMENTED;
1221 static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
1223 nsChannel *This = impl_from_nsIHttpChannel(iface);
1224 FIXME("(%p)->(%p)\n", This, aContentDispositionHeader);
1225 return NS_ERROR_NOT_IMPLEMENTED;
1228 static nsresult NSAPI nsChannel_GetLoadInfo(nsIHttpChannel *iface, nsILoadInfo **aLoadInfo)
1230 nsChannel *This = impl_from_nsIHttpChannel(iface);
1232 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1234 if(This->load_info)
1235 nsISupports_AddRef(This->load_info);
1236 *aLoadInfo = This->load_info;
1237 return NS_OK;
1240 static nsresult NSAPI nsChannel_SetLoadInfo(nsIHttpChannel *iface, nsILoadInfo *aLoadInfo)
1242 nsChannel *This = impl_from_nsIHttpChannel(iface);
1244 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1246 if(This->load_info)
1247 nsISupports_Release(This->load_info);
1248 This->load_info = aLoadInfo;
1249 if(This->load_info)
1250 nsISupports_AddRef(This->load_info);
1251 return NS_OK;
1254 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1256 nsChannel *This = impl_from_nsIHttpChannel(iface);
1258 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1260 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1261 return NS_OK;
1264 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1265 const nsACString *aRequestMethod)
1267 nsChannel *This = impl_from_nsIHttpChannel(iface);
1268 const char *method;
1269 unsigned i;
1271 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1273 nsACString_GetData(aRequestMethod, &method);
1274 for(i=0; i < sizeof(request_method_strings)/sizeof(*request_method_strings); i++) {
1275 if(!strcasecmp(method, request_method_strings[i])) {
1276 This->request_method = i;
1277 return NS_OK;
1281 ERR("Invalid method %s\n", debugstr_a(method));
1282 return NS_ERROR_UNEXPECTED;
1285 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1287 nsChannel *This = impl_from_nsIHttpChannel(iface);
1289 TRACE("(%p)->(%p)\n", This, aReferrer);
1291 if(This->referrer)
1292 nsIURI_AddRef(This->referrer);
1293 *aReferrer = This->referrer;
1294 return NS_OK;
1297 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1299 nsChannel *This = impl_from_nsIHttpChannel(iface);
1301 TRACE("(%p)->(%p)\n", This, aReferrer);
1303 return nsIHttpChannel_SetReferrerWithPolicy(&This->nsIHttpChannel_iface, aReferrer, 0);
1306 static nsresult NSAPI nsChannel_GetReferrerPolicy(nsIHttpChannel *iface, UINT32 *aReferrerPolicy)
1308 nsChannel *This = impl_from_nsIHttpChannel(iface);
1309 FIXME("(%p)->(%p)\n", This, aReferrerPolicy);
1310 return NS_ERROR_NOT_IMPLEMENTED;
1313 static nsresult NSAPI nsChannel_SetReferrerWithPolicy(nsIHttpChannel *iface, nsIURI *aReferrer, UINT32 aReferrerPolicy)
1315 nsChannel *This = impl_from_nsIHttpChannel(iface);
1316 DWORD channel_scheme, referrer_scheme;
1317 nsWineURI *referrer;
1318 BSTR referrer_uri;
1319 nsresult nsres;
1320 HRESULT hres;
1322 static const WCHAR refererW[] = {'R','e','f','e','r','e','r'};
1324 TRACE("(%p)->(%p %d)\n", This, aReferrer, aReferrerPolicy);
1326 if(aReferrerPolicy)
1327 FIXME("refferer policy %d not implemented\n", aReferrerPolicy);
1329 if(This->referrer) {
1330 nsIURI_Release(This->referrer);
1331 This->referrer = NULL;
1333 if(!aReferrer)
1334 return NS_OK;
1336 nsres = nsIURI_QueryInterface(aReferrer, &IID_nsWineURI, (void**)&referrer);
1337 if(NS_FAILED(nsres))
1338 return NS_OK;
1340 if(!ensure_uri(referrer)) {
1341 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1342 return NS_ERROR_UNEXPECTED;
1345 if(!ensure_uri(This->uri) || FAILED(IUri_GetScheme(This->uri->uri, &channel_scheme)))
1346 channel_scheme = INTERNET_SCHEME_UNKNOWN;
1348 if(FAILED(IUri_GetScheme(referrer->uri, &referrer_scheme)))
1349 referrer_scheme = INTERNET_SCHEME_UNKNOWN;
1351 if(referrer_scheme == INTERNET_SCHEME_HTTPS && channel_scheme != INTERNET_SCHEME_HTTPS) {
1352 TRACE("Ignoring https referrer on non-https channel\n");
1353 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1354 return NS_OK;
1357 hres = IUri_GetDisplayUri(referrer->uri, &referrer_uri);
1358 if(SUCCEEDED(hres)) {
1359 set_http_header(&This->request_headers, refererW, sizeof(refererW)/sizeof(WCHAR), referrer_uri, SysStringLen(referrer_uri));
1360 SysFreeString(referrer_uri);
1363 This->referrer = (nsIURI*)&referrer->nsIFileURL_iface;
1364 return NS_OK;
1367 static nsresult NSAPI nsHttpChannel_GetProtocolVersion(nsIHttpChannel *iface, nsACString *aProtocolVersion)
1369 nsChannel *This = impl_from_nsIHttpChannel(iface);
1370 FIXME("(%p)->(%p)\n", This, aProtocolVersion);
1371 return NS_ERROR_NOT_IMPLEMENTED;
1374 static nsresult NSAPI nsHttpChannel_GetTransferSize(nsIHttpChannel *iface, UINT64 *aTransferSize)
1376 nsChannel *This = impl_from_nsIHttpChannel(iface);
1377 FIXME("(%p)->(%p)\n", This, aTransferSize);
1378 return NS_ERROR_NOT_IMPLEMENTED;
1381 static nsresult NSAPI nsHttpChannel_GetDecodedBodySize(nsIHttpChannel *iface, UINT64 *aDecodedBodySize)
1383 nsChannel *This = impl_from_nsIHttpChannel(iface);
1384 FIXME("(%p)->(%p)\n", This, aDecodedBodySize);
1385 return NS_ERROR_NOT_IMPLEMENTED;
1388 static nsresult NSAPI nsHttpChannel_GetEncodedBodySize(nsIHttpChannel *iface, UINT64 *aEncodedBodySize)
1390 nsChannel *This = impl_from_nsIHttpChannel(iface);
1391 FIXME("(%p)->(%p)\n", This, aEncodedBodySize);
1392 return NS_ERROR_NOT_IMPLEMENTED;
1395 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1396 const nsACString *aHeader, nsACString *_retval)
1398 nsChannel *This = impl_from_nsIHttpChannel(iface);
1400 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1402 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1405 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1406 const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
1408 nsChannel *This = impl_from_nsIHttpChannel(iface);
1410 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1412 if(aMerge)
1413 FIXME("aMerge not supported\n");
1415 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1418 static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader)
1420 nsChannel *This = impl_from_nsIHttpChannel(iface);
1421 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader));
1422 return NS_ERROR_NOT_IMPLEMENTED;
1425 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1426 nsIHttpHeaderVisitor *aVisitor)
1428 nsChannel *This = impl_from_nsIHttpChannel(iface);
1430 FIXME("(%p)->(%p)\n", This, aVisitor);
1432 return NS_ERROR_NOT_IMPLEMENTED;
1435 static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor)
1437 nsChannel *This = impl_from_nsIHttpChannel(iface);
1438 FIXME("(%p)->(%p)\n", This, aVisitor);
1439 return NS_ERROR_NOT_IMPLEMENTED;
1442 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
1444 nsChannel *This = impl_from_nsIHttpChannel(iface);
1446 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1448 return NS_ERROR_NOT_IMPLEMENTED;
1451 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
1453 nsChannel *This = impl_from_nsIHttpChannel(iface);
1455 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1457 return NS_ERROR_NOT_IMPLEMENTED;
1460 static nsresult NSAPI nsChannel_GetAllowTLS(nsIHttpChannel *iface, cpp_bool *aAllowTLS)
1462 nsChannel *This = impl_from_nsIHttpChannel(iface);
1463 FIXME("(%p)->(%p)\n", This, aAllowTLS);
1464 return NS_ERROR_NOT_IMPLEMENTED;
1467 static nsresult NSAPI nsChannel_SetAllowTLS(nsIHttpChannel *iface, cpp_bool aAllowTLS)
1469 nsChannel *This = impl_from_nsIHttpChannel(iface);
1470 FIXME("(%p)->(%x)\n", This, aAllowTLS);
1471 return NS_ERROR_NOT_IMPLEMENTED;
1474 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
1476 nsChannel *This = impl_from_nsIHttpChannel(iface);
1478 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1480 return NS_ERROR_NOT_IMPLEMENTED;
1483 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
1485 nsChannel *This = impl_from_nsIHttpChannel(iface);
1487 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1489 return NS_ERROR_NOT_IMPLEMENTED;
1492 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
1494 nsChannel *This = impl_from_nsIHttpChannel(iface);
1496 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1498 if(This->response_status) {
1499 *aResponseStatus = This->response_status;
1500 return NS_OK;
1503 WARN("No response status\n");
1504 return NS_ERROR_UNEXPECTED;
1507 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1508 nsACString *aResponseStatusText)
1510 nsChannel *This = impl_from_nsIHttpChannel(iface);
1512 TRACE("(%p)->(%p)\n", This, aResponseStatusText);
1514 nsACString_SetData(aResponseStatusText, This->response_status_text);
1515 return NS_OK;
1518 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1519 cpp_bool *aRequestSucceeded)
1521 nsChannel *This = impl_from_nsIHttpChannel(iface);
1523 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1525 if(!This->response_status)
1526 return NS_ERROR_NOT_AVAILABLE;
1528 *aRequestSucceeded = This->response_status/100 == 2;
1530 return NS_OK;
1533 static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel)
1535 nsChannel *This = impl_from_nsIHttpChannel(iface);
1536 FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel);
1537 return NS_ERROR_NOT_IMPLEMENTED;
1540 static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel)
1542 nsChannel *This = impl_from_nsIHttpChannel(iface);
1543 FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel);
1544 return NS_ERROR_NOT_IMPLEMENTED;
1547 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1548 const nsACString *header, nsACString *_retval)
1550 nsChannel *This = impl_from_nsIHttpChannel(iface);
1552 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1554 return get_channel_http_header(&This->response_headers, header, _retval);
1557 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1558 const nsACString *header, const nsACString *value, cpp_bool merge)
1560 nsChannel *This = impl_from_nsIHttpChannel(iface);
1562 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1564 return NS_ERROR_NOT_IMPLEMENTED;
1567 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1568 nsIHttpHeaderVisitor *aVisitor)
1570 nsChannel *This = impl_from_nsIHttpChannel(iface);
1572 TRACE("(%p)->(%p)\n", This, aVisitor);
1574 return visit_http_headers(&This->response_headers, aVisitor);
1577 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1579 nsChannel *This = impl_from_nsIHttpChannel(iface);
1580 http_header_t *header;
1582 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1583 static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};
1585 TRACE("(%p)->(%p)\n", This, _retval);
1587 header = find_http_header(&This->response_headers, cache_controlW, sizeof(cache_controlW)/sizeof(WCHAR));
1588 *_retval = header && !strcmpiW(header->data, no_storeW);
1589 return NS_OK;
1592 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1594 nsChannel *This = impl_from_nsIHttpChannel(iface);
1596 FIXME("(%p)->(%p)\n", This, _retval);
1598 return NS_ERROR_NOT_IMPLEMENTED;
1601 static nsresult NSAPI nsChannel_IsPrivateResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1603 nsChannel *This = impl_from_nsIHttpChannel(iface);
1605 FIXME("(%p)->(%p)\n", This, _retval);
1607 return NS_ERROR_NOT_IMPLEMENTED;
1610 static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aTargetURI)
1612 nsChannel *This = impl_from_nsIHttpChannel(iface);
1614 FIXME("(%p)->(%p)\n", This, aTargetURI);
1616 return NS_ERROR_NOT_IMPLEMENTED;
1619 static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID)
1621 nsChannel *This = impl_from_nsIHttpChannel(iface);
1623 FIXME("(%p)->(%p)\n", This, aSchedulingContextID);
1625 return NS_ERROR_NOT_IMPLEMENTED;
1628 static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID)
1630 nsChannel *This = impl_from_nsIHttpChannel(iface);
1632 FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID));
1634 return NS_ERROR_NOT_IMPLEMENTED;
1637 static const nsIHttpChannelVtbl nsChannelVtbl = {
1638 nsChannel_QueryInterface,
1639 nsChannel_AddRef,
1640 nsChannel_Release,
1641 nsChannel_GetName,
1642 nsChannel_IsPending,
1643 nsChannel_GetStatus,
1644 nsChannel_Cancel,
1645 nsChannel_Suspend,
1646 nsChannel_Resume,
1647 nsChannel_GetLoadGroup,
1648 nsChannel_SetLoadGroup,
1649 nsChannel_GetLoadFlags,
1650 nsChannel_SetLoadFlags,
1651 nsChannel_GetOriginalURI,
1652 nsChannel_SetOriginalURI,
1653 nsChannel_GetURI,
1654 nsChannel_GetOwner,
1655 nsChannel_SetOwner,
1656 nsChannel_GetNotificationCallbacks,
1657 nsChannel_SetNotificationCallbacks,
1658 nsChannel_GetSecurityInfo,
1659 nsChannel_GetContentType,
1660 nsChannel_SetContentType,
1661 nsChannel_GetContentCharset,
1662 nsChannel_SetContentCharset,
1663 nsChannel_GetContentLength,
1664 nsChannel_SetContentLength,
1665 nsChannel_Open,
1666 nsChannel_Open2,
1667 nsChannel_AsyncOpen,
1668 nsChannel_AsyncOpen2,
1669 nsChannel_GetContentDisposition,
1670 nsChannel_SetContentDisposition,
1671 nsChannel_GetContentDispositionFilename,
1672 nsChannel_SetContentDispositionFilename,
1673 nsChannel_GetContentDispositionHeader,
1674 nsChannel_GetLoadInfo,
1675 nsChannel_SetLoadInfo,
1676 nsChannel_GetRequestMethod,
1677 nsChannel_SetRequestMethod,
1678 nsChannel_GetReferrer,
1679 nsChannel_SetReferrer,
1680 nsChannel_GetReferrerPolicy,
1681 nsChannel_SetReferrerWithPolicy,
1682 nsHttpChannel_GetProtocolVersion,
1683 nsHttpChannel_GetTransferSize,
1684 nsHttpChannel_GetDecodedBodySize,
1685 nsHttpChannel_GetEncodedBodySize,
1686 nsChannel_GetRequestHeader,
1687 nsChannel_SetRequestHeader,
1688 nsChannel_SetEmptyRequestHeader,
1689 nsChannel_VisitRequestHeaders,
1690 nsChannel_VisitNonDefaultRequestHeaders,
1691 nsChannel_GetAllowPipelining,
1692 nsChannel_SetAllowPipelining,
1693 nsChannel_GetAllowTLS,
1694 nsChannel_SetAllowTLS,
1695 nsChannel_GetRedirectionLimit,
1696 nsChannel_SetRedirectionLimit,
1697 nsChannel_GetResponseStatus,
1698 nsChannel_GetResponseStatusText,
1699 nsChannel_GetRequestSucceeded,
1700 nsChannel_GetIsMainDocumentChannel,
1701 nsChannel_SetIsMainDocumentChannel,
1702 nsChannel_GetResponseHeader,
1703 nsChannel_SetResponseHeader,
1704 nsChannel_VisitResponseHeaders,
1705 nsChannel_IsNoStoreResponse,
1706 nsChannel_IsNoCacheResponse,
1707 nsChannel_IsPrivateResponse,
1708 nsChannel_RedirectTo,
1709 nsHttpChannel_GetSchedulingContextID,
1710 nsHttpChannel_SetSchedulingContextID
1713 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1715 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1718 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1719 void **result)
1721 nsChannel *This = impl_from_nsIUploadChannel(iface);
1722 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1725 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1727 nsChannel *This = impl_from_nsIUploadChannel(iface);
1728 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1731 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1733 nsChannel *This = impl_from_nsIUploadChannel(iface);
1734 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1737 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1738 nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
1740 nsChannel *This = impl_from_nsIUploadChannel(iface);
1741 const char *content_type;
1743 static const WCHAR content_typeW[] =
1744 {'C','o','n','t','e','n','t','-','T','y','p','e'};
1746 TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));
1748 This->post_data_contains_headers = TRUE;
1750 if(aContentType) {
1751 nsACString_GetData(aContentType, &content_type);
1752 if(*content_type) {
1753 WCHAR *ct;
1755 ct = heap_strdupAtoW(content_type);
1756 if(!ct)
1757 return NS_ERROR_UNEXPECTED;
1759 set_http_header(&This->request_headers, content_typeW,
1760 sizeof(content_typeW)/sizeof(WCHAR), ct, strlenW(ct));
1761 heap_free(ct);
1762 This->post_data_contains_headers = FALSE;
1766 if(aContentLength != -1)
1767 FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));
1769 if(This->post_data_stream)
1770 nsIInputStream_Release(This->post_data_stream);
1771 This->post_data_stream = aStream;
1772 if(aStream)
1773 nsIInputStream_AddRef(aStream);
1775 This->request_method = METHOD_POST;
1776 return NS_OK;
1779 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1780 nsIInputStream **aUploadStream)
1782 nsChannel *This = impl_from_nsIUploadChannel(iface);
1784 TRACE("(%p)->(%p)\n", This, aUploadStream);
1786 if(This->post_data_stream)
1787 nsIInputStream_AddRef(This->post_data_stream);
1789 *aUploadStream = This->post_data_stream;
1790 return NS_OK;
1793 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1794 nsUploadChannel_QueryInterface,
1795 nsUploadChannel_AddRef,
1796 nsUploadChannel_Release,
1797 nsUploadChannel_SetUploadStream,
1798 nsUploadChannel_GetUploadStream
1801 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1803 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1806 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1807 void **result)
1809 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1810 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1813 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1815 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1816 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1819 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1821 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1822 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1825 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1827 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1829 FIXME("(%p)->()\n", This);
1831 return NS_ERROR_NOT_IMPLEMENTED;
1834 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1836 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1838 FIXME("(%p)->()\n", This);
1840 return NS_ERROR_NOT_IMPLEMENTED;
1843 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1845 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1847 FIXME("(%p)->()\n", This);
1849 return NS_ERROR_NOT_IMPLEMENTED;
1852 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1854 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1856 FIXME("(%p)->()\n", This);
1858 return NS_ERROR_NOT_IMPLEMENTED;
1861 static nsresult NSAPI nsHttpChannelInternal_TakeAllSecurityMessages(nsIHttpChannelInternal *iface, void *aMessages)
1863 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1865 FIXME("(%p)->()\n", This);
1867 return NS_ERROR_NOT_IMPLEMENTED;
1870 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1872 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1874 FIXME("(%p)->()\n", This);
1876 return NS_ERROR_NOT_IMPLEMENTED;
1879 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1881 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1883 FIXME("(%p)->()\n", This);
1885 return NS_ERROR_NOT_IMPLEMENTED;
1888 static nsresult NSAPI nsHttpChannelInternal_GetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 *aThirdPartyFlags)
1890 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1891 FIXME("(%p)->(%p)\n", This, aThirdPartyFlags);
1892 return NS_ERROR_NOT_IMPLEMENTED;
1895 static nsresult NSAPI nsHttpChannelInternal_SetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 aThirdPartyFlags)
1897 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1898 FIXME("(%p)->(%x)\n", This, aThirdPartyFlags);
1899 return NS_ERROR_NOT_IMPLEMENTED;
1902 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
1904 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1906 FIXME("(%p)->()\n", This);
1908 return NS_ERROR_NOT_IMPLEMENTED;
1911 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
1913 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1915 FIXME("(%p)->()\n", This);
1917 return NS_ERROR_NOT_IMPLEMENTED;
1920 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1922 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1924 FIXME("(%p)->(%p)\n", This, aCanceled);
1926 return NS_ERROR_NOT_IMPLEMENTED;
1929 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1931 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1933 FIXME("(%p)->(%p)\n", This, aCanceled);
1935 return NS_ERROR_NOT_IMPLEMENTED;
1938 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
1940 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1942 FIXME("(%p)->(%x)\n", This, aCanceled);
1944 return NS_ERROR_NOT_IMPLEMENTED;
1947 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1949 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1951 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1953 return NS_ERROR_NOT_IMPLEMENTED;
1956 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
1958 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1960 FIXME("(%p)->(%p)\n", This, aLocalPort);
1962 return NS_ERROR_NOT_IMPLEMENTED;
1965 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1967 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1969 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1971 return NS_ERROR_NOT_IMPLEMENTED;
1974 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
1976 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1978 FIXME("(%p)->(%p)\n", This, aRemotePort);
1980 return NS_ERROR_NOT_IMPLEMENTED;
1983 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1985 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1987 FIXME("(%p)->(%p)\n", This, cacheKeys);
1989 return NS_ERROR_NOT_IMPLEMENTED;
1992 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1993 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1995 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1996 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1997 return NS_ERROR_NOT_IMPLEMENTED;
2000 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
2002 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2003 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
2004 return NS_ERROR_NOT_IMPLEMENTED;
2007 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
2009 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2010 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
2011 return NS_ERROR_NOT_IMPLEMENTED;
2014 static nsresult NSAPI nsHttpChannelInternal_GetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
2015 cpp_bool *aResponseTimeoutEnabled)
2017 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2018 FIXME("(%p)->(%p)\n", This, aResponseTimeoutEnabled);
2019 return NS_ERROR_NOT_IMPLEMENTED;
2022 static nsresult NSAPI nsHttpChannelInternal_SetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
2023 cpp_bool aResponseTimeoutEnabled)
2025 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2026 FIXME("(%p)->(%x)\n", This, aResponseTimeoutEnabled);
2027 return NS_ERROR_NOT_IMPLEMENTED;
2030 static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface,
2031 UINT32 *aInitialRwin)
2033 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2034 FIXME("(%p)->(%p)\n", This, aInitialRwin);
2035 return NS_ERROR_NOT_IMPLEMENTED;
2038 static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface,
2039 UINT32 aInitialRwin)
2041 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2042 FIXME("(%p)->(%x)\n", This, aInitialRwin);
2043 return NS_ERROR_NOT_IMPLEMENTED;
2046 static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI)
2048 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2049 FIXME("(%p)->(%p)\n", This, aApiRedirectToURI);
2050 return NS_ERROR_NOT_IMPLEMENTED;
2053 static nsresult NSAPI nsHttpChannelInternal_GetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool *aAllowAltSvc)
2055 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2056 FIXME("(%p)->(%p)\n", This, aAllowAltSvc);
2057 return NS_ERROR_NOT_IMPLEMENTED;
2060 static nsresult NSAPI nsHttpChannelInternal_SetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool aAllowAltSvc)
2062 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2063 FIXME("(%p)->(%x)\n", This, aAllowAltSvc);
2064 return NS_ERROR_NOT_IMPLEMENTED;
2067 static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime)
2069 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2070 FIXME("(%p)->(%p)\n", This, aLastModifiedTime);
2071 return NS_ERROR_NOT_IMPLEMENTED;
2074 static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID)
2076 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2077 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID));
2078 return NS_ERROR_NOT_IMPLEMENTED;
2081 static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized)
2083 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2084 FIXME("(%p, %p)\n", This, ResponseSynthesized);
2085 return NS_ERROR_NOT_IMPLEMENTED;
2088 static nsresult NSAPI nsHttpChannelInternal_GetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2089 cpp_bool *aCorsIncludeCredentials)
2091 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2092 FIXME("(%p)->(%p)\n", This, aCorsIncludeCredentials);
2093 return NS_ERROR_NOT_IMPLEMENTED;
2096 static nsresult NSAPI nsHttpChannelInternal_SetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2097 cpp_bool aCorsIncludeCredentials)
2099 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2100 TRACE("(%p)->(%x)\n", This, aCorsIncludeCredentials);
2101 return NS_OK;
2104 static nsresult NSAPI nsHttpChannelInternal_GetCorsMode(nsIHttpChannelInternal *iface, UINT32 *aCorsMode)
2106 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2107 FIXME("(%p)->(%p)\n", This, aCorsMode);
2108 return NS_ERROR_NOT_IMPLEMENTED;
2111 static nsresult NSAPI nsHttpChannelInternal_SetCorsMode(nsIHttpChannelInternal *iface, UINT32 aCorsMode)
2113 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2114 TRACE("(%p)->(%d)\n", This, aCorsMode);
2115 return NS_OK;
2118 static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode)
2120 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2121 FIXME("(%p)->(%p)\n", This, aRedirectMode);
2122 return NS_ERROR_NOT_IMPLEMENTED;
2125 static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode)
2127 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2128 FIXME("(%p)->(%d)\n", This, aRedirectMode);
2129 return NS_ERROR_NOT_IMPLEMENTED;
2132 static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI)
2134 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2135 FIXME("(%p)->(%p)\n", This, aTopWindowURI);
2136 return NS_ERROR_NOT_IMPLEMENTED;
2139 static nsresult NSAPI nsHttpChannelInternal_GetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2140 nsACString *aNetworkInterfaceId)
2142 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2143 FIXME("(%p)->(%p)\n", This, aNetworkInterfaceId);
2144 return NS_ERROR_NOT_IMPLEMENTED;
2147 static nsresult NSAPI nsHttpChannelInternal_SetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2148 const nsACString *aNetworkInterfaceId)
2150 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2151 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aNetworkInterfaceId));
2152 return NS_ERROR_NOT_IMPLEMENTED;
2155 static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI)
2157 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2158 FIXME("(%p)->(%p)\n", This, aProxyURI);
2159 return NS_ERROR_NOT_IMPLEMENTED;
2162 static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface,
2163 const void /*nsTArray<nsCString>*/ *unsafeHeaders)
2165 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2166 FIXME("(%p)->(%p)\n", This, unsafeHeaders);
2167 return NS_ERROR_NOT_IMPLEMENTED;
2170 static nsresult NSAPI nsHttpChannelInternal_GetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool *aBlockAuthPrompt)
2172 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2173 FIXME("(%p)->(%p)\n", This, aBlockAuthPrompt);
2174 return NS_ERROR_NOT_IMPLEMENTED;
2177 static nsresult NSAPI nsHttpChannelInternal_SetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool aBlockAuthPrompt)
2179 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2180 FIXME("(%p)->(%x)\n", This, aBlockAuthPrompt);
2181 return NS_ERROR_NOT_IMPLEMENTED;
2184 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
2185 nsHttpChannelInternal_QueryInterface,
2186 nsHttpChannelInternal_AddRef,
2187 nsHttpChannelInternal_Release,
2188 nsHttpChannelInternal_GetDocumentURI,
2189 nsHttpChannelInternal_SetDocumentURI,
2190 nsHttpChannelInternal_GetRequestVersion,
2191 nsHttpChannelInternal_GetResponseVersion,
2192 nsHttpChannelInternal_TakeAllSecurityMessages,
2193 nsHttpChannelInternal_SetCookie,
2194 nsHttpChannelInternal_SetupFallbackChannel,
2195 nsHttpChannelInternal_GetThirdPartyFlags,
2196 nsHttpChannelInternal_SetThirdPartyFlags,
2197 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
2198 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
2199 nsHttpChannelInternal_GetCanceled,
2200 nsHttpChannelInternal_GetChannelIsForDownload,
2201 nsHttpChannelInternal_SetChannelIsForDownload,
2202 nsHttpChannelInternal_GetLocalAddress,
2203 nsHttpChannelInternal_GetLocalPort,
2204 nsHttpChannelInternal_GetRemoteAddress,
2205 nsHttpChannelInternal_GetRemotePort,
2206 nsHttpChannelInternal_SetCacheKeysRedirectChain,
2207 nsHttpChannelInternal_HTTPUpgrade,
2208 nsHttpChannelInternal_GetAllowSpdy,
2209 nsHttpChannelInternal_SetAllowSpdy,
2210 nsHttpChannelInternal_GetResponseTimeoutEnabled,
2211 nsHttpChannelInternal_SetResponseTimeoutEnabled,
2212 nsHttpChannelInternal_GetInitialRwin,
2213 nsHttpChannelInternal_SetInitialRwin,
2214 nsHttpChannelInternal_GetApiRedirectToURI,
2215 nsHttpChannelInternal_GetAllowAltSvc,
2216 nsHttpChannelInternal_SetAllowAltSvc,
2217 nsHttpChannelInternal_GetLastModifiedTime,
2218 nsHttpChannelInternal_ForceIntercepted,
2219 nsHttpChannelInternal_GetResponseSynthesized,
2220 nsHttpChannelInternal_GetCorsIncludeCredentials,
2221 nsHttpChannelInternal_SetCorsIncludeCredentials,
2222 nsHttpChannelInternal_GetCorsMode,
2223 nsHttpChannelInternal_SetCorsMode,
2224 nsHttpChannelInternal_GetRedirectMode,
2225 nsHttpChannelInternal_SetRedirectMode,
2226 nsHttpChannelInternal_GetTopWindowURI,
2227 nsHttpChannelInternal_GetNetworkInterfaceId,
2228 nsHttpChannelInternal_SetNetworkInterfaceId,
2229 nsHttpChannelInternal_GetProxyURI,
2230 nsHttpChannelInternal_SetCorsPreflightParameters,
2231 nsHttpChannelInternal_GetBlockAuthPrompt,
2232 nsHttpChannelInternal_SetBlockAuthPrompt
2236 static void invalidate_uri(nsWineURI *This)
2238 if(This->uri) {
2239 IUri_Release(This->uri);
2240 This->uri = NULL;
2244 static BOOL ensure_uri_builder(nsWineURI *This)
2246 if(!This->is_mutable) {
2247 WARN("Not mutable URI\n");
2248 return FALSE;
2251 if(!This->uri_builder) {
2252 HRESULT hres;
2254 if(!ensure_uri(This))
2255 return FALSE;
2257 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
2258 if(FAILED(hres)) {
2259 WARN("CreateIUriBuilder failed: %08x\n", hres);
2260 return FALSE;
2264 invalidate_uri(This);
2265 return TRUE;
2268 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
2270 char *vala;
2271 BSTR val;
2272 HRESULT hres;
2274 if(!ensure_uri(This))
2275 return NS_ERROR_UNEXPECTED;
2277 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
2278 if(FAILED(hres)) {
2279 WARN("GetPropertyBSTR failed: %08x\n", hres);
2280 return NS_ERROR_UNEXPECTED;
2283 vala = heap_strdupWtoU(val);
2284 SysFreeString(val);
2285 if(!vala)
2286 return NS_ERROR_OUT_OF_MEMORY;
2288 TRACE("ret %s\n", debugstr_a(vala));
2289 nsACString_SetData(ret, vala);
2290 heap_free(vala);
2291 return NS_OK;
2294 static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
2296 return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
2299 static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
2301 nsWineURI *This = impl_from_nsIFileURL(iface);
2303 *result = NULL;
2305 if(IsEqualGUID(&IID_nsISupports, riid)) {
2306 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2307 *result = &This->nsIFileURL_iface;
2308 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
2309 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
2310 *result = &This->nsIFileURL_iface;
2311 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
2312 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
2313 *result = &This->nsIFileURL_iface;
2314 }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
2315 TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
2316 *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
2317 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
2318 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
2319 *result = &This->nsIStandardURL_iface;
2320 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
2321 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
2322 *result = &This->nsIStandardURL_iface;
2323 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
2324 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
2325 *result = This;
2328 if(*result) {
2329 nsIFileURL_AddRef(&This->nsIFileURL_iface);
2330 return NS_OK;
2333 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
2334 return NS_NOINTERFACE;
2337 static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
2339 nsWineURI *This = impl_from_nsIFileURL(iface);
2340 LONG ref = InterlockedIncrement(&This->ref);
2342 TRACE("(%p) ref=%d\n", This, ref);
2344 return ref;
2347 static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
2349 nsWineURI *This = impl_from_nsIFileURL(iface);
2350 LONG ref = InterlockedDecrement(&This->ref);
2352 TRACE("(%p) ref=%d\n", This, ref);
2354 if(!ref) {
2355 if(This->window_ref)
2356 windowref_release(This->window_ref);
2357 if(This->container)
2358 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
2359 if(This->uri)
2360 IUri_Release(This->uri);
2361 if(This->uri_builder)
2362 IUriBuilder_Release(This->uri_builder);
2363 heap_free(This->origin_charset);
2364 heap_free(This);
2367 return ref;
2370 static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
2372 nsWineURI *This = impl_from_nsIFileURL(iface);
2374 TRACE("(%p)->(%p)\n", This, aSpec);
2376 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
2379 static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
2381 nsWineURI *This = impl_from_nsIFileURL(iface);
2382 const char *speca;
2383 WCHAR *spec;
2384 IUri *uri;
2385 HRESULT hres;
2387 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
2389 if(!This->is_mutable)
2390 return NS_ERROR_UNEXPECTED;
2392 nsACString_GetData(aSpec, &speca);
2393 spec = heap_strdupUtoW(speca);
2394 if(!spec)
2395 return NS_ERROR_OUT_OF_MEMORY;
2397 hres = create_uri(spec, 0, &uri);
2398 heap_free(spec);
2399 if(FAILED(hres)) {
2400 WARN("create_uri failed: %08x\n", hres);
2401 return NS_ERROR_FAILURE;
2404 invalidate_uri(This);
2405 if(This->uri_builder) {
2406 IUriBuilder_Release(This->uri_builder);
2407 This->uri_builder = NULL;
2410 This->uri = uri;
2411 return NS_OK;
2414 static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
2416 nsWineURI *This = impl_from_nsIFileURL(iface);
2417 IUriBuilder *uri_builder;
2418 BSTR display_uri;
2419 IUri *uri;
2420 int len;
2421 nsresult nsres;
2422 HRESULT hres;
2424 TRACE("(%p)->(%p)\n", This, aPrePath);
2426 if(!ensure_uri(This))
2427 return NS_ERROR_UNEXPECTED;
2429 hres = CreateIUriBuilder(This->uri, 0, 0, &uri_builder);
2430 if(FAILED(hres))
2431 return NS_ERROR_FAILURE;
2433 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_PATH|Uri_HAS_QUERY|Uri_HAS_FRAGMENT);
2434 if(SUCCEEDED(hres))
2435 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &uri);
2436 IUriBuilder_Release(uri_builder);
2437 if(FAILED(hres))
2438 return NS_ERROR_FAILURE;
2440 hres = IUri_GetDisplayUri(uri, &display_uri);
2441 IUri_Release(uri);
2442 if(FAILED(hres))
2443 return NS_ERROR_FAILURE;
2445 /* Remove trailing slash that may be appended as default path. */
2446 len = SysStringLen(display_uri);
2447 if(len && display_uri[len-1] == '/')
2448 display_uri[len-1] = 0;
2450 nsres = return_wstr_nsacstr(aPrePath, display_uri, -1);
2451 SysFreeString(display_uri);
2452 return nsres;
2455 static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
2457 nsWineURI *This = impl_from_nsIFileURL(iface);
2458 DWORD scheme;
2459 HRESULT hres;
2461 TRACE("(%p)->(%p)\n", This, aScheme);
2463 if(!ensure_uri(This))
2464 return NS_ERROR_UNEXPECTED;
2466 hres = IUri_GetScheme(This->uri, &scheme);
2467 if(FAILED(hres)) {
2468 WARN("GetScheme failed: %08x\n", hres);
2469 return NS_ERROR_UNEXPECTED;
2472 if(scheme == URL_SCHEME_ABOUT) {
2473 nsACString_SetData(aScheme, "wine");
2474 return NS_OK;
2477 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
2480 static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
2482 nsWineURI *This = impl_from_nsIFileURL(iface);
2483 const char *schemea;
2484 WCHAR *scheme;
2485 HRESULT hres;
2487 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
2489 if(!ensure_uri_builder(This))
2490 return NS_ERROR_UNEXPECTED;
2492 nsACString_GetData(aScheme, &schemea);
2493 scheme = heap_strdupUtoW(schemea);
2494 if(!scheme)
2495 return NS_ERROR_OUT_OF_MEMORY;
2497 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
2498 heap_free(scheme);
2499 if(FAILED(hres))
2500 return NS_ERROR_UNEXPECTED;
2502 return NS_OK;
2505 static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
2507 nsWineURI *This = impl_from_nsIFileURL(iface);
2508 BSTR user, pass;
2509 HRESULT hres;
2511 TRACE("(%p)->(%p)\n", This, aUserPass);
2513 if(!ensure_uri(This))
2514 return NS_ERROR_UNEXPECTED;
2516 hres = IUri_GetUserName(This->uri, &user);
2517 if(FAILED(hres))
2518 return NS_ERROR_FAILURE;
2520 hres = IUri_GetPassword(This->uri, &pass);
2521 if(FAILED(hres)) {
2522 SysFreeString(user);
2523 return NS_ERROR_FAILURE;
2526 if(*user || *pass) {
2527 FIXME("Construct user:pass string\n");
2528 }else {
2529 nsACString_SetData(aUserPass, "");
2532 SysFreeString(user);
2533 SysFreeString(pass);
2534 return NS_OK;
2537 static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
2539 nsWineURI *This = impl_from_nsIFileURL(iface);
2540 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
2541 const char *user_pass;
2542 HRESULT hres;
2544 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
2546 if(!ensure_uri_builder(This))
2547 return NS_ERROR_UNEXPECTED;
2549 nsACString_GetData(aUserPass, &user_pass);
2550 if(*user_pass) {
2551 WCHAR *ptr;
2553 buf = heap_strdupUtoW(user_pass);
2554 if(!buf)
2555 return NS_ERROR_OUT_OF_MEMORY;
2557 ptr = strchrW(buf, ':');
2558 if(!ptr) {
2559 user = buf;
2560 }else if(ptr != buf) {
2561 *ptr++ = 0;
2562 user = buf;
2563 if(*ptr)
2564 pass = ptr;
2565 }else {
2566 pass = buf+1;
2570 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2571 if(SUCCEEDED(hres))
2572 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2574 heap_free(buf);
2575 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2578 static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
2580 nsWineURI *This = impl_from_nsIFileURL(iface);
2582 TRACE("(%p)->(%p)\n", This, aUsername);
2584 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2587 static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
2589 nsWineURI *This = impl_from_nsIFileURL(iface);
2590 const char *usera;
2591 WCHAR *user;
2592 HRESULT hres;
2594 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2596 if(!ensure_uri_builder(This))
2597 return NS_ERROR_UNEXPECTED;
2599 nsACString_GetData(aUsername, &usera);
2600 user = heap_strdupUtoW(usera);
2601 if(!user)
2602 return NS_ERROR_OUT_OF_MEMORY;
2604 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2605 heap_free(user);
2606 if(FAILED(hres))
2607 return NS_ERROR_UNEXPECTED;
2609 return NS_OK;
2612 static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
2614 nsWineURI *This = impl_from_nsIFileURL(iface);
2616 TRACE("(%p)->(%p)\n", This, aPassword);
2618 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2621 static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
2623 nsWineURI *This = impl_from_nsIFileURL(iface);
2624 const char *passa;
2625 WCHAR *pass;
2626 HRESULT hres;
2628 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2630 if(!ensure_uri_builder(This))
2631 return NS_ERROR_UNEXPECTED;
2633 nsACString_GetData(aPassword, &passa);
2634 pass = heap_strdupUtoW(passa);
2635 if(!pass)
2636 return NS_ERROR_OUT_OF_MEMORY;
2638 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2639 heap_free(pass);
2640 if(FAILED(hres))
2641 return NS_ERROR_UNEXPECTED;
2643 return NS_OK;
2646 static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
2648 nsWineURI *This = impl_from_nsIFileURL(iface);
2649 const WCHAR *ptr;
2650 char *vala;
2651 BSTR val;
2652 HRESULT hres;
2654 TRACE("(%p)->(%p)\n", This, aHostPort);
2656 if(!ensure_uri(This))
2657 return NS_ERROR_UNEXPECTED;
2659 hres = IUri_GetAuthority(This->uri, &val);
2660 if(FAILED(hres)) {
2661 WARN("GetAuthority failed: %08x\n", hres);
2662 return NS_ERROR_UNEXPECTED;
2665 ptr = strchrW(val, '@');
2666 if(!ptr)
2667 ptr = val;
2669 vala = heap_strdupWtoU(ptr);
2670 SysFreeString(val);
2671 if(!vala)
2672 return NS_ERROR_OUT_OF_MEMORY;
2674 TRACE("ret %s\n", debugstr_a(vala));
2675 nsACString_SetData(aHostPort, vala);
2676 heap_free(vala);
2677 return NS_OK;
2680 static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
2682 nsWineURI *This = impl_from_nsIFileURL(iface);
2684 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2686 /* Not implemented by Gecko */
2687 return NS_ERROR_NOT_IMPLEMENTED;
2690 static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
2692 nsWineURI *This = impl_from_nsIFileURL(iface);
2694 TRACE("(%p)->(%p)\n", This, aHost);
2696 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2699 static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
2701 nsWineURI *This = impl_from_nsIFileURL(iface);
2702 const char *hosta;
2703 WCHAR *host;
2704 HRESULT hres;
2706 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2708 if(!ensure_uri_builder(This))
2709 return NS_ERROR_UNEXPECTED;
2711 nsACString_GetData(aHost, &hosta);
2712 host = heap_strdupUtoW(hosta);
2713 if(!host)
2714 return NS_ERROR_OUT_OF_MEMORY;
2716 hres = IUriBuilder_SetHost(This->uri_builder, host);
2717 heap_free(host);
2718 if(FAILED(hres))
2719 return NS_ERROR_UNEXPECTED;
2721 return NS_OK;
2724 static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
2726 nsWineURI *This = impl_from_nsIFileURL(iface);
2727 DWORD port;
2728 HRESULT hres;
2730 TRACE("(%p)->(%p)\n", This, aPort);
2732 if(!ensure_uri(This))
2733 return NS_ERROR_UNEXPECTED;
2735 hres = IUri_GetPort(This->uri, &port);
2736 if(FAILED(hres)) {
2737 WARN("GetPort failed: %08x\n", hres);
2738 return NS_ERROR_UNEXPECTED;
2741 *aPort = port ? port : -1;
2742 return NS_OK;
2745 static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
2747 nsWineURI *This = impl_from_nsIFileURL(iface);
2748 HRESULT hres;
2750 TRACE("(%p)->(%d)\n", This, aPort);
2752 if(!ensure_uri_builder(This))
2753 return NS_ERROR_UNEXPECTED;
2755 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2756 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2759 static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
2761 nsWineURI *This = impl_from_nsIFileURL(iface);
2763 TRACE("(%p)->(%p)\n", This, aPath);
2765 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2768 static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
2770 nsWineURI *This = impl_from_nsIFileURL(iface);
2771 const char *patha;
2772 WCHAR *path;
2773 HRESULT hres;
2775 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2777 if(!ensure_uri_builder(This))
2778 return NS_ERROR_UNEXPECTED;
2780 nsACString_GetData(aPath, &patha);
2781 path = heap_strdupUtoW(patha);
2782 if(!path)
2783 return NS_ERROR_OUT_OF_MEMORY;
2785 hres = IUriBuilder_SetPath(This->uri_builder, path);
2786 heap_free(path);
2787 if(FAILED(hres))
2788 return NS_ERROR_UNEXPECTED;
2790 return NS_OK;
2793 static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2795 nsWineURI *This = impl_from_nsIFileURL(iface);
2796 nsWineURI *other_obj;
2797 nsresult nsres;
2798 HRESULT hres;
2800 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2802 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2803 if(NS_FAILED(nsres)) {
2804 TRACE("Could not get nsWineURI interface\n");
2805 *_retval = FALSE;
2806 return NS_OK;
2809 if(ensure_uri(This) && ensure_uri(other_obj)) {
2810 BOOL b;
2812 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2813 if(SUCCEEDED(hres)) {
2814 *_retval = b;
2815 nsres = NS_OK;
2816 }else {
2817 nsres = NS_ERROR_FAILURE;
2819 }else {
2820 nsres = NS_ERROR_UNEXPECTED;
2823 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2824 return nsres;
2827 static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
2829 nsWineURI *This = impl_from_nsIFileURL(iface);
2830 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2831 BSTR scheme_name;
2832 HRESULT hres;
2834 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2836 if(!ensure_uri(This))
2837 return NS_ERROR_UNEXPECTED;
2839 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2840 if(FAILED(hres))
2841 return NS_ERROR_UNEXPECTED;
2843 MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, sizeof(buf)/sizeof(WCHAR));
2844 *_retval = !strcmpW(scheme_name, buf);
2845 SysFreeString(scheme_name);
2846 return NS_OK;
2849 static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
2851 nsWineURI *This = impl_from_nsIFileURL(iface);
2852 nsWineURI *wine_uri;
2853 nsresult nsres;
2855 TRACE("(%p)->(%p)\n", This, _retval);
2857 if(!ensure_uri(This))
2858 return NS_ERROR_UNEXPECTED;
2860 nsres = create_nsuri(This->uri, This->window_ref ? This->window_ref->window : NULL,
2861 This->container, This->origin_charset, &wine_uri);
2862 if(NS_FAILED(nsres)) {
2863 WARN("create_nsuri failed: %08x\n", nsres);
2864 return nsres;
2867 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2868 return NS_OK;
2871 static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
2872 nsACString *_retval)
2874 nsWineURI *This = impl_from_nsIFileURL(iface);
2875 const char *patha;
2876 IUri *new_uri;
2877 WCHAR *path;
2878 char *reta;
2879 BSTR ret;
2880 HRESULT hres;
2882 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2884 if(!ensure_uri(This))
2885 return NS_ERROR_UNEXPECTED;
2887 nsACString_GetData(aRelativePath, &patha);
2888 path = heap_strdupUtoW(patha);
2889 if(!path)
2890 return NS_ERROR_OUT_OF_MEMORY;
2892 hres = combine_url(This->uri, path, &new_uri);
2893 heap_free(path);
2894 if(FAILED(hres))
2895 return NS_ERROR_FAILURE;
2897 hres = IUri_GetDisplayUri(new_uri, &ret);
2898 IUri_Release(new_uri);
2899 if(FAILED(hres))
2900 return NS_ERROR_FAILURE;
2902 reta = heap_strdupWtoU(ret);
2903 SysFreeString(ret);
2904 if(!reta)
2905 return NS_ERROR_OUT_OF_MEMORY;
2907 TRACE("returning %s\n", debugstr_a(reta));
2908 nsACString_SetData(_retval, reta);
2909 heap_free(reta);
2910 return NS_OK;
2913 static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
2915 nsWineURI *This = impl_from_nsIFileURL(iface);
2917 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2919 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
2922 static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort)
2924 nsWineURI *This = impl_from_nsIFileURL(iface);
2926 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort);
2928 return nsIFileURL_GetHostPort(&This->nsIFileURL_iface, aAsciiHostPort);
2931 static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
2933 nsWineURI *This = impl_from_nsIFileURL(iface);
2935 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2937 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
2940 static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
2942 nsWineURI *This = impl_from_nsIFileURL(iface);
2944 TRACE("(%p)->(%p)\n", This, aOriginCharset);
2946 nsACString_SetData(aOriginCharset, This->origin_charset);
2947 return NS_OK;
2950 static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
2952 nsWineURI *This = impl_from_nsIFileURL(iface);
2953 char *refa = NULL;
2954 BSTR ref;
2955 HRESULT hres;
2957 TRACE("(%p)->(%p)\n", This, aRef);
2959 if(!ensure_uri(This))
2960 return NS_ERROR_UNEXPECTED;
2962 hres = IUri_GetFragment(This->uri, &ref);
2963 if(FAILED(hres))
2964 return NS_ERROR_UNEXPECTED;
2966 refa = heap_strdupWtoU(ref);
2967 SysFreeString(ref);
2968 if(ref && !refa)
2969 return NS_ERROR_OUT_OF_MEMORY;
2971 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
2972 heap_free(refa);
2973 return NS_OK;
2976 static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
2978 nsWineURI *This = impl_from_nsIFileURL(iface);
2979 const char *refa;
2980 WCHAR *ref;
2981 HRESULT hres;
2983 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
2985 if(!ensure_uri_builder(This))
2986 return NS_ERROR_UNEXPECTED;
2988 nsACString_GetData(aRef, &refa);
2989 ref = heap_strdupUtoW(refa);
2990 if(!ref)
2991 return NS_ERROR_OUT_OF_MEMORY;
2993 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
2994 heap_free(ref);
2995 if(FAILED(hres))
2996 return NS_ERROR_UNEXPECTED;
2998 return NS_OK;
3001 static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
3003 nsWineURI *This = impl_from_nsIFileURL(iface);
3004 nsWineURI *other_obj;
3005 nsresult nsres;
3007 TRACE("(%p)->(%p %p)\n", This, other, _retval);
3009 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
3010 if(NS_FAILED(nsres)) {
3011 TRACE("Could not get nsWineURI interface\n");
3012 *_retval = FALSE;
3013 return NS_OK;
3016 if(ensure_uri(This) && ensure_uri(other_obj)) {
3017 *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
3018 nsres = NS_OK;
3019 }else {
3020 nsres = NS_ERROR_UNEXPECTED;
3023 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
3024 return nsres;
3027 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
3029 nsWineURI *This = impl_from_nsIFileURL(iface);
3030 nsWineURI *wine_uri;
3031 IUri *uri;
3032 nsresult nsres;
3034 TRACE("(%p)->(%p)\n", This, _retval);
3036 if(!ensure_uri(This))
3037 return NS_ERROR_UNEXPECTED;
3039 uri = get_uri_nofrag(This->uri);
3040 if(!uri)
3041 return NS_ERROR_FAILURE;
3043 nsres = create_nsuri(uri, This->window_ref ? This->window_ref->window : NULL, This->container,
3044 This->origin_charset, &wine_uri);
3045 IUri_Release(uri);
3046 if(NS_FAILED(nsres)) {
3047 WARN("create_nsuri failed: %08x\n", nsres);
3048 return nsres;
3051 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3052 return NS_OK;
3055 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
3057 nsWineURI *This = impl_from_nsIFileURL(iface);
3059 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
3061 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
3064 static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
3066 nsWineURI *This = impl_from_nsIFileURL(iface);
3067 BOOL b;
3068 HRESULT hres;
3070 TRACE("(%p)->(%p)\n", This, aHasRef);
3072 if(!ensure_uri(This))
3073 return NS_ERROR_UNEXPECTED;
3075 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
3076 if(FAILED(hres))
3077 return NS_ERROR_FAILURE;
3079 *aHasRef = b;
3080 return NS_OK;
3083 static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
3085 nsWineURI *This = impl_from_nsIFileURL(iface);
3087 TRACE("(%p)->(%p)\n", This, aFilePath);
3089 return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
3092 static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
3094 nsWineURI *This = impl_from_nsIFileURL(iface);
3096 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
3098 if(!This->is_mutable)
3099 return NS_ERROR_UNEXPECTED;
3101 return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
3104 static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
3106 nsWineURI *This = impl_from_nsIFileURL(iface);
3107 WCHAR *ptr;
3108 BSTR query;
3109 nsresult nsres;
3110 HRESULT hres;
3112 TRACE("(%p)->(%p)\n", This, aQuery);
3114 if(!ensure_uri(This))
3115 return NS_ERROR_UNEXPECTED;
3117 hres = IUri_GetQuery(This->uri, &query);
3118 if(FAILED(hres))
3119 return NS_ERROR_FAILURE;
3121 ptr = query;
3122 if(ptr && *ptr == '?')
3123 ptr++;
3125 nsres = return_wstr_nsacstr(aQuery, ptr, -1);
3126 SysFreeString(query);
3127 return nsres;
3130 static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
3132 nsWineURI *This = impl_from_nsIFileURL(iface);
3133 const char *querya;
3134 WCHAR *query;
3135 HRESULT hres;
3137 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
3139 if(!ensure_uri_builder(This))
3140 return NS_ERROR_UNEXPECTED;
3142 nsACString_GetData(aQuery, &querya);
3143 query = heap_strdupUtoW(querya);
3144 if(!query)
3145 return NS_ERROR_OUT_OF_MEMORY;
3147 hres = IUriBuilder_SetQuery(This->uri_builder, query);
3148 heap_free(query);
3149 if(FAILED(hres))
3150 return NS_ERROR_UNEXPECTED;
3152 return NS_OK;
3155 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
3157 const WCHAR *ptr;
3158 HRESULT hres;
3160 if(!ensure_uri(This))
3161 return NS_ERROR_UNEXPECTED;
3163 hres = IUri_GetPath(This->uri, path);
3164 if(FAILED(hres))
3165 return NS_ERROR_FAILURE;
3167 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
3168 if(*ptr == '/' || *ptr == '\\')
3169 ptr++;
3170 *file = ptr;
3172 if(ext) {
3173 ptr = strrchrW(ptr, '.');
3174 if(!ptr)
3175 ptr = *path + SysStringLen(*path);
3176 *ext = ptr;
3179 return NS_OK;
3182 static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
3184 nsWineURI *This = impl_from_nsIFileURL(iface);
3185 const WCHAR *file;
3186 BSTR path;
3187 nsresult nsres;
3189 TRACE("(%p)->(%p)\n", This, aDirectory);
3191 nsres = get_uri_path(This, &path, &file, NULL);
3192 if(NS_FAILED(nsres))
3193 return nsres;
3195 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
3196 SysFreeString(path);
3197 return nsres;
3200 static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
3202 nsWineURI *This = impl_from_nsIFileURL(iface);
3204 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
3206 /* Not implemented by Gecko */
3207 return NS_ERROR_NOT_IMPLEMENTED;
3210 static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
3212 nsWineURI *This = impl_from_nsIFileURL(iface);
3213 const WCHAR *file;
3214 BSTR path;
3215 nsresult nsres;
3217 TRACE("(%p)->(%p)\n", This, aFileName);
3219 nsres = get_uri_path(This, &path, &file, NULL);
3220 if(NS_FAILED(nsres))
3221 return nsres;
3223 nsres = return_wstr_nsacstr(aFileName, file, -1);
3224 SysFreeString(path);
3225 return nsres;
3228 static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
3230 nsWineURI *This = impl_from_nsIFileURL(iface);
3231 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
3232 return NS_ERROR_NOT_IMPLEMENTED;
3235 static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
3237 nsWineURI *This = impl_from_nsIFileURL(iface);
3238 const WCHAR *file, *ext;
3239 BSTR path;
3240 nsresult nsres;
3242 TRACE("(%p)->(%p)\n", This, aFileBaseName);
3244 nsres = get_uri_path(This, &path, &file, &ext);
3245 if(NS_FAILED(nsres))
3246 return nsres;
3248 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
3249 SysFreeString(path);
3250 return nsres;
3253 static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
3255 nsWineURI *This = impl_from_nsIFileURL(iface);
3256 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
3257 return NS_ERROR_NOT_IMPLEMENTED;
3260 static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
3262 nsWineURI *This = impl_from_nsIFileURL(iface);
3264 TRACE("(%p)->(%p)\n", This, aFileExtension);
3266 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
3269 static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
3271 nsWineURI *This = impl_from_nsIFileURL(iface);
3272 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
3273 return NS_ERROR_NOT_IMPLEMENTED;
3276 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3278 nsWineURI *This = impl_from_nsIFileURL(iface);
3279 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3280 return NS_ERROR_NOT_IMPLEMENTED;
3283 static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3285 nsWineURI *This = impl_from_nsIFileURL(iface);
3286 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3287 return NS_ERROR_NOT_IMPLEMENTED;
3290 static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
3292 nsWineURI *This = impl_from_nsIFileURL(iface);
3293 WCHAR path[MAX_PATH];
3294 DWORD size;
3295 HRESULT hres;
3297 TRACE("(%p)->(%p)\n", This, aFile);
3299 hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, sizeof(path)/sizeof(WCHAR), &size, 0);
3300 if(FAILED(hres)) {
3301 WARN("CoInternetParseIUri failed: %08x\n", hres);
3302 return NS_ERROR_FAILURE;
3305 return create_nsfile(path, aFile);
3308 static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
3310 nsWineURI *This = impl_from_nsIFileURL(iface);
3311 FIXME("(%p)->(%p)\n", This, aFile);
3312 return NS_ERROR_NOT_IMPLEMENTED;
3315 static const nsIFileURLVtbl nsFileURLVtbl = {
3316 nsURI_QueryInterface,
3317 nsURI_AddRef,
3318 nsURI_Release,
3319 nsURI_GetSpec,
3320 nsURI_SetSpec,
3321 nsURI_GetPrePath,
3322 nsURI_GetScheme,
3323 nsURI_SetScheme,
3324 nsURI_GetUserPass,
3325 nsURI_SetUserPass,
3326 nsURI_GetUsername,
3327 nsURI_SetUsername,
3328 nsURI_GetPassword,
3329 nsURI_SetPassword,
3330 nsURI_GetHostPort,
3331 nsURI_SetHostPort,
3332 nsURI_GetHost,
3333 nsURI_SetHost,
3334 nsURI_GetPort,
3335 nsURI_SetPort,
3336 nsURI_GetPath,
3337 nsURI_SetPath,
3338 nsURI_Equals,
3339 nsURI_SchemeIs,
3340 nsURI_Clone,
3341 nsURI_Resolve,
3342 nsURI_GetAsciiSpec,
3343 nsURI_GetAsciiHostPort,
3344 nsURI_GetAsciiHost,
3345 nsURI_GetOriginCharset,
3346 nsURL_GetRef,
3347 nsURL_SetRef,
3348 nsURI_EqualsExceptRef,
3349 nsURI_CloneIgnoreRef,
3350 nsURI_GetSpecIgnoringRef,
3351 nsURI_GetHasRef,
3352 nsURL_GetFilePath,
3353 nsURL_SetFilePath,
3354 nsURL_GetQuery,
3355 nsURL_SetQuery,
3356 nsURL_GetDirectory,
3357 nsURL_SetDirectory,
3358 nsURL_GetFileName,
3359 nsURL_SetFileName,
3360 nsURL_GetFileBaseName,
3361 nsURL_SetFileBaseName,
3362 nsURL_GetFileExtension,
3363 nsURL_SetFileExtension,
3364 nsURL_GetCommonBaseSpec,
3365 nsURL_GetRelativeSpec,
3366 nsFileURL_GetFile,
3367 nsFileURL_SetFile
3370 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
3372 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
3375 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
3376 void **result)
3378 nsWineURI *This = impl_from_nsIStandardURL(iface);
3379 return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
3382 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
3384 nsWineURI *This = impl_from_nsIStandardURL(iface);
3385 return nsIFileURL_AddRef(&This->nsIFileURL_iface);
3388 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
3390 nsWineURI *This = impl_from_nsIStandardURL(iface);
3391 return nsIFileURL_Release(&This->nsIFileURL_iface);
3394 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
3396 nsWineURI *This = impl_from_nsIStandardURL(iface);
3398 TRACE("(%p)->(%p)\n", This, aMutable);
3400 *aMutable = This->is_mutable;
3401 return NS_OK;
3404 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
3406 nsWineURI *This = impl_from_nsIStandardURL(iface);
3408 TRACE("(%p)->(%x)\n", This, aMutable);
3410 This->is_mutable = aMutable;
3411 return NS_OK;
3414 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
3415 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
3417 nsWineURI *This = impl_from_nsIStandardURL(iface);
3418 FIXME("(%p)->(%d %d %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
3419 return NS_ERROR_NOT_IMPLEMENTED;
3422 static nsresult NSAPI nsStandardURL_SetDefaultPort(nsIStandardURL *iface, LONG aNewDefaultPort)
3424 nsWineURI *This = impl_from_nsIStandardURL(iface);
3425 FIXME("(%p)->(%d)\n", This, aNewDefaultPort);
3426 return NS_ERROR_NOT_IMPLEMENTED;
3429 static const nsIStandardURLVtbl nsStandardURLVtbl = {
3430 nsStandardURL_QueryInterface,
3431 nsStandardURL_AddRef,
3432 nsStandardURL_Release,
3433 nsStandardURL_GetMutable,
3434 nsStandardURL_SetMutable,
3435 nsStandardURL_Init,
3436 nsStandardURL_SetDefaultPort
3439 static nsresult create_nsuri(IUri *iuri, HTMLOuterWindow *window, NSContainer *container,
3440 const char *origin_charset, nsWineURI **_retval)
3442 nsWineURI *ret;
3443 HRESULT hres;
3445 ret = heap_alloc_zero(sizeof(nsWineURI));
3446 if(!ret)
3447 return NS_ERROR_OUT_OF_MEMORY;
3449 ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
3450 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
3451 ret->ref = 1;
3452 ret->is_mutable = TRUE;
3454 set_uri_nscontainer(ret, container);
3455 set_uri_window(ret, window);
3457 IUri_AddRef(iuri);
3458 ret->uri = iuri;
3460 hres = IUri_GetScheme(iuri, &ret->scheme);
3461 if(FAILED(hres))
3462 ret->scheme = URL_SCHEME_UNKNOWN;
3464 if(origin_charset && *origin_charset && strcmp(origin_charset, "UTF-8")) {
3465 ret->origin_charset = heap_strdupA(origin_charset);
3466 if(!ret->origin_charset) {
3467 nsIFileURL_Release(&ret->nsIFileURL_iface);
3468 return NS_ERROR_OUT_OF_MEMORY;
3472 TRACE("retval=%p\n", ret);
3473 *_retval = ret;
3474 return NS_OK;
3477 HRESULT create_doc_uri(HTMLOuterWindow *window, IUri *iuri, nsWineURI **ret)
3479 nsWineURI *uri;
3480 nsresult nsres;
3482 nsres = create_nsuri(iuri, window, window->doc_obj ? window->doc_obj->nscontainer : NULL,
3483 NULL, &uri);
3484 if(NS_FAILED(nsres))
3485 return E_FAIL;
3487 uri->is_doc_uri = TRUE;
3489 *ret = uri;
3490 return S_OK;
3493 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
3495 nsChannel *channel;
3497 if(!ensure_uri(uri))
3498 return NS_ERROR_UNEXPECTED;
3500 channel = heap_alloc_zero(sizeof(nsChannel));
3501 if(!channel)
3502 return NS_ERROR_OUT_OF_MEMORY;
3504 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
3505 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
3506 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
3507 channel->ref = 1;
3508 channel->request_method = METHOD_GET;
3509 list_init(&channel->response_headers);
3510 list_init(&channel->request_headers);
3512 nsIFileURL_AddRef(&uri->nsIFileURL_iface);
3513 channel->uri = uri;
3515 *ret = channel;
3516 return NS_OK;
3519 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
3521 HTMLOuterWindow *window = NULL;
3522 nsChannel *channel;
3523 nsWineURI *uri;
3524 IUri *iuri;
3525 nsresult nsres;
3526 HRESULT hres;
3528 hres = create_uri(url, 0, &iuri);
3529 if(FAILED(hres))
3530 return hres;
3532 if(orig_channel->uri->window_ref)
3533 window = orig_channel->uri->window_ref->window;
3534 nsres = create_nsuri(iuri, window, NULL, NULL, &uri);
3535 IUri_Release(iuri);
3536 if(NS_FAILED(nsres))
3537 return E_FAIL;
3539 nsres = create_nschannel(uri, &channel);
3540 nsIFileURL_Release(&uri->nsIFileURL_iface);
3541 if(NS_FAILED(nsres))
3542 return E_FAIL;
3544 if(orig_channel->load_group) {
3545 nsILoadGroup_AddRef(orig_channel->load_group);
3546 channel->load_group = orig_channel->load_group;
3549 if(orig_channel->notif_callback) {
3550 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
3551 channel->notif_callback = orig_channel->notif_callback;
3554 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
3556 if(orig_channel->request_method == METHOD_POST)
3557 FIXME("unsupported POST method\n");
3559 if(orig_channel->original_uri) {
3560 nsIURI_AddRef(orig_channel->original_uri);
3561 channel->original_uri = orig_channel->original_uri;
3564 if(orig_channel->referrer) {
3565 nsIURI_AddRef(orig_channel->referrer);
3566 channel->referrer = orig_channel->referrer;
3569 *ret = channel;
3570 return S_OK;
3573 typedef struct {
3574 nsIProtocolHandler nsIProtocolHandler_iface;
3576 LONG ref;
3578 nsIProtocolHandler *nshandler;
3579 } nsProtocolHandler;
3581 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
3583 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
3586 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
3587 void **result)
3589 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3591 *result = NULL;
3593 if(IsEqualGUID(&IID_nsISupports, riid)) {
3594 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
3595 *result = &This->nsIProtocolHandler_iface;
3596 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
3597 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
3598 *result = &This->nsIProtocolHandler_iface;
3599 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
3600 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
3601 return NS_NOINTERFACE;
3604 if(*result) {
3605 nsISupports_AddRef((nsISupports*)*result);
3606 return NS_OK;
3609 WARN("(%s %p)\n", debugstr_guid(riid), result);
3610 return NS_NOINTERFACE;
3613 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
3615 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3616 LONG ref = InterlockedIncrement(&This->ref);
3618 TRACE("(%p) ref=%d\n", This, ref);
3620 return ref;
3623 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3625 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3626 LONG ref = InterlockedDecrement(&This->ref);
3628 TRACE("(%p) ref=%d\n", This, ref);
3630 if(!ref) {
3631 if(This->nshandler)
3632 nsIProtocolHandler_Release(This->nshandler);
3633 heap_free(This);
3636 return ref;
3639 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3641 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3643 TRACE("(%p)->(%p)\n", This, aScheme);
3645 if(This->nshandler)
3646 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3647 return NS_ERROR_NOT_IMPLEMENTED;
3650 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3651 LONG *aDefaultPort)
3653 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3655 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3657 if(This->nshandler)
3658 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3659 return NS_ERROR_NOT_IMPLEMENTED;
3662 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3663 UINT32 *aProtocolFlags)
3665 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3667 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3669 if(This->nshandler)
3670 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3671 return NS_ERROR_NOT_IMPLEMENTED;
3674 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3675 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3677 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3679 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3680 aBaseURI, _retval);
3682 if(This->nshandler)
3683 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3684 return NS_ERROR_NOT_IMPLEMENTED;
3687 static nsresult NSAPI nsProtocolHandler_NewChannel2(nsIProtocolHandler *iface,
3688 nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3690 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3692 TRACE("(%p)->(%p %p %p)\n", This, aURI, aLoadInfo, _retval);
3694 if(This->nshandler)
3695 return nsIProtocolHandler_NewChannel2(This->nshandler, aURI, aLoadInfo, _retval);
3696 return NS_ERROR_NOT_IMPLEMENTED;
3699 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3700 nsIURI *aURI, nsIChannel **_retval)
3702 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3704 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3706 if(This->nshandler)
3707 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3708 return NS_ERROR_NOT_IMPLEMENTED;
3711 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3712 LONG port, const char *scheme, cpp_bool *_retval)
3714 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3716 TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
3718 if(This->nshandler)
3719 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3720 return NS_ERROR_NOT_IMPLEMENTED;
3723 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3724 nsProtocolHandler_QueryInterface,
3725 nsProtocolHandler_AddRef,
3726 nsProtocolHandler_Release,
3727 nsProtocolHandler_GetScheme,
3728 nsProtocolHandler_GetDefaultPort,
3729 nsProtocolHandler_GetProtocolFlags,
3730 nsProtocolHandler_NewURI,
3731 nsProtocolHandler_NewChannel2,
3732 nsProtocolHandler_NewChannel,
3733 nsProtocolHandler_AllowPort
3736 static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid,
3737 void **result)
3739 if(IsEqualGUID(&IID_nsISupports, riid)) {
3740 TRACE("(IID_nsISupports %p)\n", result);
3741 *result = iface;
3742 }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) {
3743 TRACE("(IID_nsIIOServiceHook %p)\n", result);
3744 *result = iface;
3745 }else {
3746 ERR("(%s %p)\n", debugstr_guid(riid), result);
3747 *result = NULL;
3748 return NS_NOINTERFACE;
3751 nsISupports_AddRef((nsISupports*)*result);
3752 return NS_OK;
3755 static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface)
3757 return 2;
3760 static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface)
3762 return 1;
3765 static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI,
3766 nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3768 nsWineURI *wine_uri;
3769 nsChannel *ret;
3770 nsresult nsres;
3772 TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval);
3774 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3775 if(NS_FAILED(nsres)) {
3776 TRACE("Could not get nsWineURI: %08x\n", nsres);
3777 return NS_SUCCESS_DEFAULT_ACTION;
3780 nsres = create_nschannel(wine_uri, &ret);
3781 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3782 if(NS_FAILED(nsres))
3783 return nsres;
3785 nsIURI_AddRef(aURI);
3786 ret->original_uri = aURI;
3788 if(aLoadInfo)
3789 nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo);
3791 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3792 return NS_OK;
3795 static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler,
3796 nsIProtocolHandler **_retval)
3798 nsIExternalProtocolHandler *nsexthandler;
3799 nsProtocolHandler *ret;
3800 nsresult nsres;
3802 TRACE("(%p %p)\n", aHandler, _retval);
3804 nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler);
3805 if(NS_FAILED(nsres)) {
3806 nsIProtocolHandler_AddRef(aHandler);
3807 *_retval = aHandler;
3808 return NS_OK;
3811 nsIExternalProtocolHandler_Release(nsexthandler);
3813 ret = heap_alloc(sizeof(nsProtocolHandler));
3814 if(!ret)
3815 return NS_ERROR_OUT_OF_MEMORY;
3817 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3818 ret->ref = 1;
3819 nsIProtocolHandler_AddRef(aHandler);
3820 ret->nshandler = aHandler;
3823 *_retval = &ret->nsIProtocolHandler_iface;
3824 TRACE("return %p\n", *_retval);
3825 return NS_OK;
3828 static BOOL is_gecko_special_uri(const char *spec)
3830 static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"};
3831 unsigned int i;
3833 for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
3834 if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
3835 return TRUE;
3838 if(!strncasecmp(spec, "file:", 5)) {
3839 const char *ptr = spec+5;
3840 while(*ptr == '/')
3841 ptr++;
3842 return is_gecko_path(ptr);
3845 return FALSE;
3848 static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec,
3849 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3851 nsWineURI *wine_uri, *base_wine_uri = NULL;
3852 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3853 HTMLOuterWindow *window = NULL;
3854 const char *spec = NULL;
3855 UINT cp = CP_UTF8;
3856 IUri *urlmon_uri;
3857 nsresult nsres;
3858 HRESULT hres;
3860 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3861 aBaseURI, _retval);
3863 nsACString_GetData(aSpec, &spec);
3864 if(is_gecko_special_uri(spec))
3865 return NS_SUCCESS_DEFAULT_ACTION;
3867 if(!strncmp(spec, "wine:", 5))
3868 spec += 5;
3870 if(aBaseURI) {
3871 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3872 if(NS_SUCCEEDED(nsres)) {
3873 if(!ensure_uri(base_wine_uri))
3874 return NS_ERROR_UNEXPECTED;
3875 if(base_wine_uri->window_ref)
3876 window = base_wine_uri->window_ref->window;
3877 }else {
3878 WARN("Could not get base nsWineURI: %08x\n", nsres);
3882 if(aOriginCharset && *aOriginCharset && strncasecmp(aOriginCharset, "utf", 3)) {
3883 BSTR charset;
3884 int len;
3886 len = MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, NULL, 0);
3887 charset = SysAllocStringLen(NULL, len-1);
3888 if(!charset)
3889 return NS_ERROR_OUT_OF_MEMORY;
3890 MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, charset, len);
3892 cp = cp_from_charset_string(charset);
3894 SysFreeString(charset);
3897 MultiByteToWideChar(cp, 0, spec, -1, new_spec, sizeof(new_spec)/sizeof(WCHAR));
3899 if(base_wine_uri) {
3900 hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri);
3901 }else {
3902 hres = create_uri(new_spec, 0, &urlmon_uri);
3903 if(FAILED(hres))
3904 WARN("create_uri failed: %08x\n", hres);
3907 if(FAILED(hres))
3908 return NS_SUCCESS_DEFAULT_ACTION;
3910 nsres = create_nsuri(urlmon_uri, window, NULL, NULL, &wine_uri);
3911 IUri_Release(urlmon_uri);
3912 if(base_wine_uri)
3913 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3914 if(NS_FAILED(nsres))
3915 return nsres;
3917 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3918 return nsres;
3921 static const char *debugstr_protocol_flags(UINT32 flags)
3923 switch(flags) {
3924 #define X(f) case f: return #f
3925 X(URI_STD);
3926 X(URI_NORELATIVE);
3927 X(URI_NOAUTH);
3928 X(ALLOWS_PROXY);
3929 X(ALLOWS_PROXY_HTTP);
3930 X(URI_INHERITS_SECURITY_CONTEXT);
3931 X(URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
3932 X(URI_LOADABLE_BY_ANYONE);
3933 X(URI_DANGEROUS_TO_LOAD);
3934 X(URI_IS_UI_RESOURCE);
3935 X(URI_IS_LOCAL_FILE);
3936 X(URI_LOADABLE_BY_SUBSUMERS);
3937 X(URI_DOES_NOT_RETURN_DATA);
3938 X(URI_IS_LOCAL_RESOURCE);
3939 X(URI_OPENING_EXECUTES_SCRIPT);
3940 X(URI_NON_PERSISTABLE);
3941 X(URI_FORBIDS_COOKIE_ACCESS);
3942 X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM);
3943 X(URI_SYNC_LOAD_IS_OK);
3944 X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT);
3945 X(URI_FETCHABLE_BY_ANYONE);
3946 #undef X
3947 default:
3948 return wine_dbg_sprintf("%08x", flags);
3952 static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3954 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3955 return NS_SUCCESS_DEFAULT_ACTION;
3958 static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3960 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3962 if(aFlags == URI_DOES_NOT_RETURN_DATA) {
3963 *_retval = FALSE;
3964 return S_OK;
3967 return NS_SUCCESS_DEFAULT_ACTION;
3970 static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = {
3971 nsIOServiceHook_QueryInterface,
3972 nsIOServiceHook_AddRef,
3973 nsIOServiceHook_Release,
3974 nsIOServiceHook_NewChannel,
3975 nsIOServiceHook_GetProtocolHandler,
3976 nsIOServiceHook_NewURI,
3977 nsIOServiceHook_ProtocolHasFlags,
3978 nsIOServiceHook_URIChainHasFlags
3981 static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };
3983 static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri)
3985 OLECHAR *new_url = NULL;
3986 WCHAR *url;
3987 BOOL ret = FALSE;
3988 HRESULT hres;
3990 if(!doc->hostui || !ensure_uri(uri))
3991 return FALSE;
3993 hres = IUri_GetDisplayUri(uri->uri, &url);
3994 if(FAILED(hres))
3995 return FALSE;
3997 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
3998 if(hres == S_OK && new_url) {
3999 if(strcmpW(url, new_url)) {
4000 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
4001 ret = TRUE;
4003 CoTaskMemFree(new_url);
4006 SysFreeString(url);
4007 return ret;
4010 nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, cpp_bool *_retval)
4012 nsWineURI *wine_uri;
4013 nsresult nsres;
4015 *_retval = FALSE;
4017 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
4018 if(NS_FAILED(nsres)) {
4019 WARN("Could not get nsWineURI: %08x\n", nsres);
4020 return NS_ERROR_NOT_IMPLEMENTED;
4023 if(!wine_uri->is_doc_uri) {
4024 wine_uri->is_doc_uri = TRUE;
4026 if(!wine_uri->container) {
4027 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
4028 wine_uri->container = nscontainer;
4031 if(nscontainer->doc)
4032 *_retval = translate_url(nscontainer->doc, wine_uri);
4035 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
4036 return NS_OK;
4039 void init_nsio(nsIComponentManager *component_manager)
4041 nsIFactory *old_factory = NULL;
4042 nsresult nsres;
4044 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
4045 &IID_nsIFactory, (void**)&old_factory);
4046 if(NS_FAILED(nsres)) {
4047 ERR("Could not get factory: %08x\n", nsres);
4048 return;
4051 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
4052 if(NS_FAILED(nsres)) {
4053 ERR("Couldn not create nsIOService instance %08x\n", nsres);
4054 nsIFactory_Release(old_factory);
4055 return;
4058 nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
4059 assert(nsres == NS_OK);
4062 void release_nsio(void)
4064 if(nsio) {
4065 nsIIOService_Release(nsio);
4066 nsio = NULL;