mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / mshtml / nsio.c
blobea8eae2007d0e5afe89a7971b8066734eaee7771
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 <stdarg.h>
20 #include <assert.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "winternl.h"
29 #include "ole2.h"
30 #include "shlguid.h"
31 #include "wininet.h"
32 #include "shlwapi.h"
34 #include "wine/debug.h"
36 #include "mshtml_private.h"
37 #include "binding.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41 #define NS_IOSERVICE_CLASSNAME "nsIOService"
42 #define NS_IOSERVICE_CONTRACTID "@mozilla.org/network/io-service;1"
44 static const IID NS_IOSERVICE_CID =
45 {0x9ac9e770, 0x18bc, 0x11d3, {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
46 static const IID IID_nsWineURI =
47 {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};
49 static nsIIOService *nsio = NULL;
51 static const char *request_method_strings[] = {"GET", "PUT", "POST"};
53 struct nsWineURI {
54 nsIFileURL nsIFileURL_iface; /* For non-file URL objects, it's just nsIURL */
55 nsIStandardURL nsIStandardURL_iface;
57 LONG ref;
59 nsChannelBSC *channel_bsc;
60 IUri *uri;
61 IUriBuilder *uri_builder;
62 BOOL is_mutable;
63 DWORD scheme;
66 static BOOL ensure_uri(nsWineURI *This)
68 HRESULT hres;
70 assert(This->uri || This->uri_builder);
72 if(!This->uri) {
73 hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
74 if(FAILED(hres)) {
75 WARN("CreateUriSimple failed: %08x\n", hres);
76 return FALSE;
80 return TRUE;
83 IUri *nsuri_get_uri(nsWineURI *nsuri)
85 if(!ensure_uri(nsuri))
86 return NULL;
88 IUri_AddRef(nsuri->uri);
89 return nsuri->uri;
92 IUri *get_uri_nofrag(IUri *uri)
94 IUriBuilder *uri_builder;
95 IUri *ret;
96 BOOL b;
97 HRESULT hres;
99 hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
100 if(SUCCEEDED(hres) && !b) {
101 IUri_AddRef(uri);
102 return uri;
105 hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
106 if(FAILED(hres))
107 return NULL;
109 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
110 if(SUCCEEDED(hres))
111 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
112 IUriBuilder_Release(uri_builder);
113 if(FAILED(hres))
114 return NULL;
116 return ret;
119 static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
121 IUri *uri_nofrag1, *uri_nofrag2;
122 BOOL ret = FALSE;
124 uri_nofrag1 = get_uri_nofrag(uri1);
125 if(!uri_nofrag1)
126 return FALSE;
128 uri_nofrag2 = get_uri_nofrag(uri2);
129 if(uri_nofrag2) {
130 IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
131 IUri_Release(uri_nofrag2);
134 IUri_Release(uri_nofrag1);
135 return ret;
138 static HRESULT combine_url(IUri *base_uri, const WCHAR *rel_url, IUri **ret)
140 IUri *uri_nofrag;
141 HRESULT hres;
143 uri_nofrag = get_uri_nofrag(base_uri);
144 if(!uri_nofrag)
145 return E_FAIL;
147 hres = CoInternetCombineUrlEx(uri_nofrag, rel_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
148 ret, 0);
149 IUri_Release(uri_nofrag);
150 if(FAILED(hres))
151 WARN("CoInternetCombineUrlEx failed: %08x\n", hres);
152 return hres;
155 static nsresult create_nsuri(IUri*,nsWineURI**);
157 static const char *debugstr_nsacstr(const nsACString *nsstr)
159 const char *data;
161 nsACString_GetData(nsstr, &data);
162 return debugstr_a(data);
165 static nsresult return_wstr_nsacstr(nsACString *ret_str, const WCHAR *str, int len)
167 char *stra;
168 int lena;
170 TRACE("returning %s\n", debugstr_wn(str, len));
172 if(!*str) {
173 nsACString_SetData(ret_str, "");
174 return NS_OK;
177 lena = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
178 stra = heap_alloc(lena+1);
179 if(!stra)
180 return NS_ERROR_OUT_OF_MEMORY;
182 WideCharToMultiByte(CP_UTF8, 0, str, len, stra, lena, NULL, NULL);
183 stra[lena] = 0;
185 nsACString_SetData(ret_str, stra);
186 heap_free(stra);
187 return NS_OK;
190 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
192 const WCHAR *ptr = nsuri;
194 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
196 if(!wcsncmp(nsuri, wine_prefixW, ARRAY_SIZE(wine_prefixW)))
197 ptr += ARRAY_SIZE(wine_prefixW);
199 if(*ptr || ret_empty) {
200 *ret = SysAllocString(ptr);
201 if(!*ret)
202 return E_OUTOFMEMORY;
203 }else {
204 *ret = NULL;
207 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
208 return S_OK;
211 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
213 IOleCommandTarget *cmdtrg = NULL;
214 HRESULT hres;
216 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
217 if(SUCCEEDED(hres)) {
218 VARIANT varUrl, varRes;
220 V_VT(&varUrl) = VT_BSTR;
221 V_BSTR(&varUrl) = url;
222 V_VT(&varRes) = VT_BOOL;
224 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
226 IOleCommandTarget_Release(cmdtrg);
228 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
229 TRACE("got VARIANT_FALSE, do not load\n");
230 return FALSE;
234 return TRUE;
237 static nsresult before_async_open(nsChannel *channel, GeckoBrowser *container, BOOL *cancel)
239 HTMLDocumentObj *doc = container->doc;
240 BSTR display_uri;
241 HRESULT hres;
243 if(!doc->client) {
244 *cancel = TRUE;
245 return NS_OK;
248 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
249 if(FAILED(hres))
250 return NS_ERROR_FAILURE;
252 if(doc->hostui) {
253 OLECHAR *new_url;
254 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, display_uri, &new_url);
255 if(hres == S_OK && new_url) {
256 if(wcscmp(display_uri, new_url)) {
257 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(display_uri), debugstr_w(new_url));
258 CoTaskMemFree(new_url);
259 *cancel = TRUE;
260 return NS_OK;
262 CoTaskMemFree(new_url);
266 if(!exec_shldocvw_67(doc, display_uri)) {
267 SysFreeString(display_uri);
268 *cancel = FALSE;
269 return NS_OK;
272 hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, 0, cancel);
273 SysFreeString(display_uri);
274 if(FAILED(hres))
275 *cancel = TRUE;
276 return NS_OK;
279 HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsIInputStream *post_stream,
280 nsChannelBSC *channelbsc, DWORD flags)
282 nsIWebNavigation *web_navigation;
283 nsIDocShellLoadInfo *load_info;
284 nsIDocShell *doc_shell;
285 HTMLDocumentNode *doc;
286 nsresult nsres;
288 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
289 if(NS_FAILED(nsres)) {
290 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
291 return E_FAIL;
294 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
295 nsIWebNavigation_Release(web_navigation);
296 if(NS_FAILED(nsres)) {
297 ERR("Could not get nsIDocShell: %08x\n", nsres);
298 return E_FAIL;
301 nsres = nsIDocShell_CreateLoadInfo(doc_shell, &load_info);
302 if(NS_FAILED(nsres)) {
303 nsIDocShell_Release(doc_shell);
304 return E_FAIL;
307 nsres = nsIDocShellLoadInfo_SetLoadType(load_info, (flags & LOAD_FLAGS_BYPASS_CACHE) ? loadNormalBypassCache : loadNormal);
308 assert(nsres == NS_OK);
310 if(post_stream) {
311 nsres = nsIDocShellLoadInfo_SetPostDataStream(load_info, post_stream);
312 assert(nsres == NS_OK);
315 if(window->uri_nofrag) {
316 nsWineURI *referrer_uri;
317 nsres = create_nsuri(window->uri_nofrag, &referrer_uri);
318 if(NS_SUCCEEDED(nsres)) {
319 nsres = nsIDocShellLoadInfo_SetReferrer(load_info, (nsIURI*)&referrer_uri->nsIFileURL_iface);
320 assert(nsres == NS_OK);
321 nsIFileURL_Release(&referrer_uri->nsIFileURL_iface);
325 uri->channel_bsc = channelbsc;
326 doc = window->base.inner_window->doc;
327 doc->skip_mutation_notif = TRUE;
328 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, load_info, flags, FALSE);
329 if(doc == window->base.inner_window->doc)
330 doc->skip_mutation_notif = FALSE;
331 uri->channel_bsc = NULL;
332 nsIDocShell_Release(doc_shell);
333 nsIDocShellLoadInfo_Release(load_info);
334 if(NS_FAILED(nsres)) {
335 WARN("LoadURI failed: %08x\n", nsres);
336 return E_FAIL;
339 return S_OK;
342 static inline BOOL is_http_channel(nsChannel *This)
344 return This->uri->scheme == URL_SCHEME_HTTP || This->uri->scheme == URL_SCHEME_HTTPS;
347 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
349 http_header_t *iter;
351 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
352 if(!wcsnicmp(iter->header, name, len) && !iter->header[len])
353 return iter;
356 return NULL;
359 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
360 nsACString *_retval)
362 const char *header_namea;
363 http_header_t *header;
364 WCHAR *header_name;
365 char *data;
367 nsACString_GetData(header_name_str, &header_namea);
368 header_name = heap_strdupAtoW(header_namea);
369 if(!header_name)
370 return NS_ERROR_UNEXPECTED;
372 header = find_http_header(headers, header_name, lstrlenW(header_name));
373 heap_free(header_name);
374 if(!header)
375 return NS_ERROR_NOT_AVAILABLE;
377 data = heap_strdupWtoA(header->data);
378 if(!data)
379 return NS_ERROR_UNEXPECTED;
381 TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
382 nsACString_SetData(_retval, data);
383 heap_free(data);
384 return NS_OK;
387 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
388 const WCHAR *value, int value_len)
390 http_header_t *header;
392 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
394 header = find_http_header(headers, name, name_len);
395 if(header) {
396 WCHAR *new_data;
398 new_data = heap_strndupW(value, value_len);
399 if(!new_data)
400 return E_OUTOFMEMORY;
402 heap_free(header->data);
403 header->data = new_data;
404 }else {
405 header = heap_alloc(sizeof(http_header_t));
406 if(!header)
407 return E_OUTOFMEMORY;
409 header->header = heap_strndupW(name, name_len);
410 header->data = heap_strndupW(value, value_len);
411 if(!header->header || !header->data) {
412 heap_free(header->header);
413 heap_free(header->data);
414 heap_free(header);
415 return E_OUTOFMEMORY;
418 list_add_tail(headers, &header->entry);
421 return S_OK;
424 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
425 const nsACString *value_str)
427 const char *namea, *valuea;
428 WCHAR *name, *value;
429 HRESULT hres;
431 nsACString_GetData(name_str, &namea);
432 name = heap_strdupAtoW(namea);
433 if(!name)
434 return NS_ERROR_UNEXPECTED;
436 nsACString_GetData(value_str, &valuea);
437 value = heap_strdupAtoW(valuea);
438 if(!value) {
439 heap_free(name);
440 return NS_ERROR_UNEXPECTED;
443 hres = set_http_header(headers, name, lstrlenW(name), value, lstrlenW(value));
445 heap_free(name);
446 heap_free(value);
447 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
450 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
452 nsACString header_str, value_str;
453 char *header, *value;
454 http_header_t *iter;
455 nsresult nsres;
457 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
458 header = heap_strdupWtoA(iter->header);
459 if(!header)
460 return NS_ERROR_OUT_OF_MEMORY;
462 value = heap_strdupWtoA(iter->data);
463 if(!value) {
464 heap_free(header);
465 return NS_ERROR_OUT_OF_MEMORY;
468 nsACString_InitDepend(&header_str, header);
469 nsACString_InitDepend(&value_str, value);
470 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
471 nsACString_Finish(&header_str);
472 nsACString_Finish(&value_str);
473 heap_free(header);
474 heap_free(value);
475 if(NS_FAILED(nsres))
476 break;
479 return NS_OK;
482 static void free_http_headers(struct list *list)
484 http_header_t *iter, *iter_next;
486 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
487 list_remove(&iter->entry);
488 heap_free(iter->header);
489 heap_free(iter->data);
490 heap_free(iter);
494 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
496 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
499 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
501 nsChannel *This = impl_from_nsIHttpChannel(iface);
503 if(IsEqualGUID(&IID_nsISupports, riid)) {
504 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
505 *result = &This->nsIHttpChannel_iface;
506 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
507 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
508 *result = &This->nsIHttpChannel_iface;
509 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
510 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
511 *result = &This->nsIHttpChannel_iface;
512 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
513 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
514 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
515 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
516 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
517 *result = &This->nsIUploadChannel_iface;
518 }else if(IsEqualGUID(&IID_nsIFormPOSTActionChannel, riid)) {
519 TRACE("(%p)->(IID_nsIFormPOSTActionChannel %p)\n", This, result);
520 *result = &This->nsIUploadChannel_iface;
521 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
522 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
523 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
524 }else if(IsEqualGUID(&IID_nsICacheInfoChannel, riid)) {
525 TRACE("(%p)->(IID_nsICacheInfoChannel %p)\n", This, result);
526 *result = is_http_channel(This) ? &This->nsICacheInfoChannel_iface : NULL;
527 }else {
528 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
529 *result = NULL;
532 if(*result) {
533 nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
534 return NS_OK;
537 return NS_NOINTERFACE;
540 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
542 nsChannel *This = impl_from_nsIHttpChannel(iface);
543 nsrefcnt ref = InterlockedIncrement(&This->ref);
545 TRACE("(%p) ref=%d\n", This, ref);
547 return ref;
550 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
552 nsChannel *This = impl_from_nsIHttpChannel(iface);
553 LONG ref = InterlockedDecrement(&This->ref);
555 if(!ref) {
556 nsIFileURL_Release(&This->uri->nsIFileURL_iface);
557 if(This->owner)
558 nsISupports_Release(This->owner);
559 if(This->post_data_stream)
560 nsIInputStream_Release(This->post_data_stream);
561 if(This->load_group)
562 nsILoadGroup_Release(This->load_group);
563 if(This->notif_callback)
564 nsIInterfaceRequestor_Release(This->notif_callback);
565 if(This->original_uri)
566 nsIURI_Release(This->original_uri);
567 if(This->referrer)
568 nsIURI_Release(This->referrer);
570 free_http_headers(&This->response_headers);
571 free_http_headers(&This->request_headers);
573 heap_free(This->content_type);
574 heap_free(This->charset);
575 heap_free(This);
578 return ref;
581 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
583 nsChannel *This = impl_from_nsIHttpChannel(iface);
585 TRACE("(%p)->(%p)\n", This, aName);
587 return nsIFileURL_GetSpec(&This->uri->nsIFileURL_iface, aName);
590 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, cpp_bool *_retval)
592 nsChannel *This = impl_from_nsIHttpChannel(iface);
594 FIXME("(%p)->(%p)\n", This, _retval);
596 return NS_ERROR_NOT_IMPLEMENTED;
599 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
601 nsChannel *This = impl_from_nsIHttpChannel(iface);
603 WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
605 return *aStatus = NS_OK;
608 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
610 nsChannel *This = impl_from_nsIHttpChannel(iface);
612 TRACE("(%p)->(%08x)\n", This, aStatus);
614 if(This->binding && This->binding->bsc.binding)
615 IBinding_Abort(This->binding->bsc.binding);
616 else
617 WARN("No binding to cancel\n");
618 return NS_OK;
621 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
623 nsChannel *This = impl_from_nsIHttpChannel(iface);
625 FIXME("(%p)\n", This);
627 return NS_ERROR_NOT_IMPLEMENTED;
630 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
632 nsChannel *This = impl_from_nsIHttpChannel(iface);
634 FIXME("(%p)\n", This);
636 return NS_ERROR_NOT_IMPLEMENTED;
639 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
641 nsChannel *This = impl_from_nsIHttpChannel(iface);
643 TRACE("(%p)->(%p)\n", This, aLoadGroup);
645 if(This->load_group)
646 nsILoadGroup_AddRef(This->load_group);
648 *aLoadGroup = This->load_group;
649 return NS_OK;
652 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
654 nsChannel *This = impl_from_nsIHttpChannel(iface);
656 TRACE("(%p)->(%p)\n", This, aLoadGroup);
658 if(This->load_group)
659 nsILoadGroup_Release(This->load_group);
660 if(aLoadGroup)
661 nsILoadGroup_AddRef(aLoadGroup);
662 This->load_group = aLoadGroup;
664 return NS_OK;
667 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
669 nsChannel *This = impl_from_nsIHttpChannel(iface);
671 TRACE("(%p)->(%p)\n", This, aLoadFlags);
673 *aLoadFlags = This->load_flags;
674 return NS_OK;
677 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
679 nsChannel *This = impl_from_nsIHttpChannel(iface);
681 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
683 This->load_flags = aLoadFlags;
684 return NS_OK;
687 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
689 nsChannel *This = impl_from_nsIHttpChannel(iface);
691 TRACE("(%p)->(%p)\n", This, aOriginalURI);
693 if(This->original_uri)
694 nsIURI_AddRef(This->original_uri);
696 *aOriginalURI = This->original_uri;
697 return NS_OK;
700 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
702 nsChannel *This = impl_from_nsIHttpChannel(iface);
704 TRACE("(%p)->(%p)\n", This, aOriginalURI);
706 if(This->original_uri)
707 nsIURI_Release(This->original_uri);
709 nsIURI_AddRef(aOriginalURI);
710 This->original_uri = aOriginalURI;
711 return NS_OK;
714 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
716 nsChannel *This = impl_from_nsIHttpChannel(iface);
718 TRACE("(%p)->(%p)\n", This, aURI);
720 nsIFileURL_AddRef(&This->uri->nsIFileURL_iface);
721 *aURI = (nsIURI*)&This->uri->nsIFileURL_iface;
723 return NS_OK;
726 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
728 nsChannel *This = impl_from_nsIHttpChannel(iface);
730 TRACE("(%p)->(%p)\n", This, aOwner);
732 if(This->owner)
733 nsISupports_AddRef(This->owner);
734 *aOwner = This->owner;
736 return NS_OK;
739 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
741 nsChannel *This = impl_from_nsIHttpChannel(iface);
743 TRACE("(%p)->(%p)\n", This, aOwner);
745 if(aOwner)
746 nsISupports_AddRef(aOwner);
747 if(This->owner)
748 nsISupports_Release(This->owner);
749 This->owner = aOwner;
751 return NS_OK;
754 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
755 nsIInterfaceRequestor **aNotificationCallbacks)
757 nsChannel *This = impl_from_nsIHttpChannel(iface);
759 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
761 if(This->notif_callback)
762 nsIInterfaceRequestor_AddRef(This->notif_callback);
763 *aNotificationCallbacks = This->notif_callback;
765 return NS_OK;
768 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
769 nsIInterfaceRequestor *aNotificationCallbacks)
771 nsChannel *This = impl_from_nsIHttpChannel(iface);
773 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
775 if(This->notif_callback)
776 nsIInterfaceRequestor_Release(This->notif_callback);
777 if(aNotificationCallbacks)
778 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
780 This->notif_callback = aNotificationCallbacks;
782 return NS_OK;
785 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
787 nsChannel *This = impl_from_nsIHttpChannel(iface);
789 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
791 return NS_ERROR_NOT_IMPLEMENTED;
794 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
796 nsChannel *This = impl_from_nsIHttpChannel(iface);
798 TRACE("(%p)->(%p)\n", This, aContentType);
800 if(This->content_type) {
801 nsACString_SetData(aContentType, This->content_type);
802 return S_OK;
805 if(This->load_flags & LOAD_DOCUMENT_URI) {
806 WARN("Document channel with no MIME set. Assuming text/html\n");
807 nsACString_SetData(aContentType, "text/html");
808 return S_OK;
811 WARN("unknown type\n");
812 return NS_ERROR_FAILURE;
815 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
816 const nsACString *aContentType)
818 nsChannel *This = impl_from_nsIHttpChannel(iface);
819 const char *content_type;
821 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
823 nsACString_GetData(aContentType, &content_type);
824 heap_free(This->content_type);
825 This->content_type = heap_strdupA(content_type);
827 return NS_OK;
830 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
831 nsACString *aContentCharset)
833 nsChannel *This = impl_from_nsIHttpChannel(iface);
835 TRACE("(%p)->(%p)\n", This, aContentCharset);
837 if(This->charset) {
838 nsACString_SetData(aContentCharset, This->charset);
839 return NS_OK;
842 nsACString_SetData(aContentCharset, "");
843 return NS_OK;
846 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
847 const nsACString *aContentCharset)
849 nsChannel *This = impl_from_nsIHttpChannel(iface);
850 const char *data;
851 char *charset;
853 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
855 nsACString_GetData(aContentCharset, &data);
856 charset = heap_strdupA(data);
857 if(!charset)
858 return NS_ERROR_OUT_OF_MEMORY;
860 heap_free(This->charset);
861 This->charset = charset;
862 return NS_OK;
865 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, INT64 *aContentLength)
867 nsChannel *This = impl_from_nsIHttpChannel(iface);
869 FIXME("(%p)->(%p)\n", This, aContentLength);
871 return NS_ERROR_NOT_IMPLEMENTED;
874 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, INT64 aContentLength)
876 nsChannel *This = impl_from_nsIHttpChannel(iface);
878 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aContentLength));
880 return NS_ERROR_NOT_IMPLEMENTED;
883 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
885 nsChannel *This = impl_from_nsIHttpChannel(iface);
887 FIXME("(%p)->(%p)\n", This, _retval);
889 return NS_ERROR_NOT_IMPLEMENTED;
892 static nsresult NSAPI nsChannel_Open2(nsIHttpChannel *iface, nsIInputStream **_retval)
894 nsChannel *This = impl_from_nsIHttpChannel(iface);
896 FIXME("(%p)->(%p)\n", This, _retval);
898 return NS_ERROR_NOT_IMPLEMENTED;
901 static HTMLOuterWindow *get_channel_window(nsChannel *This)
903 nsIWebProgress *web_progress = NULL;
904 mozIDOMWindowProxy *mozwindow;
905 HTMLOuterWindow *window;
906 nsresult nsres;
908 if(This->load_group) {
909 nsIRequestObserver *req_observer;
911 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
912 if(NS_FAILED(nsres)) {
913 ERR("GetGroupObserver failed: %08x\n", nsres);
914 return NULL;
917 if(req_observer) {
918 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
919 nsIRequestObserver_Release(req_observer);
920 if(NS_FAILED(nsres)) {
921 ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
922 return NULL;
927 if(!web_progress && This->notif_callback) {
928 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
929 if(NS_FAILED(nsres)) {
930 ERR("GetInterface(IID_nsIWebProgress failed: %08x\n", nsres);
931 return NULL;
935 if(!web_progress) {
936 ERR("Could not find nsIWebProgress\n");
937 return NULL;
940 nsres = nsIWebProgress_GetDOMWindow(web_progress, &mozwindow);
941 nsIWebProgress_Release(web_progress);
942 if(NS_FAILED(nsres) || !mozwindow) {
943 ERR("GetDOMWindow failed: %08x\n", nsres);
944 return NULL;
947 window = mozwindow_to_window(mozwindow);
948 mozIDOMWindowProxy_Release(mozwindow);
950 if(window)
951 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
952 else
953 FIXME("NULL window for %p\n", mozwindow);
954 return window;
957 typedef struct {
958 task_t header;
959 HTMLInnerWindow *window;
960 nsChannelBSC *bscallback;
961 } start_binding_task_t;
963 static void start_binding_proc(task_t *_task)
965 start_binding_task_t *task = (start_binding_task_t*)_task;
967 start_binding(task->window, (BSCallback*)task->bscallback, NULL);
970 static void start_binding_task_destr(task_t *_task)
972 start_binding_task_t *task = (start_binding_task_t*)_task;
974 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
975 heap_free(task);
978 static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
979 nsISupports *context)
981 nsChannelBSC *bscallback;
982 IMoniker *mon = NULL;
983 HRESULT hres;
985 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
986 if(FAILED(hres)) {
987 WARN("CreateURLMoniker failed: %08x\n", hres);
988 return NS_ERROR_UNEXPECTED;
991 if(is_doc_channel)
992 set_current_mon(window, mon, BINDING_NAVIGATED);
994 hres = create_channelbsc(mon, NULL, NULL, 0, is_doc_channel, &bscallback);
995 IMoniker_Release(mon);
996 if(FAILED(hres))
997 return NS_ERROR_UNEXPECTED;
999 channelbsc_set_channel(bscallback, This, listener, context);
1001 if(is_doc_channel) {
1002 hres = create_pending_window(window, bscallback);
1003 if(SUCCEEDED(hres))
1004 async_start_doc_binding(window, window->pending_window);
1005 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1006 if(FAILED(hres))
1007 return NS_ERROR_UNEXPECTED;
1008 }else {
1009 start_binding_task_t *task;
1011 task = heap_alloc(sizeof(start_binding_task_t));
1012 if(!task) {
1013 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1014 return NS_ERROR_OUT_OF_MEMORY;
1017 task->window = window->base.inner_window;
1018 task->bscallback = bscallback;
1019 hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic);
1020 if(FAILED(hres))
1021 return NS_ERROR_OUT_OF_MEMORY;
1024 return NS_OK;
1027 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
1028 nsISupports *aContext)
1030 nsChannel *This = impl_from_nsIHttpChannel(iface);
1031 HTMLOuterWindow *window = NULL;
1032 BOOL is_document_channel;
1033 BOOL cancel = FALSE;
1034 nsresult nsres = NS_OK;
1036 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1038 if(!ensure_uri(This->uri))
1039 return NS_ERROR_FAILURE;
1041 if(TRACE_ON(mshtml)) {
1042 HRESULT hres;
1043 BSTR uri_str;
1045 hres = IUri_GetDisplayUri(This->uri->uri, &uri_str);
1046 if(SUCCEEDED(hres)) {
1047 TRACE("opening %s\n", debugstr_w(uri_str));
1048 SysFreeString(uri_str);
1049 }else {
1050 WARN("GetDisplayUri failed: %08x\n", hres);
1054 window = get_channel_window(This);
1055 if(!window) {
1056 ERR("window = NULL\n");
1057 return NS_ERROR_UNEXPECTED;
1060 is_document_channel = !!(This->load_flags & LOAD_DOCUMENT_URI);
1062 if(is_document_channel) {
1063 if(This->uri->channel_bsc) {
1064 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1065 cancel = TRUE;
1068 if(is_main_content_window(window)) {
1069 if(!This->uri->channel_bsc) {
1070 /* top window navigation initiated by Gecko */
1071 nsres = before_async_open(This, window->browser, &cancel);
1072 if(NS_SUCCEEDED(nsres) && cancel) {
1073 TRACE("canceled\n");
1074 nsres = NS_BINDING_ABORTED;
1076 }else if(window->browser->doc->mime) {
1077 heap_free(This->content_type);
1078 This->content_type = heap_strdupWtoA(window->browser->doc->mime);
1083 if(!cancel)
1084 nsres = async_open(This, window, is_document_channel, aListener, aContext);
1086 if(NS_SUCCEEDED(nsres) && This->load_group) {
1087 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1088 aContext);
1089 if(NS_FAILED(nsres))
1090 ERR("AddRequest failed: %08x\n", nsres);
1093 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
1094 return nsres;
1097 static nsresult NSAPI nsChannel_AsyncOpen2(nsIHttpChannel *iface, nsIStreamListener *aListener)
1099 nsChannel *This = impl_from_nsIHttpChannel(iface);
1100 FIXME("(%p)->(%p)\n", This, aListener);
1101 return nsIHttpChannel_AsyncOpen(&This->nsIHttpChannel_iface, aListener, NULL);
1104 static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition)
1106 nsChannel *This = impl_from_nsIHttpChannel(iface);
1107 TRACE("(%p)->(%p) unimplemented\n", This, aContentDisposition);
1108 return NS_ERROR_NOT_IMPLEMENTED;
1111 static nsresult NSAPI nsChannel_SetContentDisposition(nsIHttpChannel *iface, UINT32 aContentDisposition)
1113 nsChannel *This = impl_from_nsIHttpChannel(iface);
1114 FIXME("(%p)->(%u)\n", This, aContentDisposition);
1115 return NS_ERROR_NOT_IMPLEMENTED;
1118 static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
1120 nsChannel *This = impl_from_nsIHttpChannel(iface);
1121 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1122 return NS_ERROR_NOT_IMPLEMENTED;
1125 static nsresult NSAPI nsChannel_SetContentDispositionFilename(nsIHttpChannel *iface, const nsAString *aContentDispositionFilename)
1127 nsChannel *This = impl_from_nsIHttpChannel(iface);
1128 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1129 return NS_ERROR_NOT_IMPLEMENTED;
1132 static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
1134 nsChannel *This = impl_from_nsIHttpChannel(iface);
1135 TRACE("(%p)->(%p) unimplemented\n", This, aContentDispositionHeader);
1136 return NS_ERROR_NOT_IMPLEMENTED;
1139 static nsresult NSAPI nsChannel_GetLoadInfo(nsIHttpChannel *iface, nsILoadInfo **aLoadInfo)
1141 nsChannel *This = impl_from_nsIHttpChannel(iface);
1143 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1145 if(This->load_info)
1146 nsISupports_AddRef(This->load_info);
1147 *aLoadInfo = This->load_info;
1148 return NS_OK;
1151 static nsresult NSAPI nsChannel_SetLoadInfo(nsIHttpChannel *iface, nsILoadInfo *aLoadInfo)
1153 nsChannel *This = impl_from_nsIHttpChannel(iface);
1155 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1157 if(This->load_info)
1158 nsISupports_Release(This->load_info);
1159 This->load_info = aLoadInfo;
1160 if(This->load_info)
1161 nsISupports_AddRef(This->load_info);
1162 return NS_OK;
1165 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1167 nsChannel *This = impl_from_nsIHttpChannel(iface);
1169 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1171 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1172 return NS_OK;
1175 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1176 const nsACString *aRequestMethod)
1178 nsChannel *This = impl_from_nsIHttpChannel(iface);
1179 const char *method;
1180 unsigned i;
1182 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1184 nsACString_GetData(aRequestMethod, &method);
1185 for(i=0; i < ARRAY_SIZE(request_method_strings); i++) {
1186 if(!stricmp(method, request_method_strings[i])) {
1187 This->request_method = i;
1188 return NS_OK;
1192 ERR("Invalid method %s\n", debugstr_a(method));
1193 return NS_ERROR_UNEXPECTED;
1196 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1198 nsChannel *This = impl_from_nsIHttpChannel(iface);
1200 TRACE("(%p)->(%p)\n", This, aReferrer);
1202 if(This->referrer)
1203 nsIURI_AddRef(This->referrer);
1204 *aReferrer = This->referrer;
1205 return NS_OK;
1208 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1210 nsChannel *This = impl_from_nsIHttpChannel(iface);
1212 TRACE("(%p)->(%p)\n", This, aReferrer);
1214 return nsIHttpChannel_SetReferrerWithPolicy(&This->nsIHttpChannel_iface, aReferrer, 0);
1217 static nsresult NSAPI nsChannel_GetReferrerPolicy(nsIHttpChannel *iface, UINT32 *aReferrerPolicy)
1219 nsChannel *This = impl_from_nsIHttpChannel(iface);
1220 TRACE("(%p)->(%p) unimplemented\n", This, aReferrerPolicy);
1221 return NS_ERROR_NOT_IMPLEMENTED;
1224 static nsresult NSAPI nsChannel_SetReferrerWithPolicy(nsIHttpChannel *iface, nsIURI *aReferrer, UINT32 aReferrerPolicy)
1226 nsChannel *This = impl_from_nsIHttpChannel(iface);
1227 DWORD channel_scheme, referrer_scheme;
1228 nsWineURI *referrer;
1229 BSTR referrer_uri;
1230 nsresult nsres;
1231 HRESULT hres;
1233 static const WCHAR refererW[] = {'R','e','f','e','r','e','r'};
1235 TRACE("(%p)->(%p %d)\n", This, aReferrer, aReferrerPolicy);
1237 if(aReferrerPolicy)
1238 FIXME("refferer policy %d not implemented\n", aReferrerPolicy);
1240 if(This->referrer) {
1241 nsIURI_Release(This->referrer);
1242 This->referrer = NULL;
1244 if(!aReferrer)
1245 return NS_OK;
1247 nsres = nsIURI_QueryInterface(aReferrer, &IID_nsWineURI, (void**)&referrer);
1248 if(NS_FAILED(nsres))
1249 return NS_OK;
1251 if(!ensure_uri(referrer)) {
1252 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1253 return NS_ERROR_UNEXPECTED;
1256 if(!ensure_uri(This->uri) || FAILED(IUri_GetScheme(This->uri->uri, &channel_scheme)))
1257 channel_scheme = INTERNET_SCHEME_UNKNOWN;
1259 if(FAILED(IUri_GetScheme(referrer->uri, &referrer_scheme)))
1260 referrer_scheme = INTERNET_SCHEME_UNKNOWN;
1262 if(referrer_scheme == INTERNET_SCHEME_HTTPS && channel_scheme != INTERNET_SCHEME_HTTPS) {
1263 TRACE("Ignoring https referrer on non-https channel\n");
1264 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1265 return NS_OK;
1268 hres = IUri_GetDisplayUri(referrer->uri, &referrer_uri);
1269 if(SUCCEEDED(hres)) {
1270 set_http_header(&This->request_headers, refererW, ARRAY_SIZE(refererW), referrer_uri, SysStringLen(referrer_uri));
1271 SysFreeString(referrer_uri);
1274 This->referrer = (nsIURI*)&referrer->nsIFileURL_iface;
1275 return NS_OK;
1278 static nsresult NSAPI nsHttpChannel_GetProtocolVersion(nsIHttpChannel *iface, nsACString *aProtocolVersion)
1280 nsChannel *This = impl_from_nsIHttpChannel(iface);
1281 FIXME("(%p)->(%p)\n", This, aProtocolVersion);
1282 return NS_ERROR_NOT_IMPLEMENTED;
1285 static nsresult NSAPI nsHttpChannel_GetTransferSize(nsIHttpChannel *iface, UINT64 *aTransferSize)
1287 nsChannel *This = impl_from_nsIHttpChannel(iface);
1288 FIXME("(%p)->(%p)\n", This, aTransferSize);
1289 return NS_ERROR_NOT_IMPLEMENTED;
1292 static nsresult NSAPI nsHttpChannel_GetDecodedBodySize(nsIHttpChannel *iface, UINT64 *aDecodedBodySize)
1294 nsChannel *This = impl_from_nsIHttpChannel(iface);
1295 FIXME("(%p)->(%p)\n", This, aDecodedBodySize);
1296 return NS_ERROR_NOT_IMPLEMENTED;
1299 static nsresult NSAPI nsHttpChannel_GetEncodedBodySize(nsIHttpChannel *iface, UINT64 *aEncodedBodySize)
1301 nsChannel *This = impl_from_nsIHttpChannel(iface);
1302 FIXME("(%p)->(%p)\n", This, aEncodedBodySize);
1303 return NS_ERROR_NOT_IMPLEMENTED;
1306 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1307 const nsACString *aHeader, nsACString *_retval)
1309 nsChannel *This = impl_from_nsIHttpChannel(iface);
1311 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1313 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1316 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1317 const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
1319 nsChannel *This = impl_from_nsIHttpChannel(iface);
1321 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1323 if(aMerge)
1324 FIXME("aMerge not supported\n");
1326 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1329 static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader)
1331 nsChannel *This = impl_from_nsIHttpChannel(iface);
1332 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader));
1333 return NS_ERROR_NOT_IMPLEMENTED;
1336 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1337 nsIHttpHeaderVisitor *aVisitor)
1339 nsChannel *This = impl_from_nsIHttpChannel(iface);
1341 FIXME("(%p)->(%p)\n", This, aVisitor);
1343 return NS_ERROR_NOT_IMPLEMENTED;
1346 static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor)
1348 nsChannel *This = impl_from_nsIHttpChannel(iface);
1349 FIXME("(%p)->(%p)\n", This, aVisitor);
1350 return NS_ERROR_NOT_IMPLEMENTED;
1353 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
1355 nsChannel *This = impl_from_nsIHttpChannel(iface);
1357 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1359 return NS_ERROR_NOT_IMPLEMENTED;
1362 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
1364 nsChannel *This = impl_from_nsIHttpChannel(iface);
1366 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1368 return NS_ERROR_NOT_IMPLEMENTED;
1371 static nsresult NSAPI nsChannel_GetAllowTLS(nsIHttpChannel *iface, cpp_bool *aAllowTLS)
1373 nsChannel *This = impl_from_nsIHttpChannel(iface);
1374 FIXME("(%p)->(%p)\n", This, aAllowTLS);
1375 return NS_ERROR_NOT_IMPLEMENTED;
1378 static nsresult NSAPI nsChannel_SetAllowTLS(nsIHttpChannel *iface, cpp_bool aAllowTLS)
1380 nsChannel *This = impl_from_nsIHttpChannel(iface);
1381 FIXME("(%p)->(%x)\n", This, aAllowTLS);
1382 return NS_ERROR_NOT_IMPLEMENTED;
1385 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
1387 nsChannel *This = impl_from_nsIHttpChannel(iface);
1389 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1391 return NS_ERROR_NOT_IMPLEMENTED;
1394 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
1396 nsChannel *This = impl_from_nsIHttpChannel(iface);
1398 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1400 return NS_ERROR_NOT_IMPLEMENTED;
1403 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
1405 nsChannel *This = impl_from_nsIHttpChannel(iface);
1407 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1409 if(This->response_status) {
1410 *aResponseStatus = This->response_status;
1411 return NS_OK;
1414 WARN("No response status\n");
1415 return NS_ERROR_UNEXPECTED;
1418 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1419 nsACString *aResponseStatusText)
1421 nsChannel *This = impl_from_nsIHttpChannel(iface);
1423 TRACE("(%p)->(%p)\n", This, aResponseStatusText);
1425 nsACString_SetData(aResponseStatusText, This->response_status_text);
1426 return NS_OK;
1429 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1430 cpp_bool *aRequestSucceeded)
1432 nsChannel *This = impl_from_nsIHttpChannel(iface);
1434 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1436 if(!This->response_status)
1437 return NS_ERROR_NOT_AVAILABLE;
1439 *aRequestSucceeded = This->response_status/100 == 2;
1441 return NS_OK;
1444 static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel)
1446 nsChannel *This = impl_from_nsIHttpChannel(iface);
1447 FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel);
1448 return NS_ERROR_NOT_IMPLEMENTED;
1451 static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel)
1453 nsChannel *This = impl_from_nsIHttpChannel(iface);
1454 FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel);
1455 return NS_ERROR_NOT_IMPLEMENTED;
1458 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1459 const nsACString *header, nsACString *_retval)
1461 nsChannel *This = impl_from_nsIHttpChannel(iface);
1463 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1465 return get_channel_http_header(&This->response_headers, header, _retval);
1468 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1469 const nsACString *header, const nsACString *value, cpp_bool merge)
1471 nsChannel *This = impl_from_nsIHttpChannel(iface);
1473 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1475 return NS_ERROR_NOT_IMPLEMENTED;
1478 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1479 nsIHttpHeaderVisitor *aVisitor)
1481 nsChannel *This = impl_from_nsIHttpChannel(iface);
1483 TRACE("(%p)->(%p)\n", This, aVisitor);
1485 return visit_http_headers(&This->response_headers, aVisitor);
1488 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1490 nsChannel *This = impl_from_nsIHttpChannel(iface);
1491 http_header_t *header;
1493 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1495 TRACE("(%p)->(%p)\n", This, _retval);
1497 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1498 *_retval = header && !wcsicmp(header->data, L"no-store");
1499 return NS_OK;
1502 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1504 nsChannel *This = impl_from_nsIHttpChannel(iface);
1506 FIXME("(%p)->(%p)\n", This, _retval);
1508 return NS_ERROR_NOT_IMPLEMENTED;
1511 static nsresult NSAPI nsChannel_IsPrivateResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1513 nsChannel *This = impl_from_nsIHttpChannel(iface);
1515 FIXME("(%p)->(%p)\n", This, _retval);
1517 return NS_ERROR_NOT_IMPLEMENTED;
1520 static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aTargetURI)
1522 nsChannel *This = impl_from_nsIHttpChannel(iface);
1524 FIXME("(%p)->(%p)\n", This, aTargetURI);
1526 return NS_ERROR_NOT_IMPLEMENTED;
1529 static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID)
1531 nsChannel *This = impl_from_nsIHttpChannel(iface);
1533 FIXME("(%p)->(%p)\n", This, aSchedulingContextID);
1535 return NS_ERROR_NOT_IMPLEMENTED;
1538 static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID)
1540 nsChannel *This = impl_from_nsIHttpChannel(iface);
1542 FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID));
1544 return NS_ERROR_NOT_IMPLEMENTED;
1547 static const nsIHttpChannelVtbl nsChannelVtbl = {
1548 nsChannel_QueryInterface,
1549 nsChannel_AddRef,
1550 nsChannel_Release,
1551 nsChannel_GetName,
1552 nsChannel_IsPending,
1553 nsChannel_GetStatus,
1554 nsChannel_Cancel,
1555 nsChannel_Suspend,
1556 nsChannel_Resume,
1557 nsChannel_GetLoadGroup,
1558 nsChannel_SetLoadGroup,
1559 nsChannel_GetLoadFlags,
1560 nsChannel_SetLoadFlags,
1561 nsChannel_GetOriginalURI,
1562 nsChannel_SetOriginalURI,
1563 nsChannel_GetURI,
1564 nsChannel_GetOwner,
1565 nsChannel_SetOwner,
1566 nsChannel_GetNotificationCallbacks,
1567 nsChannel_SetNotificationCallbacks,
1568 nsChannel_GetSecurityInfo,
1569 nsChannel_GetContentType,
1570 nsChannel_SetContentType,
1571 nsChannel_GetContentCharset,
1572 nsChannel_SetContentCharset,
1573 nsChannel_GetContentLength,
1574 nsChannel_SetContentLength,
1575 nsChannel_Open,
1576 nsChannel_Open2,
1577 nsChannel_AsyncOpen,
1578 nsChannel_AsyncOpen2,
1579 nsChannel_GetContentDisposition,
1580 nsChannel_SetContentDisposition,
1581 nsChannel_GetContentDispositionFilename,
1582 nsChannel_SetContentDispositionFilename,
1583 nsChannel_GetContentDispositionHeader,
1584 nsChannel_GetLoadInfo,
1585 nsChannel_SetLoadInfo,
1586 nsChannel_GetRequestMethod,
1587 nsChannel_SetRequestMethod,
1588 nsChannel_GetReferrer,
1589 nsChannel_SetReferrer,
1590 nsChannel_GetReferrerPolicy,
1591 nsChannel_SetReferrerWithPolicy,
1592 nsHttpChannel_GetProtocolVersion,
1593 nsHttpChannel_GetTransferSize,
1594 nsHttpChannel_GetDecodedBodySize,
1595 nsHttpChannel_GetEncodedBodySize,
1596 nsChannel_GetRequestHeader,
1597 nsChannel_SetRequestHeader,
1598 nsChannel_SetEmptyRequestHeader,
1599 nsChannel_VisitRequestHeaders,
1600 nsChannel_VisitNonDefaultRequestHeaders,
1601 nsChannel_GetAllowPipelining,
1602 nsChannel_SetAllowPipelining,
1603 nsChannel_GetAllowTLS,
1604 nsChannel_SetAllowTLS,
1605 nsChannel_GetRedirectionLimit,
1606 nsChannel_SetRedirectionLimit,
1607 nsChannel_GetResponseStatus,
1608 nsChannel_GetResponseStatusText,
1609 nsChannel_GetRequestSucceeded,
1610 nsChannel_GetIsMainDocumentChannel,
1611 nsChannel_SetIsMainDocumentChannel,
1612 nsChannel_GetResponseHeader,
1613 nsChannel_SetResponseHeader,
1614 nsChannel_VisitResponseHeaders,
1615 nsChannel_IsNoStoreResponse,
1616 nsChannel_IsNoCacheResponse,
1617 nsChannel_IsPrivateResponse,
1618 nsChannel_RedirectTo,
1619 nsHttpChannel_GetSchedulingContextID,
1620 nsHttpChannel_SetSchedulingContextID
1623 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1625 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1628 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1629 void **result)
1631 nsChannel *This = impl_from_nsIUploadChannel(iface);
1632 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1635 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1637 nsChannel *This = impl_from_nsIUploadChannel(iface);
1638 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1641 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1643 nsChannel *This = impl_from_nsIUploadChannel(iface);
1644 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1647 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1648 nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
1650 nsChannel *This = impl_from_nsIUploadChannel(iface);
1651 const char *content_type;
1653 static const WCHAR content_typeW[] =
1654 {'C','o','n','t','e','n','t','-','T','y','p','e'};
1656 TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));
1658 This->post_data_contains_headers = TRUE;
1660 if(aContentType) {
1661 nsACString_GetData(aContentType, &content_type);
1662 if(*content_type) {
1663 WCHAR *ct;
1665 ct = heap_strdupAtoW(content_type);
1666 if(!ct)
1667 return NS_ERROR_UNEXPECTED;
1669 set_http_header(&This->request_headers, content_typeW, ARRAY_SIZE(content_typeW), ct, lstrlenW(ct));
1670 heap_free(ct);
1671 This->post_data_contains_headers = FALSE;
1675 if(aContentLength != -1)
1676 FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));
1678 if(This->post_data_stream)
1679 nsIInputStream_Release(This->post_data_stream);
1680 This->post_data_stream = aStream;
1681 if(aStream)
1682 nsIInputStream_AddRef(aStream);
1684 This->request_method = METHOD_POST;
1685 return NS_OK;
1688 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1689 nsIInputStream **aUploadStream)
1691 nsChannel *This = impl_from_nsIUploadChannel(iface);
1693 TRACE("(%p)->(%p)\n", This, aUploadStream);
1695 if(This->post_data_stream)
1696 nsIInputStream_AddRef(This->post_data_stream);
1698 *aUploadStream = This->post_data_stream;
1699 return NS_OK;
1702 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1703 nsUploadChannel_QueryInterface,
1704 nsUploadChannel_AddRef,
1705 nsUploadChannel_Release,
1706 nsUploadChannel_SetUploadStream,
1707 nsUploadChannel_GetUploadStream
1710 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1712 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1715 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1716 void **result)
1718 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1719 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1722 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1724 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1725 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1728 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1730 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1731 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1734 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1736 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1738 FIXME("(%p)->()\n", This);
1740 return NS_ERROR_NOT_IMPLEMENTED;
1743 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1745 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1747 TRACE("(%p)->() unimplemented\n", This);
1749 return NS_ERROR_NOT_IMPLEMENTED;
1752 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1754 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1756 FIXME("(%p)->()\n", This);
1758 return NS_ERROR_NOT_IMPLEMENTED;
1761 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1763 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1765 FIXME("(%p)->()\n", This);
1767 return NS_ERROR_NOT_IMPLEMENTED;
1770 static nsresult NSAPI nsHttpChannelInternal_TakeAllSecurityMessages(nsIHttpChannelInternal *iface, void *aMessages)
1772 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1774 TRACE("(%p)->(%p) unimplemented\n", This, aMessages);
1776 return NS_ERROR_NOT_IMPLEMENTED;
1779 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1781 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1783 FIXME("(%p)->()\n", This);
1785 return NS_ERROR_NOT_IMPLEMENTED;
1788 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1790 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1792 FIXME("(%p)->()\n", This);
1794 return NS_ERROR_NOT_IMPLEMENTED;
1797 static nsresult NSAPI nsHttpChannelInternal_GetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 *aThirdPartyFlags)
1799 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1800 FIXME("(%p)->(%p)\n", This, aThirdPartyFlags);
1801 return NS_ERROR_NOT_IMPLEMENTED;
1804 static nsresult NSAPI nsHttpChannelInternal_SetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 aThirdPartyFlags)
1806 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1807 FIXME("(%p)->(%x)\n", This, aThirdPartyFlags);
1808 return NS_ERROR_NOT_IMPLEMENTED;
1811 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
1813 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1815 FIXME("(%p)->()\n", This);
1817 return NS_ERROR_NOT_IMPLEMENTED;
1820 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
1822 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1824 FIXME("(%p)->()\n", This);
1826 return NS_ERROR_NOT_IMPLEMENTED;
1829 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1831 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1833 FIXME("(%p)->(%p)\n", This, aCanceled);
1835 return NS_ERROR_NOT_IMPLEMENTED;
1838 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1840 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1842 FIXME("(%p)->(%p)\n", This, aCanceled);
1844 return NS_ERROR_NOT_IMPLEMENTED;
1847 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
1849 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1851 FIXME("(%p)->(%x)\n", This, aCanceled);
1853 return NS_ERROR_NOT_IMPLEMENTED;
1856 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1858 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1860 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1862 return NS_ERROR_NOT_IMPLEMENTED;
1865 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
1867 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1869 FIXME("(%p)->(%p)\n", This, aLocalPort);
1871 return NS_ERROR_NOT_IMPLEMENTED;
1874 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1876 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1878 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1880 return NS_ERROR_NOT_IMPLEMENTED;
1883 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
1885 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1887 FIXME("(%p)->(%p)\n", This, aRemotePort);
1889 return NS_ERROR_NOT_IMPLEMENTED;
1892 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1894 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1896 FIXME("(%p)->(%p)\n", This, cacheKeys);
1898 return NS_ERROR_NOT_IMPLEMENTED;
1901 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1902 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1904 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1905 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1906 return NS_ERROR_NOT_IMPLEMENTED;
1909 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
1911 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1912 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
1913 return NS_ERROR_NOT_IMPLEMENTED;
1916 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
1918 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1919 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
1920 return NS_ERROR_NOT_IMPLEMENTED;
1923 static nsresult NSAPI nsHttpChannelInternal_GetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1924 cpp_bool *aResponseTimeoutEnabled)
1926 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1927 FIXME("(%p)->(%p)\n", This, aResponseTimeoutEnabled);
1928 return NS_ERROR_NOT_IMPLEMENTED;
1931 static nsresult NSAPI nsHttpChannelInternal_SetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1932 cpp_bool aResponseTimeoutEnabled)
1934 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1935 FIXME("(%p)->(%x)\n", This, aResponseTimeoutEnabled);
1936 return NS_ERROR_NOT_IMPLEMENTED;
1939 static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface,
1940 UINT32 *aInitialRwin)
1942 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1943 FIXME("(%p)->(%p)\n", This, aInitialRwin);
1944 return NS_ERROR_NOT_IMPLEMENTED;
1947 static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface,
1948 UINT32 aInitialRwin)
1950 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1951 FIXME("(%p)->(%x)\n", This, aInitialRwin);
1952 return NS_ERROR_NOT_IMPLEMENTED;
1955 static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI)
1957 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1958 FIXME("(%p)->(%p)\n", This, aApiRedirectToURI);
1959 return NS_ERROR_NOT_IMPLEMENTED;
1962 static nsresult NSAPI nsHttpChannelInternal_GetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool *aAllowAltSvc)
1964 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1965 FIXME("(%p)->(%p)\n", This, aAllowAltSvc);
1966 return NS_ERROR_NOT_IMPLEMENTED;
1969 static nsresult NSAPI nsHttpChannelInternal_SetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool aAllowAltSvc)
1971 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1972 FIXME("(%p)->(%x)\n", This, aAllowAltSvc);
1973 return NS_ERROR_NOT_IMPLEMENTED;
1976 static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime)
1978 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1979 FIXME("(%p)->(%p)\n", This, aLastModifiedTime);
1980 return NS_ERROR_NOT_IMPLEMENTED;
1983 static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID)
1985 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1986 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID));
1987 return NS_ERROR_NOT_IMPLEMENTED;
1990 static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized)
1992 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1993 FIXME("(%p, %p)\n", This, ResponseSynthesized);
1994 return NS_ERROR_NOT_IMPLEMENTED;
1997 static nsresult NSAPI nsHttpChannelInternal_GetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
1998 cpp_bool *aCorsIncludeCredentials)
2000 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2001 FIXME("(%p)->(%p)\n", This, aCorsIncludeCredentials);
2002 return NS_ERROR_NOT_IMPLEMENTED;
2005 static nsresult NSAPI nsHttpChannelInternal_SetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2006 cpp_bool aCorsIncludeCredentials)
2008 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2009 TRACE("(%p)->(%x)\n", This, aCorsIncludeCredentials);
2010 return NS_OK;
2013 static nsresult NSAPI nsHttpChannelInternal_GetCorsMode(nsIHttpChannelInternal *iface, UINT32 *aCorsMode)
2015 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2016 FIXME("(%p)->(%p)\n", This, aCorsMode);
2017 return NS_ERROR_NOT_IMPLEMENTED;
2020 static nsresult NSAPI nsHttpChannelInternal_SetCorsMode(nsIHttpChannelInternal *iface, UINT32 aCorsMode)
2022 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2023 TRACE("(%p)->(%d)\n", This, aCorsMode);
2024 return NS_OK;
2027 static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode)
2029 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2030 FIXME("(%p)->(%p)\n", This, aRedirectMode);
2031 return NS_ERROR_NOT_IMPLEMENTED;
2034 static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode)
2036 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2037 TRACE("(%p)->(%d) unimplemented\n", This, aRedirectMode);
2038 return NS_ERROR_NOT_IMPLEMENTED;
2041 static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI)
2043 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2044 FIXME("(%p)->(%p)\n", This, aTopWindowURI);
2045 return NS_ERROR_NOT_IMPLEMENTED;
2048 static nsresult NSAPI nsHttpChannelInternal_GetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2049 nsACString *aNetworkInterfaceId)
2051 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2052 FIXME("(%p)->(%p)\n", This, aNetworkInterfaceId);
2053 return NS_ERROR_NOT_IMPLEMENTED;
2056 static nsresult NSAPI nsHttpChannelInternal_SetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2057 const nsACString *aNetworkInterfaceId)
2059 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2060 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aNetworkInterfaceId));
2061 return NS_ERROR_NOT_IMPLEMENTED;
2064 static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI)
2066 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2067 FIXME("(%p)->(%p)\n", This, aProxyURI);
2068 return NS_ERROR_NOT_IMPLEMENTED;
2071 static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface,
2072 const void /*nsTArray<nsCString>*/ *unsafeHeaders)
2074 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2075 FIXME("(%p)->(%p)\n", This, unsafeHeaders);
2076 return NS_ERROR_NOT_IMPLEMENTED;
2079 static nsresult NSAPI nsHttpChannelInternal_GetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool *aBlockAuthPrompt)
2081 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2082 FIXME("(%p)->(%p)\n", This, aBlockAuthPrompt);
2083 return NS_ERROR_NOT_IMPLEMENTED;
2086 static nsresult NSAPI nsHttpChannelInternal_SetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool aBlockAuthPrompt)
2088 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2089 FIXME("(%p)->(%x)\n", This, aBlockAuthPrompt);
2090 return NS_ERROR_NOT_IMPLEMENTED;
2093 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
2094 nsHttpChannelInternal_QueryInterface,
2095 nsHttpChannelInternal_AddRef,
2096 nsHttpChannelInternal_Release,
2097 nsHttpChannelInternal_GetDocumentURI,
2098 nsHttpChannelInternal_SetDocumentURI,
2099 nsHttpChannelInternal_GetRequestVersion,
2100 nsHttpChannelInternal_GetResponseVersion,
2101 nsHttpChannelInternal_TakeAllSecurityMessages,
2102 nsHttpChannelInternal_SetCookie,
2103 nsHttpChannelInternal_SetupFallbackChannel,
2104 nsHttpChannelInternal_GetThirdPartyFlags,
2105 nsHttpChannelInternal_SetThirdPartyFlags,
2106 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
2107 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
2108 nsHttpChannelInternal_GetCanceled,
2109 nsHttpChannelInternal_GetChannelIsForDownload,
2110 nsHttpChannelInternal_SetChannelIsForDownload,
2111 nsHttpChannelInternal_GetLocalAddress,
2112 nsHttpChannelInternal_GetLocalPort,
2113 nsHttpChannelInternal_GetRemoteAddress,
2114 nsHttpChannelInternal_GetRemotePort,
2115 nsHttpChannelInternal_SetCacheKeysRedirectChain,
2116 nsHttpChannelInternal_HTTPUpgrade,
2117 nsHttpChannelInternal_GetAllowSpdy,
2118 nsHttpChannelInternal_SetAllowSpdy,
2119 nsHttpChannelInternal_GetResponseTimeoutEnabled,
2120 nsHttpChannelInternal_SetResponseTimeoutEnabled,
2121 nsHttpChannelInternal_GetInitialRwin,
2122 nsHttpChannelInternal_SetInitialRwin,
2123 nsHttpChannelInternal_GetApiRedirectToURI,
2124 nsHttpChannelInternal_GetAllowAltSvc,
2125 nsHttpChannelInternal_SetAllowAltSvc,
2126 nsHttpChannelInternal_GetLastModifiedTime,
2127 nsHttpChannelInternal_ForceIntercepted,
2128 nsHttpChannelInternal_GetResponseSynthesized,
2129 nsHttpChannelInternal_GetCorsIncludeCredentials,
2130 nsHttpChannelInternal_SetCorsIncludeCredentials,
2131 nsHttpChannelInternal_GetCorsMode,
2132 nsHttpChannelInternal_SetCorsMode,
2133 nsHttpChannelInternal_GetRedirectMode,
2134 nsHttpChannelInternal_SetRedirectMode,
2135 nsHttpChannelInternal_GetTopWindowURI,
2136 nsHttpChannelInternal_GetNetworkInterfaceId,
2137 nsHttpChannelInternal_SetNetworkInterfaceId,
2138 nsHttpChannelInternal_GetProxyURI,
2139 nsHttpChannelInternal_SetCorsPreflightParameters,
2140 nsHttpChannelInternal_GetBlockAuthPrompt,
2141 nsHttpChannelInternal_SetBlockAuthPrompt
2144 static inline nsChannel *impl_from_nsICacheInfoChannel(nsICacheInfoChannel *iface)
2146 return CONTAINING_RECORD(iface, nsChannel, nsICacheInfoChannel_iface);
2149 static nsresult NSAPI nsCacheInfoChannel_QueryInterface(nsICacheInfoChannel *iface, nsIIDRef riid,
2150 void **result)
2152 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2153 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
2156 static nsrefcnt NSAPI nsCacheInfoChannel_AddRef(nsICacheInfoChannel *iface)
2158 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2159 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
2162 static nsrefcnt NSAPI nsCacheInfoChannel_Release(nsICacheInfoChannel *iface)
2164 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2165 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
2168 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenExpirationTime(nsICacheInfoChannel *iface, UINT32 *p)
2170 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2171 FIXME("(%p)->(%p)\n", This, p);
2172 return E_NOTIMPL;
2175 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenCachedCharset(nsICacheInfoChannel *iface, nsACString *p)
2177 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2178 FIXME("(%p)->(%p)\n", This, p);
2179 return E_NOTIMPL;
2182 static nsresult NSAPI nsCacheInfoChannel_SetCacheTokenCachedCharset(nsICacheInfoChannel *iface, const nsACString *p)
2184 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2185 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(p));
2186 return E_NOTIMPL;
2189 static nsresult NSAPI nsCacheInfoChannel_IsFromCache(nsICacheInfoChannel *iface, cpp_bool *p)
2191 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2192 FIXME("(%p)->(%p)\n", This, p);
2193 *p = FALSE;
2194 return NS_OK;
2197 static nsresult NSAPI nsCacheInfoChannel_GetCacheKey(nsICacheInfoChannel *iface, nsISupports **p)
2199 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2200 FIXME("(%p)->(%p)\n", This, p);
2201 return E_NOTIMPL;
2204 static nsresult NSAPI nsCacheInfoChannel_SetCacheKey(nsICacheInfoChannel *iface, nsISupports *key)
2206 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2207 FIXME("(%p)->(%p)\n", This, key);
2208 return E_NOTIMPL;
2211 static nsresult NSAPI nsCacheInfoChannel_GetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool *p)
2213 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2214 FIXME("(%p)->(%p)\n", This, p);
2215 return E_NOTIMPL;
2218 static nsresult NSAPI nsCacheInfoChannel_SetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool allow)
2220 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2221 FIXME("(%p)->(%x)\n", This, allow);
2222 return E_NOTIMPL;
2225 static const nsICacheInfoChannelVtbl nsCacheInfoChannelVtbl = {
2226 nsCacheInfoChannel_QueryInterface,
2227 nsCacheInfoChannel_AddRef,
2228 nsCacheInfoChannel_Release,
2229 nsCacheInfoChannel_GetCacheTokenExpirationTime,
2230 nsCacheInfoChannel_GetCacheTokenCachedCharset,
2231 nsCacheInfoChannel_SetCacheTokenCachedCharset,
2232 nsCacheInfoChannel_IsFromCache,
2233 nsCacheInfoChannel_GetCacheKey,
2234 nsCacheInfoChannel_SetCacheKey,
2235 nsCacheInfoChannel_GetAllowStaleCacheContent,
2236 nsCacheInfoChannel_SetAllowStaleCacheContent
2239 static void invalidate_uri(nsWineURI *This)
2241 if(This->uri) {
2242 IUri_Release(This->uri);
2243 This->uri = NULL;
2247 static BOOL ensure_uri_builder(nsWineURI *This)
2249 if(!This->is_mutable) {
2250 WARN("Not mutable URI\n");
2251 return FALSE;
2254 if(!This->uri_builder) {
2255 HRESULT hres;
2257 if(!ensure_uri(This))
2258 return FALSE;
2260 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
2261 if(FAILED(hres)) {
2262 WARN("CreateIUriBuilder failed: %08x\n", hres);
2263 return FALSE;
2267 invalidate_uri(This);
2268 return TRUE;
2271 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
2273 char *vala;
2274 BSTR val;
2275 HRESULT hres;
2277 if(!ensure_uri(This))
2278 return NS_ERROR_UNEXPECTED;
2280 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
2281 if(FAILED(hres)) {
2282 WARN("GetPropertyBSTR failed: %08x\n", hres);
2283 return NS_ERROR_UNEXPECTED;
2286 vala = heap_strdupWtoU(val);
2287 SysFreeString(val);
2288 if(!vala)
2289 return NS_ERROR_OUT_OF_MEMORY;
2291 TRACE("ret %s\n", debugstr_a(vala));
2292 nsACString_SetData(ret, vala);
2293 heap_free(vala);
2294 return NS_OK;
2297 static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
2299 return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
2302 static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
2304 nsWineURI *This = impl_from_nsIFileURL(iface);
2306 *result = NULL;
2308 if(IsEqualGUID(&IID_nsISupports, riid)) {
2309 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2310 *result = &This->nsIFileURL_iface;
2311 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
2312 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
2313 *result = &This->nsIFileURL_iface;
2314 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
2315 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
2316 *result = &This->nsIFileURL_iface;
2317 }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
2318 TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
2319 *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
2320 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
2321 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
2322 *result = &This->nsIStandardURL_iface;
2323 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
2324 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
2325 *result = &This->nsIStandardURL_iface;
2326 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
2327 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
2328 *result = This;
2331 if(*result) {
2332 nsIFileURL_AddRef(&This->nsIFileURL_iface);
2333 return NS_OK;
2336 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
2337 return NS_NOINTERFACE;
2340 static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
2342 nsWineURI *This = impl_from_nsIFileURL(iface);
2343 LONG ref = InterlockedIncrement(&This->ref);
2345 TRACE("(%p) ref=%d\n", This, ref);
2347 return ref;
2350 static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
2352 nsWineURI *This = impl_from_nsIFileURL(iface);
2353 LONG ref = InterlockedDecrement(&This->ref);
2355 TRACE("(%p) ref=%d\n", This, ref);
2357 if(!ref) {
2358 if(This->uri)
2359 IUri_Release(This->uri);
2360 if(This->uri_builder)
2361 IUriBuilder_Release(This->uri_builder);
2362 heap_free(This);
2365 return ref;
2368 static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
2370 nsWineURI *This = impl_from_nsIFileURL(iface);
2372 TRACE("(%p)->(%p)\n", This, aSpec);
2374 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
2377 static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
2379 nsWineURI *This = impl_from_nsIFileURL(iface);
2380 const char *speca;
2381 WCHAR *spec;
2382 IUri *uri;
2383 HRESULT hres;
2385 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
2387 if(!This->is_mutable)
2388 return NS_ERROR_UNEXPECTED;
2390 nsACString_GetData(aSpec, &speca);
2391 spec = heap_strdupUtoW(speca);
2392 if(!spec)
2393 return NS_ERROR_OUT_OF_MEMORY;
2395 hres = create_uri(spec, 0, &uri);
2396 heap_free(spec);
2397 if(FAILED(hres)) {
2398 WARN("create_uri failed: %08x\n", hres);
2399 return NS_ERROR_FAILURE;
2402 invalidate_uri(This);
2403 if(This->uri_builder) {
2404 IUriBuilder_Release(This->uri_builder);
2405 This->uri_builder = NULL;
2408 This->uri = uri;
2409 return NS_OK;
2412 static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
2414 nsWineURI *This = impl_from_nsIFileURL(iface);
2415 IUriBuilder *uri_builder;
2416 BSTR display_uri;
2417 IUri *uri;
2418 int len;
2419 nsresult nsres;
2420 HRESULT hres;
2422 TRACE("(%p)->(%p)\n", This, aPrePath);
2424 if(!ensure_uri(This))
2425 return NS_ERROR_UNEXPECTED;
2427 hres = CreateIUriBuilder(This->uri, 0, 0, &uri_builder);
2428 if(FAILED(hres))
2429 return NS_ERROR_FAILURE;
2431 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_PATH|Uri_HAS_QUERY|Uri_HAS_FRAGMENT);
2432 if(SUCCEEDED(hres))
2433 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &uri);
2434 IUriBuilder_Release(uri_builder);
2435 if(FAILED(hres))
2436 return NS_ERROR_FAILURE;
2438 hres = IUri_GetDisplayUri(uri, &display_uri);
2439 IUri_Release(uri);
2440 if(FAILED(hres))
2441 return NS_ERROR_FAILURE;
2443 /* Remove trailing slash that may be appended as default path. */
2444 len = SysStringLen(display_uri);
2445 if(len && display_uri[len-1] == '/')
2446 display_uri[len-1] = 0;
2448 nsres = return_wstr_nsacstr(aPrePath, display_uri, -1);
2449 SysFreeString(display_uri);
2450 return nsres;
2453 static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
2455 nsWineURI *This = impl_from_nsIFileURL(iface);
2456 DWORD scheme;
2457 HRESULT hres;
2459 TRACE("(%p)->(%p)\n", This, aScheme);
2461 if(!ensure_uri(This))
2462 return NS_ERROR_UNEXPECTED;
2464 hres = IUri_GetScheme(This->uri, &scheme);
2465 if(FAILED(hres)) {
2466 WARN("GetScheme failed: %08x\n", hres);
2467 return NS_ERROR_UNEXPECTED;
2470 if(scheme == URL_SCHEME_ABOUT) {
2471 nsACString_SetData(aScheme, "wine");
2472 return NS_OK;
2475 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
2478 static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
2480 nsWineURI *This = impl_from_nsIFileURL(iface);
2481 const char *schemea;
2482 WCHAR *scheme;
2483 HRESULT hres;
2485 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
2487 if(!ensure_uri_builder(This))
2488 return NS_ERROR_UNEXPECTED;
2490 nsACString_GetData(aScheme, &schemea);
2491 scheme = heap_strdupUtoW(schemea);
2492 if(!scheme)
2493 return NS_ERROR_OUT_OF_MEMORY;
2495 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
2496 heap_free(scheme);
2497 if(FAILED(hres))
2498 return NS_ERROR_UNEXPECTED;
2500 return NS_OK;
2503 static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
2505 nsWineURI *This = impl_from_nsIFileURL(iface);
2506 BSTR user, pass;
2507 HRESULT hres;
2509 TRACE("(%p)->(%p)\n", This, aUserPass);
2511 if(!ensure_uri(This))
2512 return NS_ERROR_UNEXPECTED;
2514 hres = IUri_GetUserName(This->uri, &user);
2515 if(FAILED(hres))
2516 return NS_ERROR_FAILURE;
2518 hres = IUri_GetPassword(This->uri, &pass);
2519 if(FAILED(hres)) {
2520 SysFreeString(user);
2521 return NS_ERROR_FAILURE;
2524 if(*user || *pass) {
2525 FIXME("Construct user:pass string\n");
2526 }else {
2527 nsACString_SetData(aUserPass, "");
2530 SysFreeString(user);
2531 SysFreeString(pass);
2532 return NS_OK;
2535 static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
2537 nsWineURI *This = impl_from_nsIFileURL(iface);
2538 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
2539 const char *user_pass;
2540 HRESULT hres;
2542 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
2544 if(!ensure_uri_builder(This))
2545 return NS_ERROR_UNEXPECTED;
2547 nsACString_GetData(aUserPass, &user_pass);
2548 if(*user_pass) {
2549 WCHAR *ptr;
2551 buf = heap_strdupUtoW(user_pass);
2552 if(!buf)
2553 return NS_ERROR_OUT_OF_MEMORY;
2555 ptr = wcschr(buf, ':');
2556 if(!ptr) {
2557 user = buf;
2558 }else if(ptr != buf) {
2559 *ptr++ = 0;
2560 user = buf;
2561 if(*ptr)
2562 pass = ptr;
2563 }else {
2564 pass = buf+1;
2568 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2569 if(SUCCEEDED(hres))
2570 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2572 heap_free(buf);
2573 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2576 static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
2578 nsWineURI *This = impl_from_nsIFileURL(iface);
2580 TRACE("(%p)->(%p)\n", This, aUsername);
2582 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2585 static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
2587 nsWineURI *This = impl_from_nsIFileURL(iface);
2588 const char *usera;
2589 WCHAR *user;
2590 HRESULT hres;
2592 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2594 if(!ensure_uri_builder(This))
2595 return NS_ERROR_UNEXPECTED;
2597 nsACString_GetData(aUsername, &usera);
2598 user = heap_strdupUtoW(usera);
2599 if(!user)
2600 return NS_ERROR_OUT_OF_MEMORY;
2602 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2603 heap_free(user);
2604 if(FAILED(hres))
2605 return NS_ERROR_UNEXPECTED;
2607 return NS_OK;
2610 static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
2612 nsWineURI *This = impl_from_nsIFileURL(iface);
2614 TRACE("(%p)->(%p)\n", This, aPassword);
2616 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2619 static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
2621 nsWineURI *This = impl_from_nsIFileURL(iface);
2622 const char *passa;
2623 WCHAR *pass;
2624 HRESULT hres;
2626 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2628 if(!ensure_uri_builder(This))
2629 return NS_ERROR_UNEXPECTED;
2631 nsACString_GetData(aPassword, &passa);
2632 pass = heap_strdupUtoW(passa);
2633 if(!pass)
2634 return NS_ERROR_OUT_OF_MEMORY;
2636 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2637 heap_free(pass);
2638 if(FAILED(hres))
2639 return NS_ERROR_UNEXPECTED;
2641 return NS_OK;
2644 static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
2646 nsWineURI *This = impl_from_nsIFileURL(iface);
2647 const WCHAR *ptr;
2648 char *vala;
2649 BSTR val;
2650 HRESULT hres;
2652 TRACE("(%p)->(%p)\n", This, aHostPort);
2654 if(!ensure_uri(This))
2655 return NS_ERROR_UNEXPECTED;
2657 hres = IUri_GetAuthority(This->uri, &val);
2658 if(FAILED(hres)) {
2659 WARN("GetAuthority failed: %08x\n", hres);
2660 return NS_ERROR_UNEXPECTED;
2663 ptr = wcschr(val, '@');
2664 if(!ptr)
2665 ptr = val;
2667 vala = heap_strdupWtoU(ptr);
2668 SysFreeString(val);
2669 if(!vala)
2670 return NS_ERROR_OUT_OF_MEMORY;
2672 TRACE("ret %s\n", debugstr_a(vala));
2673 nsACString_SetData(aHostPort, vala);
2674 heap_free(vala);
2675 return NS_OK;
2678 static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
2680 nsWineURI *This = impl_from_nsIFileURL(iface);
2682 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2684 /* Not implemented by Gecko */
2685 return NS_ERROR_NOT_IMPLEMENTED;
2688 static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
2690 nsWineURI *This = impl_from_nsIFileURL(iface);
2692 TRACE("(%p)->(%p)\n", This, aHost);
2694 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2697 static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
2699 nsWineURI *This = impl_from_nsIFileURL(iface);
2700 const char *hosta;
2701 WCHAR *host;
2702 HRESULT hres;
2704 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2706 if(!ensure_uri_builder(This))
2707 return NS_ERROR_UNEXPECTED;
2709 nsACString_GetData(aHost, &hosta);
2710 host = heap_strdupUtoW(hosta);
2711 if(!host)
2712 return NS_ERROR_OUT_OF_MEMORY;
2714 hres = IUriBuilder_SetHost(This->uri_builder, host);
2715 heap_free(host);
2716 if(FAILED(hres))
2717 return NS_ERROR_UNEXPECTED;
2719 return NS_OK;
2722 static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
2724 nsWineURI *This = impl_from_nsIFileURL(iface);
2725 DWORD port;
2726 HRESULT hres;
2728 TRACE("(%p)->(%p)\n", This, aPort);
2730 if(!ensure_uri(This))
2731 return NS_ERROR_UNEXPECTED;
2733 hres = IUri_GetPort(This->uri, &port);
2734 if(FAILED(hres)) {
2735 WARN("GetPort failed: %08x\n", hres);
2736 return NS_ERROR_UNEXPECTED;
2739 *aPort = port ? port : -1;
2740 return NS_OK;
2743 static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
2745 nsWineURI *This = impl_from_nsIFileURL(iface);
2746 HRESULT hres;
2748 TRACE("(%p)->(%d)\n", This, aPort);
2750 if(!ensure_uri_builder(This))
2751 return NS_ERROR_UNEXPECTED;
2753 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2754 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2757 static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
2759 nsWineURI *This = impl_from_nsIFileURL(iface);
2761 TRACE("(%p)->(%p)\n", This, aPath);
2763 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2766 static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
2768 nsWineURI *This = impl_from_nsIFileURL(iface);
2769 const char *patha;
2770 WCHAR *path;
2771 HRESULT hres;
2773 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2775 if(!ensure_uri_builder(This))
2776 return NS_ERROR_UNEXPECTED;
2778 nsACString_GetData(aPath, &patha);
2779 path = heap_strdupUtoW(patha);
2780 if(!path)
2781 return NS_ERROR_OUT_OF_MEMORY;
2783 hres = IUriBuilder_SetPath(This->uri_builder, path);
2784 heap_free(path);
2785 if(FAILED(hres))
2786 return NS_ERROR_UNEXPECTED;
2788 return NS_OK;
2791 static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2793 nsWineURI *This = impl_from_nsIFileURL(iface);
2794 nsWineURI *other_obj;
2795 nsresult nsres;
2796 HRESULT hres;
2798 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2800 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2801 if(NS_FAILED(nsres)) {
2802 TRACE("Could not get nsWineURI interface\n");
2803 *_retval = FALSE;
2804 return NS_OK;
2807 if(ensure_uri(This) && ensure_uri(other_obj)) {
2808 BOOL b;
2810 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2811 if(SUCCEEDED(hres)) {
2812 *_retval = b;
2813 nsres = NS_OK;
2814 }else {
2815 nsres = NS_ERROR_FAILURE;
2817 }else {
2818 nsres = NS_ERROR_UNEXPECTED;
2821 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2822 return nsres;
2825 static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
2827 nsWineURI *This = impl_from_nsIFileURL(iface);
2828 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2829 BSTR scheme_name;
2830 HRESULT hres;
2832 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2834 if(!ensure_uri(This))
2835 return NS_ERROR_UNEXPECTED;
2837 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2838 if(FAILED(hres))
2839 return NS_ERROR_UNEXPECTED;
2841 MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, ARRAY_SIZE(buf));
2842 *_retval = !wcscmp(scheme_name, buf);
2843 SysFreeString(scheme_name);
2844 return NS_OK;
2847 static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
2849 nsWineURI *This = impl_from_nsIFileURL(iface);
2850 nsWineURI *wine_uri;
2851 nsresult nsres;
2853 TRACE("(%p)->(%p)\n", This, _retval);
2855 if(!ensure_uri(This))
2856 return NS_ERROR_UNEXPECTED;
2858 nsres = create_nsuri(This->uri, &wine_uri);
2859 if(NS_FAILED(nsres)) {
2860 WARN("create_nsuri failed: %08x\n", nsres);
2861 return nsres;
2864 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2865 return NS_OK;
2868 static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
2869 nsACString *_retval)
2871 nsWineURI *This = impl_from_nsIFileURL(iface);
2872 const char *patha;
2873 IUri *new_uri;
2874 WCHAR *path;
2875 char *reta;
2876 BSTR ret;
2877 HRESULT hres;
2879 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2881 if(!ensure_uri(This))
2882 return NS_ERROR_UNEXPECTED;
2884 nsACString_GetData(aRelativePath, &patha);
2885 path = heap_strdupUtoW(patha);
2886 if(!path)
2887 return NS_ERROR_OUT_OF_MEMORY;
2889 hres = combine_url(This->uri, path, &new_uri);
2890 heap_free(path);
2891 if(FAILED(hres))
2892 return NS_ERROR_FAILURE;
2894 hres = IUri_GetDisplayUri(new_uri, &ret);
2895 IUri_Release(new_uri);
2896 if(FAILED(hres))
2897 return NS_ERROR_FAILURE;
2899 reta = heap_strdupWtoU(ret);
2900 SysFreeString(ret);
2901 if(!reta)
2902 return NS_ERROR_OUT_OF_MEMORY;
2904 TRACE("returning %s\n", debugstr_a(reta));
2905 nsACString_SetData(_retval, reta);
2906 heap_free(reta);
2907 return NS_OK;
2910 static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
2912 nsWineURI *This = impl_from_nsIFileURL(iface);
2914 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2916 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
2919 static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort)
2921 nsWineURI *This = impl_from_nsIFileURL(iface);
2923 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort);
2925 return nsIFileURL_GetHostPort(&This->nsIFileURL_iface, aAsciiHostPort);
2928 static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
2930 nsWineURI *This = impl_from_nsIFileURL(iface);
2932 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2934 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
2937 static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
2939 nsWineURI *This = impl_from_nsIFileURL(iface);
2941 TRACE("(%p)->(%p)\n", This, aOriginCharset);
2943 nsACString_SetData(aOriginCharset, NULL); /* assume utf-8, we store URI as utf-16 anyway */
2944 return NS_OK;
2947 static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
2949 nsWineURI *This = impl_from_nsIFileURL(iface);
2950 char *refa = NULL;
2951 BSTR ref;
2952 HRESULT hres;
2954 TRACE("(%p)->(%p)\n", This, aRef);
2956 if(!ensure_uri(This))
2957 return NS_ERROR_UNEXPECTED;
2959 hres = IUri_GetFragment(This->uri, &ref);
2960 if(FAILED(hres))
2961 return NS_ERROR_UNEXPECTED;
2963 refa = heap_strdupWtoU(ref);
2964 SysFreeString(ref);
2965 if(ref && !refa)
2966 return NS_ERROR_OUT_OF_MEMORY;
2968 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
2969 heap_free(refa);
2970 return NS_OK;
2973 static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
2975 nsWineURI *This = impl_from_nsIFileURL(iface);
2976 const char *refa;
2977 WCHAR *ref;
2978 HRESULT hres;
2980 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
2982 if(!ensure_uri_builder(This))
2983 return NS_ERROR_UNEXPECTED;
2985 nsACString_GetData(aRef, &refa);
2986 ref = heap_strdupUtoW(refa);
2987 if(!ref)
2988 return NS_ERROR_OUT_OF_MEMORY;
2990 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
2991 heap_free(ref);
2992 if(FAILED(hres))
2993 return NS_ERROR_UNEXPECTED;
2995 return NS_OK;
2998 static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
3000 nsWineURI *This = impl_from_nsIFileURL(iface);
3001 nsWineURI *other_obj;
3002 nsresult nsres;
3004 TRACE("(%p)->(%p %p)\n", This, other, _retval);
3006 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
3007 if(NS_FAILED(nsres)) {
3008 TRACE("Could not get nsWineURI interface\n");
3009 *_retval = FALSE;
3010 return NS_OK;
3013 if(ensure_uri(This) && ensure_uri(other_obj)) {
3014 *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
3015 nsres = NS_OK;
3016 }else {
3017 nsres = NS_ERROR_UNEXPECTED;
3020 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
3021 return nsres;
3024 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
3026 nsWineURI *This = impl_from_nsIFileURL(iface);
3027 nsWineURI *wine_uri;
3028 IUri *uri;
3029 nsresult nsres;
3031 TRACE("(%p)->(%p)\n", This, _retval);
3033 if(!ensure_uri(This))
3034 return NS_ERROR_UNEXPECTED;
3036 uri = get_uri_nofrag(This->uri);
3037 if(!uri)
3038 return NS_ERROR_FAILURE;
3040 nsres = create_nsuri(uri, &wine_uri);
3041 IUri_Release(uri);
3042 if(NS_FAILED(nsres)) {
3043 WARN("create_nsuri failed: %08x\n", nsres);
3044 return nsres;
3047 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3048 return NS_OK;
3051 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
3053 nsWineURI *This = impl_from_nsIFileURL(iface);
3055 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
3057 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
3060 static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
3062 nsWineURI *This = impl_from_nsIFileURL(iface);
3063 BOOL b;
3064 HRESULT hres;
3066 TRACE("(%p)->(%p)\n", This, aHasRef);
3068 if(!ensure_uri(This))
3069 return NS_ERROR_UNEXPECTED;
3071 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
3072 if(FAILED(hres))
3073 return NS_ERROR_FAILURE;
3075 *aHasRef = b;
3076 return NS_OK;
3079 static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
3081 nsWineURI *This = impl_from_nsIFileURL(iface);
3083 TRACE("(%p)->(%p)\n", This, aFilePath);
3085 return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
3088 static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
3090 nsWineURI *This = impl_from_nsIFileURL(iface);
3092 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
3094 if(!This->is_mutable)
3095 return NS_ERROR_UNEXPECTED;
3097 return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
3100 static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
3102 nsWineURI *This = impl_from_nsIFileURL(iface);
3103 WCHAR *ptr;
3104 BSTR query;
3105 nsresult nsres;
3106 HRESULT hres;
3108 TRACE("(%p)->(%p)\n", This, aQuery);
3110 if(!ensure_uri(This))
3111 return NS_ERROR_UNEXPECTED;
3113 hres = IUri_GetQuery(This->uri, &query);
3114 if(FAILED(hres))
3115 return NS_ERROR_FAILURE;
3117 ptr = query;
3118 if(ptr && *ptr == '?')
3119 ptr++;
3121 nsres = return_wstr_nsacstr(aQuery, ptr, -1);
3122 SysFreeString(query);
3123 return nsres;
3126 static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
3128 nsWineURI *This = impl_from_nsIFileURL(iface);
3129 const char *querya;
3130 WCHAR *query;
3131 HRESULT hres;
3133 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
3135 if(!ensure_uri_builder(This))
3136 return NS_ERROR_UNEXPECTED;
3138 nsACString_GetData(aQuery, &querya);
3139 query = heap_strdupUtoW(querya);
3140 if(!query)
3141 return NS_ERROR_OUT_OF_MEMORY;
3143 hres = IUriBuilder_SetQuery(This->uri_builder, query);
3144 heap_free(query);
3145 if(FAILED(hres))
3146 return NS_ERROR_UNEXPECTED;
3148 return NS_OK;
3151 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
3153 const WCHAR *ptr;
3154 HRESULT hres;
3156 if(!ensure_uri(This))
3157 return NS_ERROR_UNEXPECTED;
3159 hres = IUri_GetPath(This->uri, path);
3160 if(FAILED(hres))
3161 return NS_ERROR_FAILURE;
3163 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
3164 if(*ptr == '/' || *ptr == '\\')
3165 ptr++;
3166 *file = ptr;
3168 if(ext) {
3169 ptr = wcsrchr(ptr, '.');
3170 if(!ptr)
3171 ptr = *path + SysStringLen(*path);
3172 *ext = ptr;
3175 return NS_OK;
3178 static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
3180 nsWineURI *This = impl_from_nsIFileURL(iface);
3181 const WCHAR *file;
3182 BSTR path;
3183 nsresult nsres;
3185 TRACE("(%p)->(%p)\n", This, aDirectory);
3187 nsres = get_uri_path(This, &path, &file, NULL);
3188 if(NS_FAILED(nsres))
3189 return nsres;
3191 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
3192 SysFreeString(path);
3193 return nsres;
3196 static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
3198 nsWineURI *This = impl_from_nsIFileURL(iface);
3200 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
3202 /* Not implemented by Gecko */
3203 return NS_ERROR_NOT_IMPLEMENTED;
3206 static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
3208 nsWineURI *This = impl_from_nsIFileURL(iface);
3209 const WCHAR *file;
3210 BSTR path;
3211 nsresult nsres;
3213 TRACE("(%p)->(%p)\n", This, aFileName);
3215 nsres = get_uri_path(This, &path, &file, NULL);
3216 if(NS_FAILED(nsres))
3217 return nsres;
3219 nsres = return_wstr_nsacstr(aFileName, file, -1);
3220 SysFreeString(path);
3221 return nsres;
3224 static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
3226 nsWineURI *This = impl_from_nsIFileURL(iface);
3227 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
3228 return NS_ERROR_NOT_IMPLEMENTED;
3231 static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
3233 nsWineURI *This = impl_from_nsIFileURL(iface);
3234 const WCHAR *file, *ext;
3235 BSTR path;
3236 nsresult nsres;
3238 TRACE("(%p)->(%p)\n", This, aFileBaseName);
3240 nsres = get_uri_path(This, &path, &file, &ext);
3241 if(NS_FAILED(nsres))
3242 return nsres;
3244 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
3245 SysFreeString(path);
3246 return nsres;
3249 static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
3251 nsWineURI *This = impl_from_nsIFileURL(iface);
3252 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
3253 return NS_ERROR_NOT_IMPLEMENTED;
3256 static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
3258 nsWineURI *This = impl_from_nsIFileURL(iface);
3260 TRACE("(%p)->(%p)\n", This, aFileExtension);
3262 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
3265 static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
3267 nsWineURI *This = impl_from_nsIFileURL(iface);
3268 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
3269 return NS_ERROR_NOT_IMPLEMENTED;
3272 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3274 nsWineURI *This = impl_from_nsIFileURL(iface);
3275 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3276 return NS_ERROR_NOT_IMPLEMENTED;
3279 static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3281 nsWineURI *This = impl_from_nsIFileURL(iface);
3282 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3283 return NS_ERROR_NOT_IMPLEMENTED;
3286 static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
3288 nsWineURI *This = impl_from_nsIFileURL(iface);
3289 WCHAR path[MAX_PATH];
3290 DWORD size;
3291 HRESULT hres;
3293 TRACE("(%p)->(%p)\n", This, aFile);
3295 hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
3296 if(FAILED(hres)) {
3297 WARN("CoInternetParseIUri failed: %08x\n", hres);
3298 return NS_ERROR_FAILURE;
3301 return create_nsfile(path, aFile);
3304 static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
3306 nsWineURI *This = impl_from_nsIFileURL(iface);
3307 FIXME("(%p)->(%p)\n", This, aFile);
3308 return NS_ERROR_NOT_IMPLEMENTED;
3311 static const nsIFileURLVtbl nsFileURLVtbl = {
3312 nsURI_QueryInterface,
3313 nsURI_AddRef,
3314 nsURI_Release,
3315 nsURI_GetSpec,
3316 nsURI_SetSpec,
3317 nsURI_GetPrePath,
3318 nsURI_GetScheme,
3319 nsURI_SetScheme,
3320 nsURI_GetUserPass,
3321 nsURI_SetUserPass,
3322 nsURI_GetUsername,
3323 nsURI_SetUsername,
3324 nsURI_GetPassword,
3325 nsURI_SetPassword,
3326 nsURI_GetHostPort,
3327 nsURI_SetHostPort,
3328 nsURI_GetHost,
3329 nsURI_SetHost,
3330 nsURI_GetPort,
3331 nsURI_SetPort,
3332 nsURI_GetPath,
3333 nsURI_SetPath,
3334 nsURI_Equals,
3335 nsURI_SchemeIs,
3336 nsURI_Clone,
3337 nsURI_Resolve,
3338 nsURI_GetAsciiSpec,
3339 nsURI_GetAsciiHostPort,
3340 nsURI_GetAsciiHost,
3341 nsURI_GetOriginCharset,
3342 nsURL_GetRef,
3343 nsURL_SetRef,
3344 nsURI_EqualsExceptRef,
3345 nsURI_CloneIgnoreRef,
3346 nsURI_GetSpecIgnoringRef,
3347 nsURI_GetHasRef,
3348 nsURL_GetFilePath,
3349 nsURL_SetFilePath,
3350 nsURL_GetQuery,
3351 nsURL_SetQuery,
3352 nsURL_GetDirectory,
3353 nsURL_SetDirectory,
3354 nsURL_GetFileName,
3355 nsURL_SetFileName,
3356 nsURL_GetFileBaseName,
3357 nsURL_SetFileBaseName,
3358 nsURL_GetFileExtension,
3359 nsURL_SetFileExtension,
3360 nsURL_GetCommonBaseSpec,
3361 nsURL_GetRelativeSpec,
3362 nsFileURL_GetFile,
3363 nsFileURL_SetFile
3366 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
3368 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
3371 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
3372 void **result)
3374 nsWineURI *This = impl_from_nsIStandardURL(iface);
3375 return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
3378 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
3380 nsWineURI *This = impl_from_nsIStandardURL(iface);
3381 return nsIFileURL_AddRef(&This->nsIFileURL_iface);
3384 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
3386 nsWineURI *This = impl_from_nsIStandardURL(iface);
3387 return nsIFileURL_Release(&This->nsIFileURL_iface);
3390 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
3392 nsWineURI *This = impl_from_nsIStandardURL(iface);
3394 TRACE("(%p)->(%p)\n", This, aMutable);
3396 *aMutable = This->is_mutable;
3397 return NS_OK;
3400 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
3402 nsWineURI *This = impl_from_nsIStandardURL(iface);
3404 TRACE("(%p)->(%x)\n", This, aMutable);
3406 This->is_mutable = aMutable;
3407 return NS_OK;
3410 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
3411 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
3413 nsWineURI *This = impl_from_nsIStandardURL(iface);
3414 FIXME("(%p)->(%d %d %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
3415 return NS_ERROR_NOT_IMPLEMENTED;
3418 static nsresult NSAPI nsStandardURL_SetDefaultPort(nsIStandardURL *iface, LONG aNewDefaultPort)
3420 nsWineURI *This = impl_from_nsIStandardURL(iface);
3421 FIXME("(%p)->(%d)\n", This, aNewDefaultPort);
3422 return NS_ERROR_NOT_IMPLEMENTED;
3425 static const nsIStandardURLVtbl nsStandardURLVtbl = {
3426 nsStandardURL_QueryInterface,
3427 nsStandardURL_AddRef,
3428 nsStandardURL_Release,
3429 nsStandardURL_GetMutable,
3430 nsStandardURL_SetMutable,
3431 nsStandardURL_Init,
3432 nsStandardURL_SetDefaultPort
3435 static nsresult create_nsuri(IUri *iuri, nsWineURI **_retval)
3437 nsWineURI *ret;
3438 HRESULT hres;
3440 ret = heap_alloc_zero(sizeof(nsWineURI));
3441 if(!ret)
3442 return NS_ERROR_OUT_OF_MEMORY;
3444 ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
3445 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
3446 ret->ref = 1;
3447 ret->is_mutable = TRUE;
3449 IUri_AddRef(iuri);
3450 ret->uri = iuri;
3452 hres = IUri_GetScheme(iuri, &ret->scheme);
3453 if(FAILED(hres))
3454 ret->scheme = URL_SCHEME_UNKNOWN;
3456 TRACE("retval=%p\n", ret);
3457 *_retval = ret;
3458 return NS_OK;
3461 HRESULT create_doc_uri(IUri *iuri, nsWineURI **ret)
3463 nsresult nsres;
3464 nsres = create_nsuri(iuri, ret);
3465 return NS_SUCCEEDED(nsres) ? S_OK : E_OUTOFMEMORY;
3468 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
3470 nsChannel *channel;
3472 if(!ensure_uri(uri))
3473 return NS_ERROR_UNEXPECTED;
3475 channel = heap_alloc_zero(sizeof(nsChannel));
3476 if(!channel)
3477 return NS_ERROR_OUT_OF_MEMORY;
3479 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
3480 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
3481 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
3482 channel->nsICacheInfoChannel_iface.lpVtbl = &nsCacheInfoChannelVtbl;
3483 channel->ref = 1;
3484 channel->request_method = METHOD_GET;
3485 list_init(&channel->response_headers);
3486 list_init(&channel->request_headers);
3488 nsIFileURL_AddRef(&uri->nsIFileURL_iface);
3489 channel->uri = uri;
3491 *ret = channel;
3492 return NS_OK;
3495 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
3497 nsChannel *channel;
3498 nsWineURI *uri;
3499 IUri *iuri;
3500 nsresult nsres;
3501 HRESULT hres;
3503 hres = create_uri(url, 0, &iuri);
3504 if(FAILED(hres))
3505 return hres;
3507 nsres = create_nsuri(iuri, &uri);
3508 IUri_Release(iuri);
3509 if(NS_FAILED(nsres))
3510 return E_FAIL;
3512 nsres = create_nschannel(uri, &channel);
3513 nsIFileURL_Release(&uri->nsIFileURL_iface);
3514 if(NS_FAILED(nsres))
3515 return E_FAIL;
3517 if(orig_channel->load_group) {
3518 nsILoadGroup_AddRef(orig_channel->load_group);
3519 channel->load_group = orig_channel->load_group;
3522 if(orig_channel->notif_callback) {
3523 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
3524 channel->notif_callback = orig_channel->notif_callback;
3527 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
3529 if(orig_channel->request_method == METHOD_POST)
3530 FIXME("unsupported POST method\n");
3532 if(orig_channel->original_uri) {
3533 nsIURI_AddRef(orig_channel->original_uri);
3534 channel->original_uri = orig_channel->original_uri;
3537 if(orig_channel->referrer) {
3538 nsIURI_AddRef(orig_channel->referrer);
3539 channel->referrer = orig_channel->referrer;
3542 *ret = channel;
3543 return S_OK;
3546 typedef struct {
3547 nsIProtocolHandler nsIProtocolHandler_iface;
3549 LONG ref;
3551 nsIProtocolHandler *nshandler;
3552 } nsProtocolHandler;
3554 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
3556 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
3559 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
3560 void **result)
3562 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3564 *result = NULL;
3566 if(IsEqualGUID(&IID_nsISupports, riid)) {
3567 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
3568 *result = &This->nsIProtocolHandler_iface;
3569 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
3570 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
3571 *result = &This->nsIProtocolHandler_iface;
3572 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
3573 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
3574 return NS_NOINTERFACE;
3577 if(*result) {
3578 nsISupports_AddRef((nsISupports*)*result);
3579 return NS_OK;
3582 WARN("(%s %p)\n", debugstr_guid(riid), result);
3583 return NS_NOINTERFACE;
3586 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
3588 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3589 LONG ref = InterlockedIncrement(&This->ref);
3591 TRACE("(%p) ref=%d\n", This, ref);
3593 return ref;
3596 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3598 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3599 LONG ref = InterlockedDecrement(&This->ref);
3601 TRACE("(%p) ref=%d\n", This, ref);
3603 if(!ref) {
3604 if(This->nshandler)
3605 nsIProtocolHandler_Release(This->nshandler);
3606 heap_free(This);
3609 return ref;
3612 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3614 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3616 TRACE("(%p)->(%p)\n", This, aScheme);
3618 if(This->nshandler)
3619 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3620 return NS_ERROR_NOT_IMPLEMENTED;
3623 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3624 LONG *aDefaultPort)
3626 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3628 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3630 if(This->nshandler)
3631 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3632 return NS_ERROR_NOT_IMPLEMENTED;
3635 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3636 UINT32 *aProtocolFlags)
3638 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3640 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3642 if(This->nshandler)
3643 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3644 return NS_ERROR_NOT_IMPLEMENTED;
3647 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3648 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3650 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3652 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3653 aBaseURI, _retval);
3655 if(This->nshandler)
3656 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3657 return NS_ERROR_NOT_IMPLEMENTED;
3660 static nsresult NSAPI nsProtocolHandler_NewChannel2(nsIProtocolHandler *iface,
3661 nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3663 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3665 TRACE("(%p)->(%p %p %p)\n", This, aURI, aLoadInfo, _retval);
3667 if(This->nshandler)
3668 return nsIProtocolHandler_NewChannel2(This->nshandler, aURI, aLoadInfo, _retval);
3669 return NS_ERROR_NOT_IMPLEMENTED;
3672 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3673 nsIURI *aURI, nsIChannel **_retval)
3675 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3677 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3679 if(This->nshandler)
3680 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3681 return NS_ERROR_NOT_IMPLEMENTED;
3684 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3685 LONG port, const char *scheme, cpp_bool *_retval)
3687 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3689 TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
3691 if(This->nshandler)
3692 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3693 return NS_ERROR_NOT_IMPLEMENTED;
3696 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3697 nsProtocolHandler_QueryInterface,
3698 nsProtocolHandler_AddRef,
3699 nsProtocolHandler_Release,
3700 nsProtocolHandler_GetScheme,
3701 nsProtocolHandler_GetDefaultPort,
3702 nsProtocolHandler_GetProtocolFlags,
3703 nsProtocolHandler_NewURI,
3704 nsProtocolHandler_NewChannel2,
3705 nsProtocolHandler_NewChannel,
3706 nsProtocolHandler_AllowPort
3709 static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid,
3710 void **result)
3712 if(IsEqualGUID(&IID_nsISupports, riid)) {
3713 TRACE("(IID_nsISupports %p)\n", result);
3714 *result = iface;
3715 }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) {
3716 TRACE("(IID_nsIIOServiceHook %p)\n", result);
3717 *result = iface;
3718 }else {
3719 ERR("(%s %p)\n", debugstr_guid(riid), result);
3720 *result = NULL;
3721 return NS_NOINTERFACE;
3724 nsISupports_AddRef((nsISupports*)*result);
3725 return NS_OK;
3728 static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface)
3730 return 2;
3733 static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface)
3735 return 1;
3738 static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI,
3739 nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3741 nsWineURI *wine_uri;
3742 nsChannel *ret;
3743 nsresult nsres;
3745 TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval);
3747 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3748 if(NS_FAILED(nsres)) {
3749 TRACE("Could not get nsWineURI: %08x\n", nsres);
3750 return NS_SUCCESS_DEFAULT_ACTION;
3753 nsres = create_nschannel(wine_uri, &ret);
3754 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3755 if(NS_FAILED(nsres))
3756 return nsres;
3758 nsIURI_AddRef(aURI);
3759 ret->original_uri = aURI;
3761 if(aLoadInfo)
3762 nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo);
3764 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3765 return NS_OK;
3768 static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler,
3769 nsIProtocolHandler **_retval)
3771 nsIExternalProtocolHandler *nsexthandler;
3772 nsProtocolHandler *ret;
3773 nsresult nsres;
3775 TRACE("(%p %p)\n", aHandler, _retval);
3777 nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler);
3778 if(NS_FAILED(nsres)) {
3779 nsIProtocolHandler_AddRef(aHandler);
3780 *_retval = aHandler;
3781 return NS_OK;
3784 nsIExternalProtocolHandler_Release(nsexthandler);
3786 ret = heap_alloc(sizeof(nsProtocolHandler));
3787 if(!ret)
3788 return NS_ERROR_OUT_OF_MEMORY;
3790 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3791 ret->ref = 1;
3792 nsIProtocolHandler_AddRef(aHandler);
3793 ret->nshandler = aHandler;
3796 *_retval = &ret->nsIProtocolHandler_iface;
3797 TRACE("return %p\n", *_retval);
3798 return NS_OK;
3801 static BOOL is_gecko_special_uri(const char *spec)
3803 static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"};
3804 unsigned int i;
3806 for(i=0; i < ARRAY_SIZE(special_schemes); i++) {
3807 if(!_strnicmp(spec, special_schemes[i], strlen(special_schemes[i])))
3808 return TRUE;
3811 if(!_strnicmp(spec, "file:", 5)) {
3812 const char *ptr = spec+5;
3813 while(*ptr == '/')
3814 ptr++;
3815 return is_gecko_path(ptr);
3818 return FALSE;
3821 static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec,
3822 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3824 nsWineURI *wine_uri, *base_wine_uri = NULL;
3825 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3826 const char *spec = NULL;
3827 UINT cp = CP_UTF8;
3828 IUri *urlmon_uri;
3829 nsresult nsres;
3830 HRESULT hres;
3832 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3833 aBaseURI, _retval);
3835 nsACString_GetData(aSpec, &spec);
3836 if(is_gecko_special_uri(spec))
3837 return NS_SUCCESS_DEFAULT_ACTION;
3839 if(!strncmp(spec, "wine:", 5))
3840 spec += 5;
3842 if(aBaseURI) {
3843 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3844 if(NS_SUCCEEDED(nsres)) {
3845 if(!ensure_uri(base_wine_uri))
3846 return NS_ERROR_UNEXPECTED;
3847 }else {
3848 WARN("Could not get base nsWineURI: %08x\n", nsres);
3852 if(aOriginCharset && *aOriginCharset && _strnicmp(aOriginCharset, "utf", 3)) {
3853 BSTR charset;
3854 int len;
3856 len = MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, NULL, 0);
3857 charset = SysAllocStringLen(NULL, len-1);
3858 if(!charset)
3859 return NS_ERROR_OUT_OF_MEMORY;
3860 MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, charset, len);
3862 cp = cp_from_charset_string(charset);
3864 SysFreeString(charset);
3867 MultiByteToWideChar(cp, 0, spec, -1, new_spec, ARRAY_SIZE(new_spec));
3869 if(base_wine_uri) {
3870 hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri);
3871 }else {
3872 hres = create_uri(new_spec, 0, &urlmon_uri);
3873 if(FAILED(hres))
3874 WARN("create_uri failed: %08x\n", hres);
3877 if(FAILED(hres))
3878 return NS_SUCCESS_DEFAULT_ACTION;
3880 nsres = create_nsuri(urlmon_uri, &wine_uri);
3881 IUri_Release(urlmon_uri);
3882 if(base_wine_uri)
3883 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3884 if(NS_FAILED(nsres))
3885 return nsres;
3887 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3888 return nsres;
3891 static const char *debugstr_protocol_flags(UINT32 flags)
3893 switch(flags) {
3894 #define X(f) case f: return #f
3895 X(URI_STD);
3896 X(URI_NORELATIVE);
3897 X(URI_NOAUTH);
3898 X(ALLOWS_PROXY);
3899 X(ALLOWS_PROXY_HTTP);
3900 X(URI_INHERITS_SECURITY_CONTEXT);
3901 X(URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
3902 X(URI_LOADABLE_BY_ANYONE);
3903 X(URI_DANGEROUS_TO_LOAD);
3904 X(URI_IS_UI_RESOURCE);
3905 X(URI_IS_LOCAL_FILE);
3906 X(URI_LOADABLE_BY_SUBSUMERS);
3907 X(URI_DOES_NOT_RETURN_DATA);
3908 X(URI_IS_LOCAL_RESOURCE);
3909 X(URI_OPENING_EXECUTES_SCRIPT);
3910 X(URI_NON_PERSISTABLE);
3911 X(URI_FORBIDS_COOKIE_ACCESS);
3912 X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM);
3913 X(URI_SYNC_LOAD_IS_OK);
3914 X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT);
3915 X(URI_FETCHABLE_BY_ANYONE);
3916 #undef X
3917 default:
3918 return wine_dbg_sprintf("%08x", flags);
3922 static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3924 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3925 return NS_SUCCESS_DEFAULT_ACTION;
3928 static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3930 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3932 if(aFlags == URI_DOES_NOT_RETURN_DATA) {
3933 *_retval = FALSE;
3934 return S_OK;
3937 return NS_SUCCESS_DEFAULT_ACTION;
3940 static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = {
3941 nsIOServiceHook_QueryInterface,
3942 nsIOServiceHook_AddRef,
3943 nsIOServiceHook_Release,
3944 nsIOServiceHook_NewChannel,
3945 nsIOServiceHook_GetProtocolHandler,
3946 nsIOServiceHook_NewURI,
3947 nsIOServiceHook_ProtocolHasFlags,
3948 nsIOServiceHook_URIChainHasFlags
3951 static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };
3953 void init_nsio(nsIComponentManager *component_manager)
3955 nsIFactory *old_factory = NULL;
3956 nsresult nsres;
3958 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
3959 &IID_nsIFactory, (void**)&old_factory);
3960 if(NS_FAILED(nsres)) {
3961 ERR("Could not get factory: %08x\n", nsres);
3962 return;
3965 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
3966 if(NS_FAILED(nsres)) {
3967 ERR("Couldn not create nsIOService instance %08x\n", nsres);
3968 nsIFactory_Release(old_factory);
3969 return;
3972 nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
3973 assert(nsres == NS_OK);
3976 void release_nsio(void)
3978 if(nsio) {
3979 nsIIOService_Release(nsio);
3980 nsio = NULL;
3984 nsresult create_onload_blocker_request(nsIRequest **ret)
3986 nsIChannel *channel;
3987 nsACString spec;
3988 nsresult nsres;
3990 nsACString_InitDepend(&spec, "about:wine-script-onload-blocker");
3991 nsres = nsIIOService_NewChannel(nsio, &spec, NULL, NULL, &channel);
3992 nsACString_Finish(&spec);
3993 if(NS_FAILED(nsres)) {
3994 ERR("Failed to create channel: %08x\n", nsres);
3995 return nsres;
3998 *ret = (nsIRequest *)channel;
3999 return NS_OK;