windowscodecs: Silence fixme for IID_CMetaBitmapRenderTarget.
[wine.git] / dlls / mshtml / nsio.c
blobe42319dec13022d48ef56c9f80faa364190982e0
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>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "winreg.h"
27 #include "winternl.h"
28 #include "ole2.h"
29 #include "shlguid.h"
30 #include "wininet.h"
31 #include "shlwapi.h"
33 #include "wine/debug.h"
35 #include "mshtml_private.h"
36 #include "binding.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
40 #define NS_IOSERVICE_CLASSNAME "nsIOService"
41 #define NS_IOSERVICE_CONTRACTID "@mozilla.org/network/io-service;1"
43 static const IID NS_IOSERVICE_CID =
44 {0x9ac9e770, 0x18bc, 0x11d3, {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
45 static const IID IID_nsWineURI =
46 {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};
48 static ExternalCycleCollectionParticipant nschannel_ccp;
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: %08lx\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 BOOL compare_uri_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: %08lx\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, NULL);
174 return NS_OK;
177 if(!*str) {
178 nsACString_SetData(ret_str, "");
179 return NS_OK;
182 lena = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
183 stra = malloc(lena + 1);
184 if(!stra)
185 return NS_ERROR_OUT_OF_MEMORY;
187 WideCharToMultiByte(CP_UTF8, 0, str, len, stra, lena, NULL, NULL);
188 stra[lena] = 0;
190 nsACString_SetData(ret_str, stra);
191 free(stra);
192 return NS_OK;
195 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
197 const WCHAR *ptr = nsuri;
199 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
201 if(!wcsncmp(nsuri, wine_prefixW, ARRAY_SIZE(wine_prefixW)))
202 ptr += ARRAY_SIZE(wine_prefixW);
204 if(*ptr || ret_empty) {
205 *ret = SysAllocString(ptr);
206 if(!*ret)
207 return E_OUTOFMEMORY;
208 }else {
209 *ret = NULL;
212 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
213 return S_OK;
216 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
218 IOleCommandTarget *cmdtrg = NULL;
219 HRESULT hres;
221 if(!doc->client)
222 return TRUE;
224 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
225 if(SUCCEEDED(hres)) {
226 VARIANT varUrl, varRes;
228 V_VT(&varUrl) = VT_BSTR;
229 V_BSTR(&varUrl) = url;
230 V_VT(&varRes) = VT_BOOL;
232 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
234 IOleCommandTarget_Release(cmdtrg);
236 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
237 TRACE("got VARIANT_FALSE, do not load\n");
238 return FALSE;
242 return TRUE;
245 static nsresult before_async_open(nsChannel *channel, GeckoBrowser *container, BOOL *cancel)
247 HTMLDocumentObj *doc = container->doc;
248 BSTR display_uri;
249 HRESULT hres;
251 if(!doc->client) {
252 *cancel = TRUE;
253 return NS_OK;
256 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
257 if(FAILED(hres))
258 return NS_ERROR_FAILURE;
259 IUnknown_AddRef(doc->outer_unk);
261 if(doc->hostui) {
262 OLECHAR *new_url;
263 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, display_uri, &new_url);
264 if(hres == S_OK && new_url) {
265 if(wcscmp(display_uri, new_url)) {
266 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(display_uri), debugstr_w(new_url));
267 CoTaskMemFree(new_url);
268 *cancel = TRUE;
269 goto done;
271 CoTaskMemFree(new_url);
275 if(!exec_shldocvw_67(doc, display_uri)) {
276 SysFreeString(display_uri);
277 *cancel = FALSE;
278 goto done;
281 hres = hlink_frame_navigate(doc, display_uri, channel, 0, cancel);
282 SysFreeString(display_uri);
283 if(FAILED(hres))
284 *cancel = TRUE;
286 done:
287 IUnknown_Release(doc->outer_unk);
288 return NS_OK;
291 HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsIInputStream *post_stream,
292 nsChannelBSC *channelbsc, DWORD flags)
294 nsIWebNavigation *web_navigation;
295 nsDocShellInfoLoadType load_type;
296 nsIDocShellLoadInfo *load_info;
297 nsIDocShell *doc_shell;
298 HTMLDocumentNode *doc;
299 nsresult nsres;
301 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
302 if(NS_FAILED(nsres)) {
303 ERR("Could not get nsIWebNavigation interface: %08lx\n", nsres);
304 return E_FAIL;
307 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
308 nsIWebNavigation_Release(web_navigation);
309 if(NS_FAILED(nsres)) {
310 ERR("Could not get nsIDocShell: %08lx\n", nsres);
311 return E_FAIL;
314 nsres = nsIDocShell_CreateLoadInfo(doc_shell, &load_info);
315 if(NS_FAILED(nsres)) {
316 nsIDocShell_Release(doc_shell);
317 return E_FAIL;
320 if(flags & LOAD_FLAGS_IS_REFRESH)
321 load_type = (flags & LOAD_FLAGS_BYPASS_CACHE) ? loadReloadBypassCache : loadReloadNormal;
322 else
323 load_type = (flags & LOAD_FLAGS_BYPASS_CACHE) ? loadNormalBypassCache : loadNormal;
324 nsres = nsIDocShellLoadInfo_SetLoadType(load_info, load_type);
325 assert(nsres == NS_OK);
327 if(post_stream) {
328 nsres = nsIDocShellLoadInfo_SetPostDataStream(load_info, post_stream);
329 assert(nsres == NS_OK);
332 if(window->uri_nofrag) {
333 nsWineURI *referrer_uri;
334 nsres = create_nsuri(window->uri_nofrag, &referrer_uri);
335 if(NS_SUCCEEDED(nsres)) {
336 nsres = nsIDocShellLoadInfo_SetReferrer(load_info, (nsIURI*)&referrer_uri->nsIFileURL_iface);
337 assert(nsres == NS_OK);
338 nsIFileURL_Release(&referrer_uri->nsIFileURL_iface);
342 uri->channel_bsc = channelbsc;
343 doc = window->base.inner_window->doc;
344 doc->skip_mutation_notif = TRUE;
345 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, load_info, flags, FALSE);
346 if(doc == window->base.inner_window->doc)
347 doc->skip_mutation_notif = FALSE;
348 uri->channel_bsc = NULL;
349 nsIDocShell_Release(doc_shell);
350 nsIDocShellLoadInfo_Release(load_info);
351 if(NS_FAILED(nsres)) {
352 WARN("LoadURI failed: %08lx\n", nsres);
353 return E_FAIL;
356 return S_OK;
359 static inline BOOL is_http_channel(nsChannel *This)
361 return This->uri->scheme == URL_SCHEME_HTTP || This->uri->scheme == URL_SCHEME_HTTPS;
364 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
366 http_header_t *iter;
368 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
369 if(!wcsnicmp(iter->header, name, len) && !iter->header[len])
370 return iter;
373 return NULL;
376 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
377 nsACString *_retval)
379 const char *header_namea;
380 http_header_t *header;
381 WCHAR *header_name;
382 char *data;
384 nsACString_GetData(header_name_str, &header_namea);
385 header_name = strdupAtoW(header_namea);
386 if(!header_name)
387 return NS_ERROR_UNEXPECTED;
389 header = find_http_header(headers, header_name, lstrlenW(header_name));
390 free(header_name);
391 if(!header)
392 return NS_ERROR_NOT_AVAILABLE;
394 data = strdupWtoA(header->data);
395 if(!data)
396 return NS_ERROR_UNEXPECTED;
398 TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
399 nsACString_SetData(_retval, data);
400 free(data);
401 return NS_OK;
404 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
405 const WCHAR *value, int value_len)
407 http_header_t *header;
409 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
411 header = find_http_header(headers, name, name_len);
412 if(header) {
413 WCHAR *new_data;
415 new_data = strndupW(value, value_len);
416 if(!new_data)
417 return E_OUTOFMEMORY;
419 free(header->data);
420 header->data = new_data;
421 }else {
422 header = malloc(sizeof(http_header_t));
423 if(!header)
424 return E_OUTOFMEMORY;
426 header->header = strndupW(name, name_len);
427 header->data = strndupW(value, value_len);
428 if(!header->header || !header->data) {
429 free(header->header);
430 free(header->data);
431 free(header);
432 return E_OUTOFMEMORY;
435 list_add_tail(headers, &header->entry);
438 return S_OK;
441 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
442 const nsACString *value_str)
444 const char *namea, *valuea;
445 WCHAR *name, *value;
446 HRESULT hres;
448 nsACString_GetData(name_str, &namea);
449 name = strdupAtoW(namea);
450 if(!name)
451 return NS_ERROR_UNEXPECTED;
453 nsACString_GetData(value_str, &valuea);
454 value = strdupAtoW(valuea);
455 if(!value) {
456 free(name);
457 return NS_ERROR_UNEXPECTED;
460 hres = set_http_header(headers, name, lstrlenW(name), value, lstrlenW(value));
462 free(name);
463 free(value);
464 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
467 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
469 nsACString header_str, value_str;
470 char *header, *value;
471 http_header_t *iter;
472 nsresult nsres;
474 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
475 header = strdupWtoA(iter->header);
476 if(!header)
477 return NS_ERROR_OUT_OF_MEMORY;
479 value = strdupWtoA(iter->data);
480 if(!value) {
481 free(header);
482 return NS_ERROR_OUT_OF_MEMORY;
485 nsACString_InitDepend(&header_str, header);
486 nsACString_InitDepend(&value_str, value);
487 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
488 nsACString_Finish(&header_str);
489 nsACString_Finish(&value_str);
490 free(header);
491 free(value);
492 if(NS_FAILED(nsres))
493 break;
496 return NS_OK;
499 static void free_http_headers(struct list *list)
501 http_header_t *iter, *iter_next;
503 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
504 list_remove(&iter->entry);
505 free(iter->header);
506 free(iter->data);
507 free(iter);
511 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
513 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
516 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
518 nsChannel *This = impl_from_nsIHttpChannel(iface);
520 if(IsEqualGUID(&IID_nsISupports, riid)) {
521 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
522 *result = &This->nsIHttpChannel_iface;
523 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
524 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
525 *result = &This->nsIHttpChannel_iface;
526 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
527 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
528 *result = &This->nsIHttpChannel_iface;
529 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
530 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
531 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
532 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
533 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
534 *result = &This->nsIUploadChannel_iface;
535 }else if(IsEqualGUID(&IID_nsIFormPOSTActionChannel, riid)) {
536 TRACE("(%p)->(IID_nsIFormPOSTActionChannel %p)\n", This, result);
537 *result = &This->nsIUploadChannel_iface;
538 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
539 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
540 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
541 }else if(IsEqualGUID(&IID_nsICacheInfoChannel, riid)) {
542 TRACE("(%p)->(IID_nsICacheInfoChannel %p)\n", This, result);
543 *result = is_http_channel(This) ? &This->nsICacheInfoChannel_iface : NULL;
544 }else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) {
545 TRACE("(%p)->(IID_nsXPCOMCycleCollectionParticipant %p)\n", This, result);
546 *result = &nschannel_ccp;
547 return S_OK;
548 }else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
549 TRACE("(%p)->(IID_nsCycleCollectionISupports %p)\n", This, result);
550 *result = &This->nsIHttpChannel_iface;
551 return S_OK;
552 }else {
553 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
554 *result = NULL;
557 if(*result) {
558 nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
559 return NS_OK;
562 return NS_NOINTERFACE;
565 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
567 nsChannel *This = impl_from_nsIHttpChannel(iface);
568 nsrefcnt ref = ccref_incr(&This->ccref, (nsISupports*)&This->nsIHttpChannel_iface);
570 TRACE("(%p) ref=%ld\n", This, ref);
572 return ref;
575 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
577 nsChannel *This = impl_from_nsIHttpChannel(iface);
578 nsrefcnt ref = ccref_decr(&This->ccref, (nsISupports*)&This->nsIHttpChannel_iface, &nschannel_ccp);
580 TRACE("(%p) ref=%ld\n", This, ref);
582 return ref;
585 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
587 nsChannel *This = impl_from_nsIHttpChannel(iface);
589 TRACE("(%p)->(%p)\n", This, aName);
591 return nsIFileURL_GetSpec(&This->uri->nsIFileURL_iface, aName);
594 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, cpp_bool *_retval)
596 nsChannel *This = impl_from_nsIHttpChannel(iface);
598 FIXME("(%p)->(%p)\n", This, _retval);
600 return NS_ERROR_NOT_IMPLEMENTED;
603 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
605 nsChannel *This = impl_from_nsIHttpChannel(iface);
607 TRACE("(%p)->(%p) returning %#lx\n", This, aStatus, This->status);
609 return *aStatus = This->status;
612 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
614 nsChannel *This = impl_from_nsIHttpChannel(iface);
616 TRACE("(%p)->(%08lx)\n", This, aStatus);
618 if(NS_FAILED(aStatus))
619 This->status = aStatus;
621 if(This->binding && This->binding->bsc.binding)
622 IBinding_Abort(This->binding->bsc.binding);
623 else
624 WARN("No binding to cancel\n");
625 return NS_OK;
628 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
630 nsChannel *This = impl_from_nsIHttpChannel(iface);
632 FIXME("(%p)\n", This);
634 return NS_ERROR_NOT_IMPLEMENTED;
637 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
639 nsChannel *This = impl_from_nsIHttpChannel(iface);
641 FIXME("(%p)\n", This);
643 return NS_ERROR_NOT_IMPLEMENTED;
646 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
648 nsChannel *This = impl_from_nsIHttpChannel(iface);
650 TRACE("(%p)->(%p)\n", This, aLoadGroup);
652 if(This->load_group)
653 nsILoadGroup_AddRef(This->load_group);
655 *aLoadGroup = This->load_group;
656 return NS_OK;
659 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
661 nsChannel *This = impl_from_nsIHttpChannel(iface);
663 TRACE("(%p)->(%p)\n", This, aLoadGroup);
665 if(This->load_group)
666 nsILoadGroup_Release(This->load_group);
667 if(aLoadGroup)
668 nsILoadGroup_AddRef(aLoadGroup);
669 This->load_group = aLoadGroup;
671 return NS_OK;
674 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
676 nsChannel *This = impl_from_nsIHttpChannel(iface);
678 TRACE("(%p)->(%p)\n", This, aLoadFlags);
680 *aLoadFlags = This->load_flags;
681 return NS_OK;
684 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
686 nsChannel *This = impl_from_nsIHttpChannel(iface);
688 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
690 This->load_flags = aLoadFlags;
691 return NS_OK;
694 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
696 nsChannel *This = impl_from_nsIHttpChannel(iface);
698 TRACE("(%p)->(%p)\n", This, aOriginalURI);
700 if(This->original_uri)
701 nsIURI_AddRef(This->original_uri);
703 *aOriginalURI = This->original_uri;
704 return NS_OK;
707 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
709 nsChannel *This = impl_from_nsIHttpChannel(iface);
711 TRACE("(%p)->(%p)\n", This, aOriginalURI);
713 if(This->original_uri)
714 nsIURI_Release(This->original_uri);
716 nsIURI_AddRef(aOriginalURI);
717 This->original_uri = aOriginalURI;
718 return NS_OK;
721 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
723 nsChannel *This = impl_from_nsIHttpChannel(iface);
725 TRACE("(%p)->(%p)\n", This, aURI);
727 nsIFileURL_AddRef(&This->uri->nsIFileURL_iface);
728 *aURI = (nsIURI*)&This->uri->nsIFileURL_iface;
730 return NS_OK;
733 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
735 nsChannel *This = impl_from_nsIHttpChannel(iface);
737 TRACE("(%p)->(%p)\n", This, aOwner);
739 if(This->owner)
740 nsISupports_AddRef(This->owner);
741 *aOwner = This->owner;
743 return NS_OK;
746 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
748 nsChannel *This = impl_from_nsIHttpChannel(iface);
750 TRACE("(%p)->(%p)\n", This, aOwner);
752 if(aOwner)
753 nsISupports_AddRef(aOwner);
754 if(This->owner)
755 nsISupports_Release(This->owner);
756 This->owner = aOwner;
758 return NS_OK;
761 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
762 nsIInterfaceRequestor **aNotificationCallbacks)
764 nsChannel *This = impl_from_nsIHttpChannel(iface);
766 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
768 if(This->notif_callback)
769 nsIInterfaceRequestor_AddRef(This->notif_callback);
770 *aNotificationCallbacks = This->notif_callback;
772 return NS_OK;
775 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
776 nsIInterfaceRequestor *aNotificationCallbacks)
778 nsChannel *This = impl_from_nsIHttpChannel(iface);
780 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
782 if(This->notif_callback)
783 nsIInterfaceRequestor_Release(This->notif_callback);
784 if(aNotificationCallbacks)
785 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
787 This->notif_callback = aNotificationCallbacks;
789 return NS_OK;
792 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
794 nsChannel *This = impl_from_nsIHttpChannel(iface);
796 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
798 return NS_ERROR_NOT_IMPLEMENTED;
801 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
803 nsChannel *This = impl_from_nsIHttpChannel(iface);
805 TRACE("(%p)->(%p)\n", This, aContentType);
807 if(This->content_type) {
808 nsACString_SetData(aContentType, This->content_type);
809 return S_OK;
812 if(This->load_flags & LOAD_DOCUMENT_URI) {
813 WARN("Document channel with no MIME set. Assuming text/html\n");
814 nsACString_SetData(aContentType, "text/html");
815 return S_OK;
818 WARN("unknown type\n");
819 return NS_ERROR_FAILURE;
822 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
823 const nsACString *aContentType)
825 nsChannel *This = impl_from_nsIHttpChannel(iface);
826 const char *content_type;
828 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
830 nsACString_GetData(aContentType, &content_type);
831 free(This->content_type);
832 This->content_type = strdup(content_type);
834 return NS_OK;
837 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
838 nsACString *aContentCharset)
840 nsChannel *This = impl_from_nsIHttpChannel(iface);
842 TRACE("(%p)->(%p)\n", This, aContentCharset);
844 if(This->charset) {
845 nsACString_SetData(aContentCharset, This->charset);
846 return NS_OK;
849 nsACString_SetData(aContentCharset, "");
850 return NS_OK;
853 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
854 const nsACString *aContentCharset)
856 nsChannel *This = impl_from_nsIHttpChannel(iface);
857 const char *data;
858 char *charset;
860 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
862 nsACString_GetData(aContentCharset, &data);
863 charset = strdup(data);
864 if(!charset)
865 return NS_ERROR_OUT_OF_MEMORY;
867 free(This->charset);
868 This->charset = charset;
869 return NS_OK;
872 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, INT64 *aContentLength)
874 nsChannel *This = impl_from_nsIHttpChannel(iface);
876 FIXME("(%p)->(%p)\n", This, aContentLength);
878 return NS_ERROR_NOT_IMPLEMENTED;
881 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, INT64 aContentLength)
883 nsChannel *This = impl_from_nsIHttpChannel(iface);
885 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aContentLength));
887 return NS_ERROR_NOT_IMPLEMENTED;
890 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
892 nsChannel *This = impl_from_nsIHttpChannel(iface);
894 FIXME("(%p)->(%p)\n", This, _retval);
896 return NS_ERROR_NOT_IMPLEMENTED;
899 static nsresult NSAPI nsChannel_Open2(nsIHttpChannel *iface, nsIInputStream **_retval)
901 nsChannel *This = impl_from_nsIHttpChannel(iface);
903 FIXME("(%p)->(%p)\n", This, _retval);
905 return NS_ERROR_NOT_IMPLEMENTED;
908 static HTMLOuterWindow *get_channel_window(nsChannel *This, UINT32 *load_type)
910 nsIWebProgress *web_progress = NULL;
911 mozIDOMWindowProxy *mozwindow;
912 HTMLOuterWindow *window;
913 nsresult nsres;
915 if(This->load_group) {
916 nsIRequestObserver *req_observer;
918 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
919 if(NS_FAILED(nsres)) {
920 ERR("GetGroupObserver failed: %08lx\n", nsres);
921 return NULL;
924 if(req_observer) {
925 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
926 nsIRequestObserver_Release(req_observer);
927 if(NS_FAILED(nsres)) {
928 ERR("Could not get nsIWebProgress iface: %08lx\n", nsres);
929 return NULL;
934 if(!web_progress && This->notif_callback) {
935 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
936 if(NS_FAILED(nsres)) {
937 ERR("GetInterface(IID_nsIWebProgress failed: %08lx\n", nsres);
938 return NULL;
942 if(!web_progress) {
943 ERR("Could not find nsIWebProgress\n");
944 return NULL;
947 nsIWebProgress_GetLoadType(web_progress, load_type);
949 nsres = nsIWebProgress_GetDOMWindow(web_progress, &mozwindow);
950 nsIWebProgress_Release(web_progress);
951 if(NS_FAILED(nsres) || !mozwindow) {
952 ERR("GetDOMWindow failed: %08lx\n", nsres);
953 return NULL;
956 window = mozwindow_to_window(mozwindow);
957 mozIDOMWindowProxy_Release(mozwindow);
959 if(window)
960 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
961 else
962 FIXME("NULL window for %p\n", mozwindow);
963 return window;
966 typedef struct {
967 task_t header;
968 HTMLInnerWindow *window;
969 nsChannelBSC *bscallback;
970 } start_binding_task_t;
972 static void start_binding_proc(task_t *_task)
974 start_binding_task_t *task = (start_binding_task_t*)_task;
976 start_binding(task->window, (BSCallback*)task->bscallback, NULL);
979 static void start_binding_task_destr(task_t *_task)
981 start_binding_task_t *task = (start_binding_task_t*)_task;
983 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
986 static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, UINT32 load_type,
987 nsIStreamListener *listener, nsISupports *context)
989 nsChannelBSC *bscallback;
990 IMoniker *mon = NULL;
991 HRESULT hres;
993 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
994 if(FAILED(hres)) {
995 WARN("CreateURLMoniker failed: %08lx\n", hres);
996 return NS_ERROR_UNEXPECTED;
999 if(is_doc_channel)
1000 set_current_mon(window, mon, BINDING_NAVIGATED);
1002 hres = create_channelbsc(mon, NULL, NULL, 0, is_doc_channel, &bscallback);
1003 IMoniker_Release(mon);
1004 if(FAILED(hres))
1005 return NS_ERROR_UNEXPECTED;
1007 channelbsc_set_channel(bscallback, This, listener, context);
1009 if(is_doc_channel) {
1010 hres = create_pending_window(window, bscallback);
1011 if(SUCCEEDED(hres))
1012 async_start_doc_binding(window, window->pending_window, (load_type & LOAD_CMD_RELOAD) ? BINDING_REFRESH : BINDING_NAVIGATED);
1013 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1014 if(FAILED(hres))
1015 return NS_ERROR_UNEXPECTED;
1016 }else {
1017 start_binding_task_t *task;
1019 task = malloc(sizeof(start_binding_task_t));
1020 if(!task) {
1021 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1022 return NS_ERROR_OUT_OF_MEMORY;
1025 task->window = window->base.inner_window;
1026 task->bscallback = bscallback;
1027 hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic);
1028 if(FAILED(hres))
1029 return NS_ERROR_OUT_OF_MEMORY;
1032 return NS_OK;
1035 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
1036 nsISupports *aContext)
1038 nsChannel *This = impl_from_nsIHttpChannel(iface);
1039 UINT32 load_type = LOAD_CMD_NORMAL;
1040 HTMLOuterWindow *window = NULL;
1041 BOOL is_document_channel;
1042 BOOL cancel = FALSE;
1043 nsresult nsres = NS_OK;
1045 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1047 if(!ensure_uri(This->uri))
1048 return NS_ERROR_FAILURE;
1050 if(TRACE_ON(mshtml)) {
1051 HRESULT hres;
1052 BSTR uri_str;
1054 hres = IUri_GetDisplayUri(This->uri->uri, &uri_str);
1055 if(SUCCEEDED(hres)) {
1056 TRACE("opening %s\n", debugstr_w(uri_str));
1057 SysFreeString(uri_str);
1058 }else {
1059 WARN("GetDisplayUri failed: %08lx\n", hres);
1063 window = get_channel_window(This, &load_type);
1064 if(!window) {
1065 ERR("window = NULL\n");
1066 return NS_ERROR_UNEXPECTED;
1069 is_document_channel = !!(This->load_flags & LOAD_DOCUMENT_URI);
1071 if(is_document_channel) {
1072 if(This->uri->channel_bsc) {
1073 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1074 cancel = TRUE;
1077 if(is_main_content_window(window)) {
1078 if(!This->uri->channel_bsc) {
1079 /* top window navigation initiated by Gecko */
1080 nsres = before_async_open(This, window->browser, &cancel);
1081 if(NS_SUCCEEDED(nsres) && cancel) {
1082 TRACE("canceled\n");
1083 nsres = NS_BINDING_ABORTED;
1085 }else if(window->browser->doc && window->browser->doc->mime) {
1086 free(This->content_type);
1087 This->content_type = strdupWtoA(window->browser->doc->mime);
1092 if(!cancel)
1093 nsres = async_open(This, window, is_document_channel, load_type, aListener, aContext);
1095 if(NS_SUCCEEDED(nsres) && This->load_group) {
1096 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1097 aContext);
1098 if(NS_FAILED(nsres))
1099 ERR("AddRequest failed: %08lx\n", nsres);
1102 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
1103 return nsres;
1106 static nsresult NSAPI nsChannel_AsyncOpen2(nsIHttpChannel *iface, nsIStreamListener *aListener)
1108 nsChannel *This = impl_from_nsIHttpChannel(iface);
1109 FIXME("(%p)->(%p)\n", This, aListener);
1110 return nsIHttpChannel_AsyncOpen(&This->nsIHttpChannel_iface, aListener, NULL);
1113 static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition)
1115 nsChannel *This = impl_from_nsIHttpChannel(iface);
1116 TRACE("(%p)->(%p) unimplemented\n", This, aContentDisposition);
1117 return NS_ERROR_NOT_IMPLEMENTED;
1120 static nsresult NSAPI nsChannel_SetContentDisposition(nsIHttpChannel *iface, UINT32 aContentDisposition)
1122 nsChannel *This = impl_from_nsIHttpChannel(iface);
1123 FIXME("(%p)->(%u)\n", This, aContentDisposition);
1124 return NS_ERROR_NOT_IMPLEMENTED;
1127 static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
1129 nsChannel *This = impl_from_nsIHttpChannel(iface);
1130 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1131 return NS_ERROR_NOT_IMPLEMENTED;
1134 static nsresult NSAPI nsChannel_SetContentDispositionFilename(nsIHttpChannel *iface, const nsAString *aContentDispositionFilename)
1136 nsChannel *This = impl_from_nsIHttpChannel(iface);
1137 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1138 return NS_ERROR_NOT_IMPLEMENTED;
1141 static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
1143 nsChannel *This = impl_from_nsIHttpChannel(iface);
1144 TRACE("(%p)->(%p) unimplemented\n", This, aContentDispositionHeader);
1145 return NS_ERROR_NOT_IMPLEMENTED;
1148 static nsresult NSAPI nsChannel_GetLoadInfo(nsIHttpChannel *iface, nsILoadInfo **aLoadInfo)
1150 nsChannel *This = impl_from_nsIHttpChannel(iface);
1152 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1154 if(This->load_info)
1155 nsISupports_AddRef(This->load_info);
1156 *aLoadInfo = This->load_info;
1157 return NS_OK;
1160 static nsresult NSAPI nsChannel_SetLoadInfo(nsIHttpChannel *iface, nsILoadInfo *aLoadInfo)
1162 nsChannel *This = impl_from_nsIHttpChannel(iface);
1164 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1166 if(This->load_info)
1167 nsISupports_Release(This->load_info);
1168 This->load_info = aLoadInfo;
1169 if(This->load_info)
1170 nsISupports_AddRef(This->load_info);
1171 return NS_OK;
1174 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1176 nsChannel *This = impl_from_nsIHttpChannel(iface);
1178 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1180 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1181 return NS_OK;
1184 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1185 const nsACString *aRequestMethod)
1187 nsChannel *This = impl_from_nsIHttpChannel(iface);
1188 const char *method;
1189 unsigned i;
1191 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1193 nsACString_GetData(aRequestMethod, &method);
1194 for(i=0; i < ARRAY_SIZE(request_method_strings); i++) {
1195 if(!stricmp(method, request_method_strings[i])) {
1196 This->request_method = i;
1197 return NS_OK;
1201 ERR("Invalid method %s\n", debugstr_a(method));
1202 return NS_ERROR_UNEXPECTED;
1205 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1207 nsChannel *This = impl_from_nsIHttpChannel(iface);
1209 TRACE("(%p)->(%p)\n", This, aReferrer);
1211 if(This->referrer)
1212 nsIURI_AddRef(This->referrer);
1213 *aReferrer = This->referrer;
1214 return NS_OK;
1217 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1219 nsChannel *This = impl_from_nsIHttpChannel(iface);
1221 TRACE("(%p)->(%p)\n", This, aReferrer);
1223 return nsIHttpChannel_SetReferrerWithPolicy(&This->nsIHttpChannel_iface, aReferrer, 0);
1226 static nsresult NSAPI nsChannel_GetReferrerPolicy(nsIHttpChannel *iface, UINT32 *aReferrerPolicy)
1228 nsChannel *This = impl_from_nsIHttpChannel(iface);
1229 TRACE("(%p)->(%p) unimplemented\n", This, aReferrerPolicy);
1230 return NS_ERROR_NOT_IMPLEMENTED;
1233 static nsresult NSAPI nsChannel_SetReferrerWithPolicy(nsIHttpChannel *iface, nsIURI *aReferrer, UINT32 aReferrerPolicy)
1235 nsChannel *This = impl_from_nsIHttpChannel(iface);
1236 DWORD channel_scheme, referrer_scheme;
1237 nsWineURI *referrer;
1238 BSTR referrer_uri;
1239 nsresult nsres;
1240 HRESULT hres;
1242 static const WCHAR refererW[] = {'R','e','f','e','r','e','r'};
1244 TRACE("(%p)->(%p %d)\n", This, aReferrer, aReferrerPolicy);
1246 if(aReferrerPolicy)
1247 FIXME("refferer policy %d not implemented\n", aReferrerPolicy);
1249 unlink_ref(&This->referrer);
1250 if(!aReferrer)
1251 return NS_OK;
1253 nsres = nsIURI_QueryInterface(aReferrer, &IID_nsWineURI, (void**)&referrer);
1254 if(NS_FAILED(nsres))
1255 return NS_OK;
1257 if(!ensure_uri(referrer)) {
1258 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1259 return NS_ERROR_UNEXPECTED;
1262 if(!ensure_uri(This->uri) || IUri_GetScheme(This->uri->uri, &channel_scheme) != S_OK)
1263 channel_scheme = INTERNET_SCHEME_UNKNOWN;
1265 if(IUri_GetScheme(referrer->uri, &referrer_scheme) != S_OK)
1266 referrer_scheme = INTERNET_SCHEME_UNKNOWN;
1268 if(referrer_scheme == INTERNET_SCHEME_HTTPS && channel_scheme != INTERNET_SCHEME_HTTPS) {
1269 TRACE("Ignoring https referrer on non-https channel\n");
1270 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1271 return NS_OK;
1274 hres = IUri_GetDisplayUri(referrer->uri, &referrer_uri);
1275 if(SUCCEEDED(hres)) {
1276 set_http_header(&This->request_headers, refererW, ARRAY_SIZE(refererW), referrer_uri, SysStringLen(referrer_uri));
1277 SysFreeString(referrer_uri);
1280 This->referrer = (nsIURI*)&referrer->nsIFileURL_iface;
1281 return NS_OK;
1284 static nsresult NSAPI nsHttpChannel_GetProtocolVersion(nsIHttpChannel *iface, nsACString *aProtocolVersion)
1286 nsChannel *This = impl_from_nsIHttpChannel(iface);
1287 FIXME("(%p)->(%p)\n", This, aProtocolVersion);
1288 return NS_ERROR_NOT_IMPLEMENTED;
1291 static nsresult NSAPI nsHttpChannel_GetTransferSize(nsIHttpChannel *iface, UINT64 *aTransferSize)
1293 nsChannel *This = impl_from_nsIHttpChannel(iface);
1294 FIXME("(%p)->(%p)\n", This, aTransferSize);
1295 return NS_ERROR_NOT_IMPLEMENTED;
1298 static nsresult NSAPI nsHttpChannel_GetDecodedBodySize(nsIHttpChannel *iface, UINT64 *aDecodedBodySize)
1300 nsChannel *This = impl_from_nsIHttpChannel(iface);
1301 FIXME("(%p)->(%p)\n", This, aDecodedBodySize);
1302 return NS_ERROR_NOT_IMPLEMENTED;
1305 static nsresult NSAPI nsHttpChannel_GetEncodedBodySize(nsIHttpChannel *iface, UINT64 *aEncodedBodySize)
1307 nsChannel *This = impl_from_nsIHttpChannel(iface);
1308 FIXME("(%p)->(%p)\n", This, aEncodedBodySize);
1309 return NS_ERROR_NOT_IMPLEMENTED;
1312 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1313 const nsACString *aHeader, nsACString *_retval)
1315 nsChannel *This = impl_from_nsIHttpChannel(iface);
1317 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1319 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1322 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1323 const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
1325 nsChannel *This = impl_from_nsIHttpChannel(iface);
1327 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1329 if(aMerge)
1330 FIXME("aMerge not supported\n");
1332 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1335 static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader)
1337 nsChannel *This = impl_from_nsIHttpChannel(iface);
1338 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader));
1339 return NS_ERROR_NOT_IMPLEMENTED;
1342 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1343 nsIHttpHeaderVisitor *aVisitor)
1345 nsChannel *This = impl_from_nsIHttpChannel(iface);
1347 FIXME("(%p)->(%p)\n", This, aVisitor);
1349 return NS_ERROR_NOT_IMPLEMENTED;
1352 static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor)
1354 nsChannel *This = impl_from_nsIHttpChannel(iface);
1355 FIXME("(%p)->(%p)\n", This, aVisitor);
1356 return NS_ERROR_NOT_IMPLEMENTED;
1359 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
1361 nsChannel *This = impl_from_nsIHttpChannel(iface);
1363 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1365 return NS_ERROR_NOT_IMPLEMENTED;
1368 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
1370 nsChannel *This = impl_from_nsIHttpChannel(iface);
1372 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1374 return NS_ERROR_NOT_IMPLEMENTED;
1377 static nsresult NSAPI nsChannel_GetAllowTLS(nsIHttpChannel *iface, cpp_bool *aAllowTLS)
1379 nsChannel *This = impl_from_nsIHttpChannel(iface);
1380 FIXME("(%p)->(%p)\n", This, aAllowTLS);
1381 return NS_ERROR_NOT_IMPLEMENTED;
1384 static nsresult NSAPI nsChannel_SetAllowTLS(nsIHttpChannel *iface, cpp_bool aAllowTLS)
1386 nsChannel *This = impl_from_nsIHttpChannel(iface);
1387 FIXME("(%p)->(%x)\n", This, aAllowTLS);
1388 return NS_ERROR_NOT_IMPLEMENTED;
1391 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
1393 nsChannel *This = impl_from_nsIHttpChannel(iface);
1395 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1397 return NS_ERROR_NOT_IMPLEMENTED;
1400 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
1402 nsChannel *This = impl_from_nsIHttpChannel(iface);
1404 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1406 return NS_ERROR_NOT_IMPLEMENTED;
1409 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
1411 nsChannel *This = impl_from_nsIHttpChannel(iface);
1413 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1415 if(This->response_status) {
1416 *aResponseStatus = This->response_status;
1417 return NS_OK;
1420 WARN("No response status\n");
1421 return NS_ERROR_UNEXPECTED;
1424 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1425 nsACString *aResponseStatusText)
1427 nsChannel *This = impl_from_nsIHttpChannel(iface);
1429 TRACE("(%p)->(%p)\n", This, aResponseStatusText);
1431 nsACString_SetData(aResponseStatusText, This->response_status_text);
1432 return NS_OK;
1435 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1436 cpp_bool *aRequestSucceeded)
1438 nsChannel *This = impl_from_nsIHttpChannel(iface);
1440 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1442 if(!This->response_status)
1443 return NS_ERROR_NOT_AVAILABLE;
1445 *aRequestSucceeded = This->response_status/100 == 2;
1447 return NS_OK;
1450 static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel)
1452 nsChannel *This = impl_from_nsIHttpChannel(iface);
1453 FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel);
1454 return NS_ERROR_NOT_IMPLEMENTED;
1457 static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel)
1459 nsChannel *This = impl_from_nsIHttpChannel(iface);
1460 FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel);
1461 return NS_ERROR_NOT_IMPLEMENTED;
1464 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1465 const nsACString *header, nsACString *_retval)
1467 nsChannel *This = impl_from_nsIHttpChannel(iface);
1469 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1471 return get_channel_http_header(&This->response_headers, header, _retval);
1474 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1475 const nsACString *header, const nsACString *value, cpp_bool merge)
1477 nsChannel *This = impl_from_nsIHttpChannel(iface);
1479 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1481 return NS_ERROR_NOT_IMPLEMENTED;
1484 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1485 nsIHttpHeaderVisitor *aVisitor)
1487 nsChannel *This = impl_from_nsIHttpChannel(iface);
1489 TRACE("(%p)->(%p)\n", This, aVisitor);
1491 return visit_http_headers(&This->response_headers, aVisitor);
1494 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1496 nsChannel *This = impl_from_nsIHttpChannel(iface);
1497 http_header_t *header;
1499 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1501 TRACE("(%p)->(%p)\n", This, _retval);
1503 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1504 *_retval = header && !wcsicmp(header->data, L"no-store");
1505 return NS_OK;
1508 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1510 nsChannel *This = impl_from_nsIHttpChannel(iface);
1511 http_header_t *header;
1513 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1515 TRACE("(%p)->(%p)\n", This, _retval);
1517 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1518 *_retval = header && !wcsicmp(header->data, L"no-cache");
1519 /* FIXME: Gecko also checks if max-age is in the past */
1520 return NS_OK;
1523 static nsresult NSAPI nsChannel_IsPrivateResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1525 nsChannel *This = impl_from_nsIHttpChannel(iface);
1527 FIXME("(%p)->(%p)\n", This, _retval);
1529 return NS_ERROR_NOT_IMPLEMENTED;
1532 static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aTargetURI)
1534 nsChannel *This = impl_from_nsIHttpChannel(iface);
1536 FIXME("(%p)->(%p)\n", This, aTargetURI);
1538 return NS_ERROR_NOT_IMPLEMENTED;
1541 static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID)
1543 nsChannel *This = impl_from_nsIHttpChannel(iface);
1545 FIXME("(%p)->(%p)\n", This, aSchedulingContextID);
1547 return NS_ERROR_NOT_IMPLEMENTED;
1550 static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID)
1552 nsChannel *This = impl_from_nsIHttpChannel(iface);
1554 FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID));
1556 return NS_ERROR_NOT_IMPLEMENTED;
1559 static const nsIHttpChannelVtbl nsChannelVtbl = {
1560 nsChannel_QueryInterface,
1561 nsChannel_AddRef,
1562 nsChannel_Release,
1563 nsChannel_GetName,
1564 nsChannel_IsPending,
1565 nsChannel_GetStatus,
1566 nsChannel_Cancel,
1567 nsChannel_Suspend,
1568 nsChannel_Resume,
1569 nsChannel_GetLoadGroup,
1570 nsChannel_SetLoadGroup,
1571 nsChannel_GetLoadFlags,
1572 nsChannel_SetLoadFlags,
1573 nsChannel_GetOriginalURI,
1574 nsChannel_SetOriginalURI,
1575 nsChannel_GetURI,
1576 nsChannel_GetOwner,
1577 nsChannel_SetOwner,
1578 nsChannel_GetNotificationCallbacks,
1579 nsChannel_SetNotificationCallbacks,
1580 nsChannel_GetSecurityInfo,
1581 nsChannel_GetContentType,
1582 nsChannel_SetContentType,
1583 nsChannel_GetContentCharset,
1584 nsChannel_SetContentCharset,
1585 nsChannel_GetContentLength,
1586 nsChannel_SetContentLength,
1587 nsChannel_Open,
1588 nsChannel_Open2,
1589 nsChannel_AsyncOpen,
1590 nsChannel_AsyncOpen2,
1591 nsChannel_GetContentDisposition,
1592 nsChannel_SetContentDisposition,
1593 nsChannel_GetContentDispositionFilename,
1594 nsChannel_SetContentDispositionFilename,
1595 nsChannel_GetContentDispositionHeader,
1596 nsChannel_GetLoadInfo,
1597 nsChannel_SetLoadInfo,
1598 nsChannel_GetRequestMethod,
1599 nsChannel_SetRequestMethod,
1600 nsChannel_GetReferrer,
1601 nsChannel_SetReferrer,
1602 nsChannel_GetReferrerPolicy,
1603 nsChannel_SetReferrerWithPolicy,
1604 nsHttpChannel_GetProtocolVersion,
1605 nsHttpChannel_GetTransferSize,
1606 nsHttpChannel_GetDecodedBodySize,
1607 nsHttpChannel_GetEncodedBodySize,
1608 nsChannel_GetRequestHeader,
1609 nsChannel_SetRequestHeader,
1610 nsChannel_SetEmptyRequestHeader,
1611 nsChannel_VisitRequestHeaders,
1612 nsChannel_VisitNonDefaultRequestHeaders,
1613 nsChannel_GetAllowPipelining,
1614 nsChannel_SetAllowPipelining,
1615 nsChannel_GetAllowTLS,
1616 nsChannel_SetAllowTLS,
1617 nsChannel_GetRedirectionLimit,
1618 nsChannel_SetRedirectionLimit,
1619 nsChannel_GetResponseStatus,
1620 nsChannel_GetResponseStatusText,
1621 nsChannel_GetRequestSucceeded,
1622 nsChannel_GetIsMainDocumentChannel,
1623 nsChannel_SetIsMainDocumentChannel,
1624 nsChannel_GetResponseHeader,
1625 nsChannel_SetResponseHeader,
1626 nsChannel_VisitResponseHeaders,
1627 nsChannel_IsNoStoreResponse,
1628 nsChannel_IsNoCacheResponse,
1629 nsChannel_IsPrivateResponse,
1630 nsChannel_RedirectTo,
1631 nsHttpChannel_GetSchedulingContextID,
1632 nsHttpChannel_SetSchedulingContextID
1635 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1637 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1640 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1641 void **result)
1643 nsChannel *This = impl_from_nsIUploadChannel(iface);
1644 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1647 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1649 nsChannel *This = impl_from_nsIUploadChannel(iface);
1650 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1653 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1655 nsChannel *This = impl_from_nsIUploadChannel(iface);
1656 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1659 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1660 nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
1662 nsChannel *This = impl_from_nsIUploadChannel(iface);
1663 const char *content_type;
1665 static const WCHAR content_typeW[] =
1666 {'C','o','n','t','e','n','t','-','T','y','p','e'};
1668 TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));
1670 This->post_data_contains_headers = TRUE;
1672 if(aContentType) {
1673 nsACString_GetData(aContentType, &content_type);
1674 if(*content_type) {
1675 WCHAR *ct;
1677 ct = strdupAtoW(content_type);
1678 if(!ct)
1679 return NS_ERROR_UNEXPECTED;
1681 set_http_header(&This->request_headers, content_typeW, ARRAY_SIZE(content_typeW), ct, lstrlenW(ct));
1682 free(ct);
1683 This->post_data_contains_headers = FALSE;
1687 if(aContentLength != -1)
1688 FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));
1690 if(This->post_data_stream)
1691 nsIInputStream_Release(This->post_data_stream);
1692 This->post_data_stream = aStream;
1693 if(aStream)
1694 nsIInputStream_AddRef(aStream);
1696 This->request_method = METHOD_POST;
1697 return NS_OK;
1700 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1701 nsIInputStream **aUploadStream)
1703 nsChannel *This = impl_from_nsIUploadChannel(iface);
1705 TRACE("(%p)->(%p)\n", This, aUploadStream);
1707 if(This->post_data_stream)
1708 nsIInputStream_AddRef(This->post_data_stream);
1710 *aUploadStream = This->post_data_stream;
1711 return NS_OK;
1714 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1715 nsUploadChannel_QueryInterface,
1716 nsUploadChannel_AddRef,
1717 nsUploadChannel_Release,
1718 nsUploadChannel_SetUploadStream,
1719 nsUploadChannel_GetUploadStream
1722 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1724 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1727 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1728 void **result)
1730 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1731 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1734 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1736 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1737 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1740 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1742 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1743 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1746 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1748 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1750 FIXME("(%p)->()\n", This);
1752 return NS_ERROR_NOT_IMPLEMENTED;
1755 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1757 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1759 TRACE("(%p)->() unimplemented\n", This);
1761 return NS_ERROR_NOT_IMPLEMENTED;
1764 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1766 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1768 FIXME("(%p)->()\n", This);
1770 return NS_ERROR_NOT_IMPLEMENTED;
1773 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1775 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1777 FIXME("(%p)->()\n", This);
1779 return NS_ERROR_NOT_IMPLEMENTED;
1782 static nsresult NSAPI nsHttpChannelInternal_TakeAllSecurityMessages(nsIHttpChannelInternal *iface, void *aMessages)
1784 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1786 TRACE("(%p)->(%p) unimplemented\n", This, aMessages);
1788 return NS_ERROR_NOT_IMPLEMENTED;
1791 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1793 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1795 FIXME("(%p)->()\n", This);
1797 return NS_ERROR_NOT_IMPLEMENTED;
1800 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1802 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1804 FIXME("(%p)->()\n", This);
1806 return NS_ERROR_NOT_IMPLEMENTED;
1809 static nsresult NSAPI nsHttpChannelInternal_GetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 *aThirdPartyFlags)
1811 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1812 FIXME("(%p)->(%p)\n", This, aThirdPartyFlags);
1813 return NS_ERROR_NOT_IMPLEMENTED;
1816 static nsresult NSAPI nsHttpChannelInternal_SetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 aThirdPartyFlags)
1818 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1819 FIXME("(%p)->(%x)\n", This, aThirdPartyFlags);
1820 return NS_ERROR_NOT_IMPLEMENTED;
1823 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
1825 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1827 FIXME("(%p)->()\n", This);
1829 return NS_ERROR_NOT_IMPLEMENTED;
1832 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
1834 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1836 FIXME("(%p)->()\n", This);
1838 return NS_ERROR_NOT_IMPLEMENTED;
1841 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1843 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1845 FIXME("(%p)->(%p)\n", This, aCanceled);
1847 return NS_ERROR_NOT_IMPLEMENTED;
1850 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1852 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1854 FIXME("(%p)->(%p)\n", This, aCanceled);
1856 return NS_ERROR_NOT_IMPLEMENTED;
1859 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
1861 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1863 FIXME("(%p)->(%x)\n", This, aCanceled);
1865 return NS_ERROR_NOT_IMPLEMENTED;
1868 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1870 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1872 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1874 return NS_ERROR_NOT_IMPLEMENTED;
1877 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
1879 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1881 FIXME("(%p)->(%p)\n", This, aLocalPort);
1883 return NS_ERROR_NOT_IMPLEMENTED;
1886 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1888 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1890 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1892 return NS_ERROR_NOT_IMPLEMENTED;
1895 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
1897 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1899 FIXME("(%p)->(%p)\n", This, aRemotePort);
1901 return NS_ERROR_NOT_IMPLEMENTED;
1904 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1906 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1908 FIXME("(%p)->(%p)\n", This, cacheKeys);
1910 return NS_ERROR_NOT_IMPLEMENTED;
1913 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1914 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1916 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1917 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1918 return NS_ERROR_NOT_IMPLEMENTED;
1921 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
1923 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1924 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
1925 return NS_ERROR_NOT_IMPLEMENTED;
1928 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
1930 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1931 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
1932 return NS_ERROR_NOT_IMPLEMENTED;
1935 static nsresult NSAPI nsHttpChannelInternal_GetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1936 cpp_bool *aResponseTimeoutEnabled)
1938 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1939 FIXME("(%p)->(%p)\n", This, aResponseTimeoutEnabled);
1940 return NS_ERROR_NOT_IMPLEMENTED;
1943 static nsresult NSAPI nsHttpChannelInternal_SetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1944 cpp_bool aResponseTimeoutEnabled)
1946 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1947 FIXME("(%p)->(%x)\n", This, aResponseTimeoutEnabled);
1948 return NS_ERROR_NOT_IMPLEMENTED;
1951 static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface,
1952 UINT32 *aInitialRwin)
1954 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1955 FIXME("(%p)->(%p)\n", This, aInitialRwin);
1956 return NS_ERROR_NOT_IMPLEMENTED;
1959 static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface,
1960 UINT32 aInitialRwin)
1962 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1963 FIXME("(%p)->(%x)\n", This, aInitialRwin);
1964 return NS_ERROR_NOT_IMPLEMENTED;
1967 static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI)
1969 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1970 FIXME("(%p)->(%p)\n", This, aApiRedirectToURI);
1971 return NS_ERROR_NOT_IMPLEMENTED;
1974 static nsresult NSAPI nsHttpChannelInternal_GetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool *aAllowAltSvc)
1976 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1977 FIXME("(%p)->(%p)\n", This, aAllowAltSvc);
1978 return NS_ERROR_NOT_IMPLEMENTED;
1981 static nsresult NSAPI nsHttpChannelInternal_SetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool aAllowAltSvc)
1983 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1984 FIXME("(%p)->(%x)\n", This, aAllowAltSvc);
1985 return NS_ERROR_NOT_IMPLEMENTED;
1988 static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime)
1990 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1991 FIXME("(%p)->(%p)\n", This, aLastModifiedTime);
1992 return NS_ERROR_NOT_IMPLEMENTED;
1995 static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID)
1997 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1998 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID));
1999 return NS_ERROR_NOT_IMPLEMENTED;
2002 static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized)
2004 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2005 FIXME("(%p, %p)\n", This, ResponseSynthesized);
2006 return NS_ERROR_NOT_IMPLEMENTED;
2009 static nsresult NSAPI nsHttpChannelInternal_GetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2010 cpp_bool *aCorsIncludeCredentials)
2012 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2013 FIXME("(%p)->(%p)\n", This, aCorsIncludeCredentials);
2014 return NS_ERROR_NOT_IMPLEMENTED;
2017 static nsresult NSAPI nsHttpChannelInternal_SetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2018 cpp_bool aCorsIncludeCredentials)
2020 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2021 TRACE("(%p)->(%x)\n", This, aCorsIncludeCredentials);
2022 return NS_OK;
2025 static nsresult NSAPI nsHttpChannelInternal_GetCorsMode(nsIHttpChannelInternal *iface, UINT32 *aCorsMode)
2027 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2028 FIXME("(%p)->(%p)\n", This, aCorsMode);
2029 return NS_ERROR_NOT_IMPLEMENTED;
2032 static nsresult NSAPI nsHttpChannelInternal_SetCorsMode(nsIHttpChannelInternal *iface, UINT32 aCorsMode)
2034 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2035 TRACE("(%p)->(%d)\n", This, aCorsMode);
2036 return NS_OK;
2039 static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode)
2041 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2042 FIXME("(%p)->(%p)\n", This, aRedirectMode);
2043 return NS_ERROR_NOT_IMPLEMENTED;
2046 static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode)
2048 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2049 TRACE("(%p)->(%d) unimplemented\n", This, aRedirectMode);
2050 return NS_ERROR_NOT_IMPLEMENTED;
2053 static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI)
2055 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2056 FIXME("(%p)->(%p)\n", This, aTopWindowURI);
2057 return NS_ERROR_NOT_IMPLEMENTED;
2060 static nsresult NSAPI nsHttpChannelInternal_GetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2061 nsACString *aNetworkInterfaceId)
2063 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2064 FIXME("(%p)->(%p)\n", This, aNetworkInterfaceId);
2065 return NS_ERROR_NOT_IMPLEMENTED;
2068 static nsresult NSAPI nsHttpChannelInternal_SetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2069 const nsACString *aNetworkInterfaceId)
2071 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2072 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aNetworkInterfaceId));
2073 return NS_ERROR_NOT_IMPLEMENTED;
2076 static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI)
2078 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2079 FIXME("(%p)->(%p)\n", This, aProxyURI);
2080 return NS_ERROR_NOT_IMPLEMENTED;
2083 static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface,
2084 const void /*nsTArray<nsCString>*/ *unsafeHeaders)
2086 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2087 FIXME("(%p)->(%p)\n", This, unsafeHeaders);
2088 return NS_ERROR_NOT_IMPLEMENTED;
2091 static nsresult NSAPI nsHttpChannelInternal_GetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool *aBlockAuthPrompt)
2093 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2094 FIXME("(%p)->(%p)\n", This, aBlockAuthPrompt);
2095 return NS_ERROR_NOT_IMPLEMENTED;
2098 static nsresult NSAPI nsHttpChannelInternal_SetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool aBlockAuthPrompt)
2100 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2101 FIXME("(%p)->(%x)\n", This, aBlockAuthPrompt);
2102 return NS_ERROR_NOT_IMPLEMENTED;
2105 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
2106 nsHttpChannelInternal_QueryInterface,
2107 nsHttpChannelInternal_AddRef,
2108 nsHttpChannelInternal_Release,
2109 nsHttpChannelInternal_GetDocumentURI,
2110 nsHttpChannelInternal_SetDocumentURI,
2111 nsHttpChannelInternal_GetRequestVersion,
2112 nsHttpChannelInternal_GetResponseVersion,
2113 nsHttpChannelInternal_TakeAllSecurityMessages,
2114 nsHttpChannelInternal_SetCookie,
2115 nsHttpChannelInternal_SetupFallbackChannel,
2116 nsHttpChannelInternal_GetThirdPartyFlags,
2117 nsHttpChannelInternal_SetThirdPartyFlags,
2118 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
2119 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
2120 nsHttpChannelInternal_GetCanceled,
2121 nsHttpChannelInternal_GetChannelIsForDownload,
2122 nsHttpChannelInternal_SetChannelIsForDownload,
2123 nsHttpChannelInternal_GetLocalAddress,
2124 nsHttpChannelInternal_GetLocalPort,
2125 nsHttpChannelInternal_GetRemoteAddress,
2126 nsHttpChannelInternal_GetRemotePort,
2127 nsHttpChannelInternal_SetCacheKeysRedirectChain,
2128 nsHttpChannelInternal_HTTPUpgrade,
2129 nsHttpChannelInternal_GetAllowSpdy,
2130 nsHttpChannelInternal_SetAllowSpdy,
2131 nsHttpChannelInternal_GetResponseTimeoutEnabled,
2132 nsHttpChannelInternal_SetResponseTimeoutEnabled,
2133 nsHttpChannelInternal_GetInitialRwin,
2134 nsHttpChannelInternal_SetInitialRwin,
2135 nsHttpChannelInternal_GetApiRedirectToURI,
2136 nsHttpChannelInternal_GetAllowAltSvc,
2137 nsHttpChannelInternal_SetAllowAltSvc,
2138 nsHttpChannelInternal_GetLastModifiedTime,
2139 nsHttpChannelInternal_ForceIntercepted,
2140 nsHttpChannelInternal_GetResponseSynthesized,
2141 nsHttpChannelInternal_GetCorsIncludeCredentials,
2142 nsHttpChannelInternal_SetCorsIncludeCredentials,
2143 nsHttpChannelInternal_GetCorsMode,
2144 nsHttpChannelInternal_SetCorsMode,
2145 nsHttpChannelInternal_GetRedirectMode,
2146 nsHttpChannelInternal_SetRedirectMode,
2147 nsHttpChannelInternal_GetTopWindowURI,
2148 nsHttpChannelInternal_GetNetworkInterfaceId,
2149 nsHttpChannelInternal_SetNetworkInterfaceId,
2150 nsHttpChannelInternal_GetProxyURI,
2151 nsHttpChannelInternal_SetCorsPreflightParameters,
2152 nsHttpChannelInternal_GetBlockAuthPrompt,
2153 nsHttpChannelInternal_SetBlockAuthPrompt
2156 static inline nsChannel *impl_from_nsICacheInfoChannel(nsICacheInfoChannel *iface)
2158 return CONTAINING_RECORD(iface, nsChannel, nsICacheInfoChannel_iface);
2161 static nsresult NSAPI nsCacheInfoChannel_QueryInterface(nsICacheInfoChannel *iface, nsIIDRef riid,
2162 void **result)
2164 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2165 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
2168 static nsrefcnt NSAPI nsCacheInfoChannel_AddRef(nsICacheInfoChannel *iface)
2170 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2171 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
2174 static nsrefcnt NSAPI nsCacheInfoChannel_Release(nsICacheInfoChannel *iface)
2176 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2177 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
2180 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenExpirationTime(nsICacheInfoChannel *iface, UINT32 *p)
2182 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2183 FIXME("(%p)->(%p)\n", This, p);
2184 return E_NOTIMPL;
2187 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenCachedCharset(nsICacheInfoChannel *iface, nsACString *p)
2189 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2190 FIXME("(%p)->(%p)\n", This, p);
2191 return E_NOTIMPL;
2194 static nsresult NSAPI nsCacheInfoChannel_SetCacheTokenCachedCharset(nsICacheInfoChannel *iface, const nsACString *p)
2196 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2197 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(p));
2198 return E_NOTIMPL;
2201 static nsresult NSAPI nsCacheInfoChannel_IsFromCache(nsICacheInfoChannel *iface, cpp_bool *p)
2203 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2204 FIXME("(%p)->(%p)\n", This, p);
2205 *p = FALSE;
2206 return NS_OK;
2209 static nsresult NSAPI nsCacheInfoChannel_GetCacheKey(nsICacheInfoChannel *iface, nsISupports **p)
2211 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2212 FIXME("(%p)->(%p)\n", This, p);
2213 return E_NOTIMPL;
2216 static nsresult NSAPI nsCacheInfoChannel_SetCacheKey(nsICacheInfoChannel *iface, nsISupports *key)
2218 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2219 FIXME("(%p)->(%p)\n", This, key);
2220 return E_NOTIMPL;
2223 static nsresult NSAPI nsCacheInfoChannel_GetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool *p)
2225 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2226 FIXME("(%p)->(%p)\n", This, p);
2227 return E_NOTIMPL;
2230 static nsresult NSAPI nsCacheInfoChannel_SetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool allow)
2232 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2233 FIXME("(%p)->(%x)\n", This, allow);
2234 return E_NOTIMPL;
2237 static const nsICacheInfoChannelVtbl nsCacheInfoChannelVtbl = {
2238 nsCacheInfoChannel_QueryInterface,
2239 nsCacheInfoChannel_AddRef,
2240 nsCacheInfoChannel_Release,
2241 nsCacheInfoChannel_GetCacheTokenExpirationTime,
2242 nsCacheInfoChannel_GetCacheTokenCachedCharset,
2243 nsCacheInfoChannel_SetCacheTokenCachedCharset,
2244 nsCacheInfoChannel_IsFromCache,
2245 nsCacheInfoChannel_GetCacheKey,
2246 nsCacheInfoChannel_SetCacheKey,
2247 nsCacheInfoChannel_GetAllowStaleCacheContent,
2248 nsCacheInfoChannel_SetAllowStaleCacheContent
2251 static nsresult NSAPI nsChannel_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb)
2253 nsChannel *This = impl_from_nsIHttpChannel(p);
2255 TRACE("%p\n", This);
2257 describe_cc_node(&This->ccref, "nsChannel", cb);
2259 if(This->owner)
2260 note_cc_edge(This->owner, "owner", cb);
2261 if(This->post_data_stream)
2262 note_cc_edge((nsISupports*)This->post_data_stream, "post_data_stream", cb);
2263 if(This->load_info)
2264 note_cc_edge(This->load_info, "load_info", cb);
2265 if(This->load_group)
2266 note_cc_edge((nsISupports*)This->load_group, "load_group", cb);
2267 if(This->notif_callback)
2268 note_cc_edge((nsISupports*)This->notif_callback, "notif_callback", cb);
2269 if(This->original_uri)
2270 note_cc_edge((nsISupports*)This->original_uri, "original_uri", cb);
2271 if(This->referrer)
2272 note_cc_edge((nsISupports*)This->referrer, "referrer", cb);
2274 return NS_OK;
2277 static nsresult NSAPI nsChannel_unlink(void *p)
2279 nsChannel *This = impl_from_nsIHttpChannel(p);
2281 TRACE("%p\n", This);
2283 unlink_ref(&This->owner);
2284 unlink_ref(&This->post_data_stream);
2285 unlink_ref(&This->load_info);
2286 unlink_ref(&This->load_group);
2287 unlink_ref(&This->notif_callback);
2288 unlink_ref(&This->original_uri);
2289 unlink_ref(&This->referrer);
2290 return NS_OK;
2293 static void NSAPI nsChannel_delete_cycle_collectable(void *p)
2295 nsChannel *This = impl_from_nsIHttpChannel(p);
2296 nsChannel_unlink(p);
2298 TRACE("(%p)\n", This);
2300 nsIFileURL_Release(&This->uri->nsIFileURL_iface);
2301 free_http_headers(&This->response_headers);
2302 free_http_headers(&This->request_headers);
2304 free(This->content_type);
2305 free(This->charset);
2306 free(This);
2309 static BOOL ensure_uri_builder(nsWineURI *This)
2311 if(!This->is_mutable) {
2312 WARN("Not mutable URI\n");
2313 return FALSE;
2316 if(!This->uri_builder) {
2317 HRESULT hres;
2319 if(!ensure_uri(This))
2320 return FALSE;
2322 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
2323 if(FAILED(hres)) {
2324 WARN("CreateIUriBuilder failed: %08lx\n", hres);
2325 return FALSE;
2329 unlink_ref(&This->uri);
2330 return TRUE;
2333 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
2335 char *vala;
2336 BSTR val;
2337 HRESULT hres;
2339 if(!ensure_uri(This))
2340 return NS_ERROR_UNEXPECTED;
2342 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
2343 if(FAILED(hres)) {
2344 WARN("GetPropertyBSTR failed: %08lx\n", hres);
2345 return NS_ERROR_UNEXPECTED;
2348 vala = strdupWtoU(hres == S_OK ? val : NULL);
2349 SysFreeString(val);
2350 if(hres == S_OK && !vala)
2351 return NS_ERROR_OUT_OF_MEMORY;
2353 TRACE("ret %s\n", debugstr_a(vala));
2354 nsACString_SetData(ret, vala);
2355 free(vala);
2356 return NS_OK;
2359 static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
2361 return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
2364 static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
2366 nsWineURI *This = impl_from_nsIFileURL(iface);
2368 *result = NULL;
2370 if(IsEqualGUID(&IID_nsISupports, riid)) {
2371 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2372 *result = &This->nsIFileURL_iface;
2373 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
2374 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
2375 *result = &This->nsIFileURL_iface;
2376 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
2377 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
2378 *result = &This->nsIFileURL_iface;
2379 }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
2380 TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
2381 *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
2382 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
2383 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
2384 *result = &This->nsIStandardURL_iface;
2385 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
2386 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
2387 *result = &This->nsIStandardURL_iface;
2388 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
2389 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
2390 *result = This;
2393 if(*result) {
2394 nsIFileURL_AddRef(&This->nsIFileURL_iface);
2395 return NS_OK;
2398 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
2399 return NS_NOINTERFACE;
2402 static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
2404 nsWineURI *This = impl_from_nsIFileURL(iface);
2405 LONG ref = InterlockedIncrement(&This->ref);
2407 TRACE("(%p) ref=%ld\n", This, ref);
2409 return ref;
2412 static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
2414 nsWineURI *This = impl_from_nsIFileURL(iface);
2415 LONG ref = InterlockedDecrement(&This->ref);
2417 TRACE("(%p) ref=%ld\n", This, ref);
2419 if(!ref) {
2420 if(This->uri)
2421 IUri_Release(This->uri);
2422 if(This->uri_builder)
2423 IUriBuilder_Release(This->uri_builder);
2424 free(This);
2427 return ref;
2430 static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
2432 nsWineURI *This = impl_from_nsIFileURL(iface);
2434 TRACE("(%p)->(%p)\n", This, aSpec);
2436 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
2439 static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
2441 nsWineURI *This = impl_from_nsIFileURL(iface);
2442 const char *speca;
2443 WCHAR *spec;
2444 IUri *uri;
2445 HRESULT hres;
2447 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
2449 if(!This->is_mutable)
2450 return NS_ERROR_UNEXPECTED;
2452 nsACString_GetData(aSpec, &speca);
2453 spec = strdupUtoW(speca);
2454 if(!spec)
2455 return NS_ERROR_OUT_OF_MEMORY;
2457 hres = create_uri(spec, 0, &uri);
2458 free(spec);
2459 if(FAILED(hres)) {
2460 WARN("create_uri failed: %08lx\n", hres);
2461 return NS_ERROR_FAILURE;
2464 unlink_ref(&This->uri);
2465 unlink_ref(&This->uri_builder);
2467 This->uri = uri;
2468 return NS_OK;
2471 static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
2473 nsWineURI *This = impl_from_nsIFileURL(iface);
2474 IUriBuilder *uri_builder;
2475 BSTR display_uri;
2476 IUri *uri;
2477 int len;
2478 nsresult nsres;
2479 HRESULT hres;
2481 TRACE("(%p)->(%p)\n", This, aPrePath);
2483 if(!ensure_uri(This))
2484 return NS_ERROR_UNEXPECTED;
2486 hres = CreateIUriBuilder(This->uri, 0, 0, &uri_builder);
2487 if(FAILED(hres))
2488 return NS_ERROR_FAILURE;
2490 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_PATH|Uri_HAS_QUERY|Uri_HAS_FRAGMENT);
2491 if(SUCCEEDED(hres))
2492 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &uri);
2493 IUriBuilder_Release(uri_builder);
2494 if(FAILED(hres))
2495 return NS_ERROR_FAILURE;
2497 hres = IUri_GetDisplayUri(uri, &display_uri);
2498 IUri_Release(uri);
2499 if(FAILED(hres))
2500 return NS_ERROR_FAILURE;
2502 /* Remove trailing slash that may be appended as default path. */
2503 len = SysStringLen(display_uri);
2504 if(len && display_uri[len-1] == '/')
2505 display_uri[len-1] = 0;
2507 nsres = return_wstr_nsacstr(aPrePath, display_uri, -1);
2508 SysFreeString(display_uri);
2509 return nsres;
2512 static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
2514 nsWineURI *This = impl_from_nsIFileURL(iface);
2515 DWORD scheme;
2516 HRESULT hres;
2518 TRACE("(%p)->(%p)\n", This, aScheme);
2520 if(!ensure_uri(This))
2521 return NS_ERROR_UNEXPECTED;
2523 hres = IUri_GetScheme(This->uri, &scheme);
2524 if(FAILED(hres)) {
2525 WARN("GetScheme failed: %08lx\n", hres);
2526 return NS_ERROR_UNEXPECTED;
2529 if(scheme == URL_SCHEME_ABOUT) {
2530 nsACString_SetData(aScheme, "wine");
2531 return NS_OK;
2534 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
2537 static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
2539 nsWineURI *This = impl_from_nsIFileURL(iface);
2540 const char *schemea;
2541 WCHAR *scheme;
2542 HRESULT hres;
2544 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
2546 if(!ensure_uri_builder(This))
2547 return NS_ERROR_UNEXPECTED;
2549 nsACString_GetData(aScheme, &schemea);
2550 scheme = strdupUtoW(schemea);
2551 if(!scheme)
2552 return NS_ERROR_OUT_OF_MEMORY;
2554 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
2555 free(scheme);
2556 if(FAILED(hres))
2557 return NS_ERROR_UNEXPECTED;
2559 return NS_OK;
2562 static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
2564 nsWineURI *This = impl_from_nsIFileURL(iface);
2565 BSTR user, pass;
2566 HRESULT hres;
2568 TRACE("(%p)->(%p)\n", This, aUserPass);
2570 if(!ensure_uri(This))
2571 return NS_ERROR_UNEXPECTED;
2573 hres = IUri_GetUserName(This->uri, &user);
2574 if(FAILED(hres))
2575 return NS_ERROR_FAILURE;
2577 hres = IUri_GetPassword(This->uri, &pass);
2578 if(FAILED(hres)) {
2579 SysFreeString(user);
2580 return NS_ERROR_FAILURE;
2583 if(*user || *pass) {
2584 FIXME("Construct user:pass string\n");
2585 }else {
2586 nsACString_SetData(aUserPass, "");
2589 SysFreeString(user);
2590 SysFreeString(pass);
2591 return NS_OK;
2594 static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
2596 nsWineURI *This = impl_from_nsIFileURL(iface);
2597 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
2598 const char *user_pass;
2599 HRESULT hres;
2601 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
2603 if(!ensure_uri_builder(This))
2604 return NS_ERROR_UNEXPECTED;
2606 nsACString_GetData(aUserPass, &user_pass);
2607 if(*user_pass) {
2608 WCHAR *ptr;
2610 buf = strdupUtoW(user_pass);
2611 if(!buf)
2612 return NS_ERROR_OUT_OF_MEMORY;
2614 ptr = wcschr(buf, ':');
2615 if(!ptr) {
2616 user = buf;
2617 }else if(ptr != buf) {
2618 *ptr++ = 0;
2619 user = buf;
2620 if(*ptr)
2621 pass = ptr;
2622 }else {
2623 pass = buf+1;
2627 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2628 if(SUCCEEDED(hres))
2629 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2631 free(buf);
2632 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2635 static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
2637 nsWineURI *This = impl_from_nsIFileURL(iface);
2639 TRACE("(%p)->(%p)\n", This, aUsername);
2641 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2644 static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
2646 nsWineURI *This = impl_from_nsIFileURL(iface);
2647 const char *usera;
2648 WCHAR *user;
2649 HRESULT hres;
2651 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2653 if(!ensure_uri_builder(This))
2654 return NS_ERROR_UNEXPECTED;
2656 nsACString_GetData(aUsername, &usera);
2657 user = strdupUtoW(usera);
2658 if(!user)
2659 return NS_ERROR_OUT_OF_MEMORY;
2661 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2662 free(user);
2663 if(FAILED(hres))
2664 return NS_ERROR_UNEXPECTED;
2666 return NS_OK;
2669 static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
2671 nsWineURI *This = impl_from_nsIFileURL(iface);
2673 TRACE("(%p)->(%p)\n", This, aPassword);
2675 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2678 static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
2680 nsWineURI *This = impl_from_nsIFileURL(iface);
2681 const char *passa;
2682 WCHAR *pass;
2683 HRESULT hres;
2685 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2687 if(!ensure_uri_builder(This))
2688 return NS_ERROR_UNEXPECTED;
2690 nsACString_GetData(aPassword, &passa);
2691 pass = strdupUtoW(passa);
2692 if(!pass)
2693 return NS_ERROR_OUT_OF_MEMORY;
2695 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2696 free(pass);
2697 if(FAILED(hres))
2698 return NS_ERROR_UNEXPECTED;
2700 return NS_OK;
2703 static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
2705 nsWineURI *This = impl_from_nsIFileURL(iface);
2706 const WCHAR *ptr = NULL;
2707 char *vala;
2708 BSTR val;
2709 HRESULT hres;
2711 TRACE("(%p)->(%p)\n", This, aHostPort);
2713 if(!ensure_uri(This))
2714 return NS_ERROR_UNEXPECTED;
2716 hres = IUri_GetAuthority(This->uri, &val);
2717 if(FAILED(hres)) {
2718 WARN("GetAuthority failed: %08lx\n", hres);
2719 return NS_ERROR_UNEXPECTED;
2722 if(hres == S_OK) {
2723 ptr = wcschr(val, '@');
2724 if(!ptr)
2725 ptr = val;
2727 vala = strdupWtoU(ptr);
2728 SysFreeString(val);
2729 if(hres == S_OK && !vala)
2730 return NS_ERROR_OUT_OF_MEMORY;
2732 TRACE("ret %s\n", debugstr_a(vala));
2733 nsACString_SetData(aHostPort, vala);
2734 free(vala);
2735 return NS_OK;
2738 static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
2740 nsWineURI *This = impl_from_nsIFileURL(iface);
2742 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2744 /* Not implemented by Gecko */
2745 return NS_ERROR_NOT_IMPLEMENTED;
2748 static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
2750 nsWineURI *This = impl_from_nsIFileURL(iface);
2752 TRACE("(%p)->(%p)\n", This, aHost);
2754 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2757 static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
2759 nsWineURI *This = impl_from_nsIFileURL(iface);
2760 const char *hosta;
2761 WCHAR *host;
2762 HRESULT hres;
2764 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2766 if(!ensure_uri_builder(This))
2767 return NS_ERROR_UNEXPECTED;
2769 nsACString_GetData(aHost, &hosta);
2770 host = strdupUtoW(hosta);
2771 if(!host)
2772 return NS_ERROR_OUT_OF_MEMORY;
2774 hres = IUriBuilder_SetHost(This->uri_builder, host);
2775 free(host);
2776 if(FAILED(hres))
2777 return NS_ERROR_UNEXPECTED;
2779 return NS_OK;
2782 static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
2784 nsWineURI *This = impl_from_nsIFileURL(iface);
2785 DWORD port;
2786 HRESULT hres;
2788 TRACE("(%p)->(%p)\n", This, aPort);
2790 if(!ensure_uri(This))
2791 return NS_ERROR_UNEXPECTED;
2793 hres = IUri_GetPort(This->uri, &port);
2794 if(FAILED(hres)) {
2795 WARN("GetPort failed: %08lx\n", hres);
2796 return NS_ERROR_UNEXPECTED;
2799 *aPort = port ? port : -1;
2800 return NS_OK;
2803 static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
2805 nsWineURI *This = impl_from_nsIFileURL(iface);
2806 HRESULT hres;
2808 TRACE("(%p)->(%ld)\n", This, aPort);
2810 if(!ensure_uri_builder(This))
2811 return NS_ERROR_UNEXPECTED;
2813 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2814 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2817 static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
2819 nsWineURI *This = impl_from_nsIFileURL(iface);
2821 TRACE("(%p)->(%p)\n", This, aPath);
2823 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2826 static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
2828 nsWineURI *This = impl_from_nsIFileURL(iface);
2829 const char *patha;
2830 WCHAR *path;
2831 HRESULT hres;
2833 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2835 if(!ensure_uri_builder(This))
2836 return NS_ERROR_UNEXPECTED;
2838 nsACString_GetData(aPath, &patha);
2839 path = strdupUtoW(patha);
2840 if(!path)
2841 return NS_ERROR_OUT_OF_MEMORY;
2843 hres = IUriBuilder_SetPath(This->uri_builder, path);
2844 free(path);
2845 if(FAILED(hres))
2846 return NS_ERROR_UNEXPECTED;
2848 return NS_OK;
2851 static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2853 nsWineURI *This = impl_from_nsIFileURL(iface);
2854 nsWineURI *other_obj;
2855 nsresult nsres;
2856 HRESULT hres;
2858 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2860 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2861 if(NS_FAILED(nsres)) {
2862 TRACE("Could not get nsWineURI interface\n");
2863 *_retval = FALSE;
2864 return NS_OK;
2867 if(ensure_uri(This) && ensure_uri(other_obj)) {
2868 BOOL b;
2870 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2871 if(SUCCEEDED(hres)) {
2872 *_retval = b;
2873 nsres = NS_OK;
2874 }else {
2875 nsres = NS_ERROR_FAILURE;
2877 }else {
2878 nsres = NS_ERROR_UNEXPECTED;
2881 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2882 return nsres;
2885 static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
2887 nsWineURI *This = impl_from_nsIFileURL(iface);
2888 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2889 BSTR scheme_name;
2890 HRESULT hres;
2892 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2894 if(!ensure_uri(This))
2895 return NS_ERROR_UNEXPECTED;
2897 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2898 if(FAILED(hres))
2899 return NS_ERROR_UNEXPECTED;
2901 if(hres != S_OK)
2902 *_retval = FALSE;
2903 else {
2904 MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, ARRAY_SIZE(buf));
2905 *_retval = !wcscmp(scheme_name, buf);
2907 SysFreeString(scheme_name);
2908 return NS_OK;
2911 static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
2913 nsWineURI *This = impl_from_nsIFileURL(iface);
2914 nsWineURI *wine_uri;
2915 nsresult nsres;
2917 TRACE("(%p)->(%p)\n", This, _retval);
2919 if(!ensure_uri(This))
2920 return NS_ERROR_UNEXPECTED;
2922 nsres = create_nsuri(This->uri, &wine_uri);
2923 if(NS_FAILED(nsres)) {
2924 WARN("create_nsuri failed: %08lx\n", nsres);
2925 return nsres;
2928 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2929 return NS_OK;
2932 static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
2933 nsACString *_retval)
2935 nsWineURI *This = impl_from_nsIFileURL(iface);
2936 const char *patha;
2937 IUri *new_uri;
2938 WCHAR *path;
2939 char *reta;
2940 BSTR ret;
2941 HRESULT hres;
2943 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2945 if(!ensure_uri(This))
2946 return NS_ERROR_UNEXPECTED;
2948 nsACString_GetData(aRelativePath, &patha);
2949 path = strdupUtoW(patha);
2950 if(!path)
2951 return NS_ERROR_OUT_OF_MEMORY;
2953 hres = combine_url(This->uri, path, &new_uri);
2954 free(path);
2955 if(FAILED(hres))
2956 return NS_ERROR_FAILURE;
2958 hres = IUri_GetDisplayUri(new_uri, &ret);
2959 IUri_Release(new_uri);
2960 if(FAILED(hres))
2961 return NS_ERROR_FAILURE;
2963 reta = strdupWtoU(ret);
2964 SysFreeString(ret);
2965 if(!reta)
2966 return NS_ERROR_OUT_OF_MEMORY;
2968 TRACE("returning %s\n", debugstr_a(reta));
2969 nsACString_SetData(_retval, reta);
2970 free(reta);
2971 return NS_OK;
2974 static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
2976 nsWineURI *This = impl_from_nsIFileURL(iface);
2978 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2980 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
2983 static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort)
2985 nsWineURI *This = impl_from_nsIFileURL(iface);
2987 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort);
2989 return nsIFileURL_GetHostPort(&This->nsIFileURL_iface, aAsciiHostPort);
2992 static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
2994 nsWineURI *This = impl_from_nsIFileURL(iface);
2996 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2998 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
3001 static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
3003 nsWineURI *This = impl_from_nsIFileURL(iface);
3005 TRACE("(%p)->(%p)\n", This, aOriginCharset);
3007 nsACString_SetData(aOriginCharset, NULL); /* assume utf-8, we store URI as utf-16 anyway */
3008 return NS_OK;
3011 static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
3013 nsWineURI *This = impl_from_nsIFileURL(iface);
3014 char *refa = NULL;
3015 BSTR ref;
3016 HRESULT hres;
3018 TRACE("(%p)->(%p)\n", This, aRef);
3020 if(!ensure_uri(This))
3021 return NS_ERROR_UNEXPECTED;
3023 hres = IUri_GetFragment(This->uri, &ref);
3024 if(FAILED(hres))
3025 return NS_ERROR_UNEXPECTED;
3027 refa = strdupWtoU(ref);
3028 SysFreeString(ref);
3029 if(ref && !refa)
3030 return NS_ERROR_OUT_OF_MEMORY;
3032 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
3033 free(refa);
3034 return NS_OK;
3037 static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
3039 nsWineURI *This = impl_from_nsIFileURL(iface);
3040 const char *refa;
3041 WCHAR *ref;
3042 HRESULT hres;
3044 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
3046 if(!ensure_uri_builder(This))
3047 return NS_ERROR_UNEXPECTED;
3049 nsACString_GetData(aRef, &refa);
3050 ref = strdupUtoW(refa);
3051 if(!ref)
3052 return NS_ERROR_OUT_OF_MEMORY;
3054 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
3055 free(ref);
3056 if(FAILED(hres))
3057 return NS_ERROR_UNEXPECTED;
3059 return NS_OK;
3062 static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
3064 nsWineURI *This = impl_from_nsIFileURL(iface);
3065 nsWineURI *other_obj;
3066 nsresult nsres;
3068 TRACE("(%p)->(%p %p)\n", This, other, _retval);
3070 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
3071 if(NS_FAILED(nsres)) {
3072 TRACE("Could not get nsWineURI interface\n");
3073 *_retval = FALSE;
3074 return NS_OK;
3077 if(ensure_uri(This) && ensure_uri(other_obj)) {
3078 *_retval = compare_uri_ignoring_frag(This->uri, other_obj->uri);
3079 nsres = NS_OK;
3080 }else {
3081 nsres = NS_ERROR_UNEXPECTED;
3084 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
3085 return nsres;
3088 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
3090 nsWineURI *This = impl_from_nsIFileURL(iface);
3091 nsWineURI *wine_uri;
3092 IUri *uri;
3093 nsresult nsres;
3095 TRACE("(%p)->(%p)\n", This, _retval);
3097 if(!ensure_uri(This))
3098 return NS_ERROR_UNEXPECTED;
3100 uri = get_uri_nofrag(This->uri);
3101 if(!uri)
3102 return NS_ERROR_FAILURE;
3104 nsres = create_nsuri(uri, &wine_uri);
3105 IUri_Release(uri);
3106 if(NS_FAILED(nsres)) {
3107 WARN("create_nsuri failed: %08lx\n", nsres);
3108 return nsres;
3111 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3112 return NS_OK;
3115 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
3117 nsWineURI *This = impl_from_nsIFileURL(iface);
3119 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
3121 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
3124 static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
3126 nsWineURI *This = impl_from_nsIFileURL(iface);
3127 BOOL b;
3128 HRESULT hres;
3130 TRACE("(%p)->(%p)\n", This, aHasRef);
3132 if(!ensure_uri(This))
3133 return NS_ERROR_UNEXPECTED;
3135 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
3136 if(FAILED(hres))
3137 return NS_ERROR_FAILURE;
3139 *aHasRef = b;
3140 return NS_OK;
3143 static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
3145 nsWineURI *This = impl_from_nsIFileURL(iface);
3147 TRACE("(%p)->(%p)\n", This, aFilePath);
3149 return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
3152 static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
3154 nsWineURI *This = impl_from_nsIFileURL(iface);
3156 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
3158 if(!This->is_mutable)
3159 return NS_ERROR_UNEXPECTED;
3161 return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
3164 static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
3166 nsWineURI *This = impl_from_nsIFileURL(iface);
3167 WCHAR *ptr;
3168 BSTR query;
3169 nsresult nsres;
3170 HRESULT hres;
3172 TRACE("(%p)->(%p)\n", This, aQuery);
3174 if(!ensure_uri(This))
3175 return NS_ERROR_UNEXPECTED;
3177 hres = IUri_GetQuery(This->uri, &query);
3178 if(FAILED(hres))
3179 return NS_ERROR_FAILURE;
3181 ptr = query;
3182 if(ptr && *ptr == '?')
3183 ptr++;
3185 nsres = return_wstr_nsacstr(aQuery, ptr, -1);
3186 SysFreeString(query);
3187 return nsres;
3190 static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
3192 nsWineURI *This = impl_from_nsIFileURL(iface);
3193 const char *querya;
3194 WCHAR *query;
3195 HRESULT hres;
3197 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
3199 if(!ensure_uri_builder(This))
3200 return NS_ERROR_UNEXPECTED;
3202 nsACString_GetData(aQuery, &querya);
3203 query = strdupUtoW(querya);
3204 if(!query)
3205 return NS_ERROR_OUT_OF_MEMORY;
3207 hres = IUriBuilder_SetQuery(This->uri_builder, query);
3208 free(query);
3209 if(FAILED(hres))
3210 return NS_ERROR_UNEXPECTED;
3212 return NS_OK;
3215 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
3217 const WCHAR *ptr;
3218 HRESULT hres;
3220 if(!ensure_uri(This))
3221 return NS_ERROR_UNEXPECTED;
3223 hres = IUri_GetPath(This->uri, path);
3224 if(FAILED(hres))
3225 return NS_ERROR_FAILURE;
3226 if(hres != S_OK) {
3227 SysFreeString(*path);
3228 *ext = *file = *path = NULL;
3229 return NS_OK;
3232 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
3233 if(*ptr == '/' || *ptr == '\\')
3234 ptr++;
3235 *file = ptr;
3237 if(ext) {
3238 ptr = wcsrchr(ptr, '.');
3239 if(!ptr)
3240 ptr = *path + SysStringLen(*path);
3241 *ext = ptr;
3244 return NS_OK;
3247 static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
3249 nsWineURI *This = impl_from_nsIFileURL(iface);
3250 const WCHAR *file;
3251 BSTR path;
3252 nsresult nsres;
3254 TRACE("(%p)->(%p)\n", This, aDirectory);
3256 nsres = get_uri_path(This, &path, &file, NULL);
3257 if(NS_FAILED(nsres))
3258 return nsres;
3260 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
3261 SysFreeString(path);
3262 return nsres;
3265 static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
3267 nsWineURI *This = impl_from_nsIFileURL(iface);
3269 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
3271 /* Not implemented by Gecko */
3272 return NS_ERROR_NOT_IMPLEMENTED;
3275 static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
3277 nsWineURI *This = impl_from_nsIFileURL(iface);
3278 const WCHAR *file;
3279 BSTR path;
3280 nsresult nsres;
3282 TRACE("(%p)->(%p)\n", This, aFileName);
3284 nsres = get_uri_path(This, &path, &file, NULL);
3285 if(NS_FAILED(nsres))
3286 return nsres;
3288 nsres = return_wstr_nsacstr(aFileName, file, -1);
3289 SysFreeString(path);
3290 return nsres;
3293 static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
3295 nsWineURI *This = impl_from_nsIFileURL(iface);
3296 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
3297 return NS_ERROR_NOT_IMPLEMENTED;
3300 static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
3302 nsWineURI *This = impl_from_nsIFileURL(iface);
3303 const WCHAR *file, *ext;
3304 BSTR path;
3305 nsresult nsres;
3307 TRACE("(%p)->(%p)\n", This, aFileBaseName);
3309 nsres = get_uri_path(This, &path, &file, &ext);
3310 if(NS_FAILED(nsres))
3311 return nsres;
3313 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
3314 SysFreeString(path);
3315 return nsres;
3318 static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
3320 nsWineURI *This = impl_from_nsIFileURL(iface);
3321 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
3322 return NS_ERROR_NOT_IMPLEMENTED;
3325 static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
3327 nsWineURI *This = impl_from_nsIFileURL(iface);
3329 TRACE("(%p)->(%p)\n", This, aFileExtension);
3331 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
3334 static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
3336 nsWineURI *This = impl_from_nsIFileURL(iface);
3337 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
3338 return NS_ERROR_NOT_IMPLEMENTED;
3341 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3343 nsWineURI *This = impl_from_nsIFileURL(iface);
3344 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3345 return NS_ERROR_NOT_IMPLEMENTED;
3348 static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3350 nsWineURI *This = impl_from_nsIFileURL(iface);
3351 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3352 return NS_ERROR_NOT_IMPLEMENTED;
3355 static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
3357 nsWineURI *This = impl_from_nsIFileURL(iface);
3358 WCHAR path[MAX_PATH];
3359 DWORD size;
3360 HRESULT hres;
3362 TRACE("(%p)->(%p)\n", This, aFile);
3364 hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
3365 if(FAILED(hres)) {
3366 WARN("CoInternetParseIUri failed: %08lx\n", hres);
3367 return NS_ERROR_FAILURE;
3370 return create_nsfile(path, aFile);
3373 static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
3375 nsWineURI *This = impl_from_nsIFileURL(iface);
3376 FIXME("(%p)->(%p)\n", This, aFile);
3377 return NS_ERROR_NOT_IMPLEMENTED;
3380 static const nsIFileURLVtbl nsFileURLVtbl = {
3381 nsURI_QueryInterface,
3382 nsURI_AddRef,
3383 nsURI_Release,
3384 nsURI_GetSpec,
3385 nsURI_SetSpec,
3386 nsURI_GetPrePath,
3387 nsURI_GetScheme,
3388 nsURI_SetScheme,
3389 nsURI_GetUserPass,
3390 nsURI_SetUserPass,
3391 nsURI_GetUsername,
3392 nsURI_SetUsername,
3393 nsURI_GetPassword,
3394 nsURI_SetPassword,
3395 nsURI_GetHostPort,
3396 nsURI_SetHostPort,
3397 nsURI_GetHost,
3398 nsURI_SetHost,
3399 nsURI_GetPort,
3400 nsURI_SetPort,
3401 nsURI_GetPath,
3402 nsURI_SetPath,
3403 nsURI_Equals,
3404 nsURI_SchemeIs,
3405 nsURI_Clone,
3406 nsURI_Resolve,
3407 nsURI_GetAsciiSpec,
3408 nsURI_GetAsciiHostPort,
3409 nsURI_GetAsciiHost,
3410 nsURI_GetOriginCharset,
3411 nsURL_GetRef,
3412 nsURL_SetRef,
3413 nsURI_EqualsExceptRef,
3414 nsURI_CloneIgnoreRef,
3415 nsURI_GetSpecIgnoringRef,
3416 nsURI_GetHasRef,
3417 nsURL_GetFilePath,
3418 nsURL_SetFilePath,
3419 nsURL_GetQuery,
3420 nsURL_SetQuery,
3421 nsURL_GetDirectory,
3422 nsURL_SetDirectory,
3423 nsURL_GetFileName,
3424 nsURL_SetFileName,
3425 nsURL_GetFileBaseName,
3426 nsURL_SetFileBaseName,
3427 nsURL_GetFileExtension,
3428 nsURL_SetFileExtension,
3429 nsURL_GetCommonBaseSpec,
3430 nsURL_GetRelativeSpec,
3431 nsFileURL_GetFile,
3432 nsFileURL_SetFile
3435 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
3437 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
3440 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
3441 void **result)
3443 nsWineURI *This = impl_from_nsIStandardURL(iface);
3444 return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
3447 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
3449 nsWineURI *This = impl_from_nsIStandardURL(iface);
3450 return nsIFileURL_AddRef(&This->nsIFileURL_iface);
3453 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
3455 nsWineURI *This = impl_from_nsIStandardURL(iface);
3456 return nsIFileURL_Release(&This->nsIFileURL_iface);
3459 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
3461 nsWineURI *This = impl_from_nsIStandardURL(iface);
3463 TRACE("(%p)->(%p)\n", This, aMutable);
3465 *aMutable = This->is_mutable;
3466 return NS_OK;
3469 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
3471 nsWineURI *This = impl_from_nsIStandardURL(iface);
3473 TRACE("(%p)->(%x)\n", This, aMutable);
3475 This->is_mutable = aMutable;
3476 return NS_OK;
3479 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
3480 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
3482 nsWineURI *This = impl_from_nsIStandardURL(iface);
3483 FIXME("(%p)->(%d %ld %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
3484 return NS_ERROR_NOT_IMPLEMENTED;
3487 static nsresult NSAPI nsStandardURL_SetDefaultPort(nsIStandardURL *iface, LONG aNewDefaultPort)
3489 nsWineURI *This = impl_from_nsIStandardURL(iface);
3490 FIXME("(%p)->(%ld)\n", This, aNewDefaultPort);
3491 return NS_ERROR_NOT_IMPLEMENTED;
3494 static const nsIStandardURLVtbl nsStandardURLVtbl = {
3495 nsStandardURL_QueryInterface,
3496 nsStandardURL_AddRef,
3497 nsStandardURL_Release,
3498 nsStandardURL_GetMutable,
3499 nsStandardURL_SetMutable,
3500 nsStandardURL_Init,
3501 nsStandardURL_SetDefaultPort
3504 static nsresult create_nsuri(IUri *iuri, nsWineURI **_retval)
3506 nsWineURI *ret;
3507 HRESULT hres;
3509 ret = calloc(1, sizeof(nsWineURI));
3510 if(!ret)
3511 return NS_ERROR_OUT_OF_MEMORY;
3513 ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
3514 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
3515 ret->ref = 1;
3516 ret->is_mutable = TRUE;
3518 IUri_AddRef(iuri);
3519 ret->uri = iuri;
3521 hres = IUri_GetScheme(iuri, &ret->scheme);
3522 if(hres != S_OK)
3523 ret->scheme = URL_SCHEME_UNKNOWN;
3525 TRACE("retval=%p\n", ret);
3526 *_retval = ret;
3527 return NS_OK;
3530 HRESULT create_doc_uri(IUri *iuri, nsWineURI **ret)
3532 nsresult nsres;
3533 nsres = create_nsuri(iuri, ret);
3534 return NS_SUCCEEDED(nsres) ? S_OK : E_OUTOFMEMORY;
3537 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
3539 nsChannel *channel;
3541 if(!ensure_uri(uri))
3542 return NS_ERROR_UNEXPECTED;
3544 channel = calloc(1, sizeof(nsChannel));
3545 if(!channel)
3546 return NS_ERROR_OUT_OF_MEMORY;
3548 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
3549 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
3550 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
3551 channel->nsICacheInfoChannel_iface.lpVtbl = &nsCacheInfoChannelVtbl;
3552 channel->request_method = METHOD_GET;
3553 list_init(&channel->response_headers);
3554 list_init(&channel->request_headers);
3555 ccref_init(&channel->ccref, 1);
3557 nsIFileURL_AddRef(&uri->nsIFileURL_iface);
3558 channel->uri = uri;
3560 *ret = channel;
3561 return NS_OK;
3564 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
3566 nsChannel *channel;
3567 nsWineURI *uri;
3568 IUri *iuri;
3569 nsresult nsres;
3570 HRESULT hres;
3572 hres = create_uri(url, 0, &iuri);
3573 if(FAILED(hres))
3574 return hres;
3576 nsres = create_nsuri(iuri, &uri);
3577 IUri_Release(iuri);
3578 if(NS_FAILED(nsres))
3579 return E_FAIL;
3581 nsres = create_nschannel(uri, &channel);
3582 nsIFileURL_Release(&uri->nsIFileURL_iface);
3583 if(NS_FAILED(nsres))
3584 return E_FAIL;
3586 if(orig_channel->load_group) {
3587 nsILoadGroup_AddRef(orig_channel->load_group);
3588 channel->load_group = orig_channel->load_group;
3591 if(orig_channel->notif_callback) {
3592 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
3593 channel->notif_callback = orig_channel->notif_callback;
3596 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
3598 if(orig_channel->request_method == METHOD_POST)
3599 FIXME("unsupported POST method\n");
3601 if(orig_channel->original_uri) {
3602 nsIURI_AddRef(orig_channel->original_uri);
3603 channel->original_uri = orig_channel->original_uri;
3606 if(orig_channel->referrer) {
3607 nsIURI_AddRef(orig_channel->referrer);
3608 channel->referrer = orig_channel->referrer;
3611 *ret = channel;
3612 return S_OK;
3615 typedef struct {
3616 nsIProtocolHandler nsIProtocolHandler_iface;
3618 LONG ref;
3620 nsIProtocolHandler *nshandler;
3621 } nsProtocolHandler;
3623 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
3625 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
3628 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
3629 void **result)
3631 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3633 *result = NULL;
3635 if(IsEqualGUID(&IID_nsISupports, riid)) {
3636 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
3637 *result = &This->nsIProtocolHandler_iface;
3638 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
3639 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
3640 *result = &This->nsIProtocolHandler_iface;
3641 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
3642 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
3643 return NS_NOINTERFACE;
3646 if(*result) {
3647 nsISupports_AddRef((nsISupports*)*result);
3648 return NS_OK;
3651 WARN("(%s %p)\n", debugstr_guid(riid), result);
3652 return NS_NOINTERFACE;
3655 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
3657 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3658 LONG ref = InterlockedIncrement(&This->ref);
3660 TRACE("(%p) ref=%ld\n", This, ref);
3662 return ref;
3665 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3667 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3668 LONG ref = InterlockedDecrement(&This->ref);
3670 TRACE("(%p) ref=%ld\n", This, ref);
3672 if(!ref) {
3673 if(This->nshandler)
3674 nsIProtocolHandler_Release(This->nshandler);
3675 free(This);
3678 return ref;
3681 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3683 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3685 TRACE("(%p)->(%p)\n", This, aScheme);
3687 if(This->nshandler)
3688 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3689 return NS_ERROR_NOT_IMPLEMENTED;
3692 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3693 LONG *aDefaultPort)
3695 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3697 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3699 if(This->nshandler)
3700 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3701 return NS_ERROR_NOT_IMPLEMENTED;
3704 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3705 UINT32 *aProtocolFlags)
3707 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3709 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3711 if(This->nshandler)
3712 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3713 return NS_ERROR_NOT_IMPLEMENTED;
3716 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3717 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3719 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3721 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3722 aBaseURI, _retval);
3724 if(This->nshandler)
3725 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3726 return NS_ERROR_NOT_IMPLEMENTED;
3729 static nsresult NSAPI nsProtocolHandler_NewChannel2(nsIProtocolHandler *iface,
3730 nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3732 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3734 TRACE("(%p)->(%p %p %p)\n", This, aURI, aLoadInfo, _retval);
3736 if(This->nshandler)
3737 return nsIProtocolHandler_NewChannel2(This->nshandler, aURI, aLoadInfo, _retval);
3738 return NS_ERROR_NOT_IMPLEMENTED;
3741 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3742 nsIURI *aURI, nsIChannel **_retval)
3744 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3746 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3748 if(This->nshandler)
3749 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3750 return NS_ERROR_NOT_IMPLEMENTED;
3753 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3754 LONG port, const char *scheme, cpp_bool *_retval)
3756 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3758 TRACE("(%p)->(%ld %s %p)\n", This, port, debugstr_a(scheme), _retval);
3760 if(This->nshandler)
3761 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3762 return NS_ERROR_NOT_IMPLEMENTED;
3765 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3766 nsProtocolHandler_QueryInterface,
3767 nsProtocolHandler_AddRef,
3768 nsProtocolHandler_Release,
3769 nsProtocolHandler_GetScheme,
3770 nsProtocolHandler_GetDefaultPort,
3771 nsProtocolHandler_GetProtocolFlags,
3772 nsProtocolHandler_NewURI,
3773 nsProtocolHandler_NewChannel2,
3774 nsProtocolHandler_NewChannel,
3775 nsProtocolHandler_AllowPort
3778 static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid,
3779 void **result)
3781 if(IsEqualGUID(&IID_nsISupports, riid)) {
3782 TRACE("(IID_nsISupports %p)\n", result);
3783 *result = iface;
3784 }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) {
3785 TRACE("(IID_nsIIOServiceHook %p)\n", result);
3786 *result = iface;
3787 }else {
3788 ERR("(%s %p)\n", debugstr_guid(riid), result);
3789 *result = NULL;
3790 return NS_NOINTERFACE;
3793 nsISupports_AddRef((nsISupports*)*result);
3794 return NS_OK;
3797 static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface)
3799 return 2;
3802 static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface)
3804 return 1;
3807 static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI,
3808 nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3810 nsWineURI *wine_uri;
3811 nsChannel *ret;
3812 nsresult nsres;
3814 TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval);
3816 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3817 if(NS_FAILED(nsres)) {
3818 TRACE("Could not get nsWineURI: %08lx\n", nsres);
3819 return NS_SUCCESS_DEFAULT_ACTION;
3822 nsres = create_nschannel(wine_uri, &ret);
3823 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3824 if(NS_FAILED(nsres))
3825 return nsres;
3827 nsIURI_AddRef(aURI);
3828 ret->original_uri = aURI;
3830 if(aLoadInfo)
3831 nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo);
3833 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3834 return NS_OK;
3837 static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler,
3838 nsIProtocolHandler **_retval)
3840 nsIExternalProtocolHandler *nsexthandler;
3841 nsProtocolHandler *ret;
3842 nsresult nsres;
3844 TRACE("(%p %p)\n", aHandler, _retval);
3846 nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler);
3847 if(NS_FAILED(nsres)) {
3848 nsIProtocolHandler_AddRef(aHandler);
3849 *_retval = aHandler;
3850 return NS_OK;
3853 nsIExternalProtocolHandler_Release(nsexthandler);
3855 ret = malloc(sizeof(nsProtocolHandler));
3856 if(!ret)
3857 return NS_ERROR_OUT_OF_MEMORY;
3859 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3860 ret->ref = 1;
3861 nsIProtocolHandler_AddRef(aHandler);
3862 ret->nshandler = aHandler;
3865 *_retval = &ret->nsIProtocolHandler_iface;
3866 TRACE("return %p\n", *_retval);
3867 return NS_OK;
3870 static BOOL is_gecko_special_uri(const char *spec)
3872 static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource://gre/", "resource://gre-resources/", "javascript:", "wyciwyg:"};
3873 unsigned int i;
3875 for(i=0; i < ARRAY_SIZE(special_schemes); i++) {
3876 if(!_strnicmp(spec, special_schemes[i], strlen(special_schemes[i])))
3877 return TRUE;
3880 if(!_strnicmp(spec, "file:", 5)) {
3881 const char *ptr = spec+5;
3882 while(*ptr == '/')
3883 ptr++;
3884 return is_gecko_path(ptr);
3887 return FALSE;
3890 static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec,
3891 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3893 nsWineURI *wine_uri, *base_wine_uri = NULL;
3894 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3895 const char *spec = NULL;
3896 UINT cp = CP_UTF8;
3897 IUri *urlmon_uri;
3898 nsresult nsres;
3899 HRESULT hres;
3901 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3902 aBaseURI, _retval);
3904 nsACString_GetData(aSpec, &spec);
3905 if(is_gecko_special_uri(spec))
3906 return NS_SUCCESS_DEFAULT_ACTION;
3908 if(!strncmp(spec, "wine:", 5))
3909 spec += 5;
3911 if(aOriginCharset && *aOriginCharset && _strnicmp(aOriginCharset, "utf", 3)) {
3912 BSTR charset;
3913 int len;
3915 len = MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, NULL, 0);
3916 charset = SysAllocStringLen(NULL, len-1);
3917 if(!charset)
3918 return NS_ERROR_OUT_OF_MEMORY;
3919 MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, charset, len);
3921 cp = cp_from_charset_string(charset);
3923 SysFreeString(charset);
3926 MultiByteToWideChar(cp, 0, spec, -1, new_spec, ARRAY_SIZE(new_spec));
3928 if(aBaseURI) {
3929 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3930 if(NS_SUCCEEDED(nsres)) {
3931 if(!ensure_uri(base_wine_uri)) {
3932 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3933 return NS_ERROR_UNEXPECTED;
3935 }else {
3936 WARN("Could not get base nsWineURI: %08lx\n", nsres);
3940 if(base_wine_uri) {
3941 hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri);
3942 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3943 }else {
3944 hres = create_uri(new_spec, 0, &urlmon_uri);
3945 if(FAILED(hres))
3946 WARN("create_uri failed: %08lx\n", hres);
3949 if(FAILED(hres))
3950 return NS_SUCCESS_DEFAULT_ACTION;
3952 nsres = create_nsuri(urlmon_uri, &wine_uri);
3953 IUri_Release(urlmon_uri);
3954 if(NS_FAILED(nsres))
3955 return nsres;
3957 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3958 return nsres;
3961 static const char *debugstr_protocol_flags(UINT32 flags)
3963 switch(flags) {
3964 #define X(f) case f: return #f
3965 X(URI_STD);
3966 X(URI_NORELATIVE);
3967 X(URI_NOAUTH);
3968 X(ALLOWS_PROXY);
3969 X(ALLOWS_PROXY_HTTP);
3970 X(URI_INHERITS_SECURITY_CONTEXT);
3971 X(URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
3972 X(URI_LOADABLE_BY_ANYONE);
3973 X(URI_DANGEROUS_TO_LOAD);
3974 X(URI_IS_UI_RESOURCE);
3975 X(URI_IS_LOCAL_FILE);
3976 X(URI_LOADABLE_BY_SUBSUMERS);
3977 X(URI_DOES_NOT_RETURN_DATA);
3978 X(URI_IS_LOCAL_RESOURCE);
3979 X(URI_OPENING_EXECUTES_SCRIPT);
3980 X(URI_NON_PERSISTABLE);
3981 X(URI_FORBIDS_COOKIE_ACCESS);
3982 X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM);
3983 X(URI_SYNC_LOAD_IS_OK);
3984 X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT);
3985 X(URI_FETCHABLE_BY_ANYONE);
3986 #undef X
3987 default:
3988 return wine_dbg_sprintf("%08x", flags);
3992 static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3994 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3995 return NS_SUCCESS_DEFAULT_ACTION;
3998 static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
4000 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
4002 if(aFlags == URI_DOES_NOT_RETURN_DATA) {
4003 *_retval = FALSE;
4004 return S_OK;
4007 return NS_SUCCESS_DEFAULT_ACTION;
4010 static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = {
4011 nsIOServiceHook_QueryInterface,
4012 nsIOServiceHook_AddRef,
4013 nsIOServiceHook_Release,
4014 nsIOServiceHook_NewChannel,
4015 nsIOServiceHook_GetProtocolHandler,
4016 nsIOServiceHook_NewURI,
4017 nsIOServiceHook_ProtocolHasFlags,
4018 nsIOServiceHook_URIChainHasFlags
4021 static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };
4023 void init_nsio(nsIComponentManager *component_manager)
4025 static const CCObjCallback nschannel_ccp_callback = {
4026 nsChannel_traverse,
4027 nsChannel_unlink,
4028 nsChannel_delete_cycle_collectable
4030 nsIFactory *old_factory = NULL;
4031 nsresult nsres;
4033 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
4034 &IID_nsIFactory, (void**)&old_factory);
4035 if(NS_FAILED(nsres)) {
4036 ERR("Could not get factory: %08lx\n", nsres);
4037 return;
4040 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
4041 nsIFactory_Release(old_factory);
4042 if(NS_FAILED(nsres)) {
4043 ERR("Couldn not create nsIOService instance %08lx\n", nsres);
4044 return;
4047 nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
4048 assert(nsres == NS_OK);
4050 ccp_init(&nschannel_ccp, &nschannel_ccp_callback);
4053 void release_nsio(void)
4055 if(nsio) {
4056 nsIIOService_Release(nsio);
4057 nsio = NULL;
4061 nsresult create_onload_blocker_request(nsIRequest **ret)
4063 nsIChannel *channel;
4064 nsACString spec;
4065 nsresult nsres;
4067 nsACString_InitDepend(&spec, "about:wine-script-onload-blocker");
4068 nsres = nsIIOService_NewChannel(nsio, &spec, NULL, NULL, &channel);
4069 nsACString_Finish(&spec);
4070 if(NS_FAILED(nsres)) {
4071 ERR("Failed to create channel: %08lx\n", nsres);
4072 return nsres;
4075 *ret = (nsIRequest *)channel;
4076 return NS_OK;