mshtml: Fix classList toggle() when return value pointer is NULL.
[wine.git] / dlls / mshtml / nsio.c
blob6bd9a4080373297f10c390156cd66dd729f3a165
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->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 if(This->referrer) {
1250 nsIURI_Release(This->referrer);
1251 This->referrer = NULL;
1253 if(!aReferrer)
1254 return NS_OK;
1256 nsres = nsIURI_QueryInterface(aReferrer, &IID_nsWineURI, (void**)&referrer);
1257 if(NS_FAILED(nsres))
1258 return NS_OK;
1260 if(!ensure_uri(referrer)) {
1261 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1262 return NS_ERROR_UNEXPECTED;
1265 if(!ensure_uri(This->uri) || IUri_GetScheme(This->uri->uri, &channel_scheme) != S_OK)
1266 channel_scheme = INTERNET_SCHEME_UNKNOWN;
1268 if(IUri_GetScheme(referrer->uri, &referrer_scheme) != S_OK)
1269 referrer_scheme = INTERNET_SCHEME_UNKNOWN;
1271 if(referrer_scheme == INTERNET_SCHEME_HTTPS && channel_scheme != INTERNET_SCHEME_HTTPS) {
1272 TRACE("Ignoring https referrer on non-https channel\n");
1273 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1274 return NS_OK;
1277 hres = IUri_GetDisplayUri(referrer->uri, &referrer_uri);
1278 if(SUCCEEDED(hres)) {
1279 set_http_header(&This->request_headers, refererW, ARRAY_SIZE(refererW), referrer_uri, SysStringLen(referrer_uri));
1280 SysFreeString(referrer_uri);
1283 This->referrer = (nsIURI*)&referrer->nsIFileURL_iface;
1284 return NS_OK;
1287 static nsresult NSAPI nsHttpChannel_GetProtocolVersion(nsIHttpChannel *iface, nsACString *aProtocolVersion)
1289 nsChannel *This = impl_from_nsIHttpChannel(iface);
1290 FIXME("(%p)->(%p)\n", This, aProtocolVersion);
1291 return NS_ERROR_NOT_IMPLEMENTED;
1294 static nsresult NSAPI nsHttpChannel_GetTransferSize(nsIHttpChannel *iface, UINT64 *aTransferSize)
1296 nsChannel *This = impl_from_nsIHttpChannel(iface);
1297 FIXME("(%p)->(%p)\n", This, aTransferSize);
1298 return NS_ERROR_NOT_IMPLEMENTED;
1301 static nsresult NSAPI nsHttpChannel_GetDecodedBodySize(nsIHttpChannel *iface, UINT64 *aDecodedBodySize)
1303 nsChannel *This = impl_from_nsIHttpChannel(iface);
1304 FIXME("(%p)->(%p)\n", This, aDecodedBodySize);
1305 return NS_ERROR_NOT_IMPLEMENTED;
1308 static nsresult NSAPI nsHttpChannel_GetEncodedBodySize(nsIHttpChannel *iface, UINT64 *aEncodedBodySize)
1310 nsChannel *This = impl_from_nsIHttpChannel(iface);
1311 FIXME("(%p)->(%p)\n", This, aEncodedBodySize);
1312 return NS_ERROR_NOT_IMPLEMENTED;
1315 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1316 const nsACString *aHeader, nsACString *_retval)
1318 nsChannel *This = impl_from_nsIHttpChannel(iface);
1320 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1322 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1325 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1326 const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
1328 nsChannel *This = impl_from_nsIHttpChannel(iface);
1330 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1332 if(aMerge)
1333 FIXME("aMerge not supported\n");
1335 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1338 static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader)
1340 nsChannel *This = impl_from_nsIHttpChannel(iface);
1341 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader));
1342 return NS_ERROR_NOT_IMPLEMENTED;
1345 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1346 nsIHttpHeaderVisitor *aVisitor)
1348 nsChannel *This = impl_from_nsIHttpChannel(iface);
1350 FIXME("(%p)->(%p)\n", This, aVisitor);
1352 return NS_ERROR_NOT_IMPLEMENTED;
1355 static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor)
1357 nsChannel *This = impl_from_nsIHttpChannel(iface);
1358 FIXME("(%p)->(%p)\n", This, aVisitor);
1359 return NS_ERROR_NOT_IMPLEMENTED;
1362 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
1364 nsChannel *This = impl_from_nsIHttpChannel(iface);
1366 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1368 return NS_ERROR_NOT_IMPLEMENTED;
1371 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
1373 nsChannel *This = impl_from_nsIHttpChannel(iface);
1375 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1377 return NS_ERROR_NOT_IMPLEMENTED;
1380 static nsresult NSAPI nsChannel_GetAllowTLS(nsIHttpChannel *iface, cpp_bool *aAllowTLS)
1382 nsChannel *This = impl_from_nsIHttpChannel(iface);
1383 FIXME("(%p)->(%p)\n", This, aAllowTLS);
1384 return NS_ERROR_NOT_IMPLEMENTED;
1387 static nsresult NSAPI nsChannel_SetAllowTLS(nsIHttpChannel *iface, cpp_bool aAllowTLS)
1389 nsChannel *This = impl_from_nsIHttpChannel(iface);
1390 FIXME("(%p)->(%x)\n", This, aAllowTLS);
1391 return NS_ERROR_NOT_IMPLEMENTED;
1394 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
1396 nsChannel *This = impl_from_nsIHttpChannel(iface);
1398 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1400 return NS_ERROR_NOT_IMPLEMENTED;
1403 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
1405 nsChannel *This = impl_from_nsIHttpChannel(iface);
1407 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1409 return NS_ERROR_NOT_IMPLEMENTED;
1412 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
1414 nsChannel *This = impl_from_nsIHttpChannel(iface);
1416 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1418 if(This->response_status) {
1419 *aResponseStatus = This->response_status;
1420 return NS_OK;
1423 WARN("No response status\n");
1424 return NS_ERROR_UNEXPECTED;
1427 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1428 nsACString *aResponseStatusText)
1430 nsChannel *This = impl_from_nsIHttpChannel(iface);
1432 TRACE("(%p)->(%p)\n", This, aResponseStatusText);
1434 nsACString_SetData(aResponseStatusText, This->response_status_text);
1435 return NS_OK;
1438 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1439 cpp_bool *aRequestSucceeded)
1441 nsChannel *This = impl_from_nsIHttpChannel(iface);
1443 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1445 if(!This->response_status)
1446 return NS_ERROR_NOT_AVAILABLE;
1448 *aRequestSucceeded = This->response_status/100 == 2;
1450 return NS_OK;
1453 static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel)
1455 nsChannel *This = impl_from_nsIHttpChannel(iface);
1456 FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel);
1457 return NS_ERROR_NOT_IMPLEMENTED;
1460 static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel)
1462 nsChannel *This = impl_from_nsIHttpChannel(iface);
1463 FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel);
1464 return NS_ERROR_NOT_IMPLEMENTED;
1467 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1468 const nsACString *header, nsACString *_retval)
1470 nsChannel *This = impl_from_nsIHttpChannel(iface);
1472 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1474 return get_channel_http_header(&This->response_headers, header, _retval);
1477 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1478 const nsACString *header, const nsACString *value, cpp_bool merge)
1480 nsChannel *This = impl_from_nsIHttpChannel(iface);
1482 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1484 return NS_ERROR_NOT_IMPLEMENTED;
1487 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1488 nsIHttpHeaderVisitor *aVisitor)
1490 nsChannel *This = impl_from_nsIHttpChannel(iface);
1492 TRACE("(%p)->(%p)\n", This, aVisitor);
1494 return visit_http_headers(&This->response_headers, aVisitor);
1497 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1499 nsChannel *This = impl_from_nsIHttpChannel(iface);
1500 http_header_t *header;
1502 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1504 TRACE("(%p)->(%p)\n", This, _retval);
1506 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1507 *_retval = header && !wcsicmp(header->data, L"no-store");
1508 return NS_OK;
1511 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1513 nsChannel *This = impl_from_nsIHttpChannel(iface);
1514 http_header_t *header;
1516 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1518 TRACE("(%p)->(%p)\n", This, _retval);
1520 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1521 *_retval = header && !wcsicmp(header->data, L"no-cache");
1522 /* FIXME: Gecko also checks if max-age is in the past */
1523 return NS_OK;
1526 static nsresult NSAPI nsChannel_IsPrivateResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1528 nsChannel *This = impl_from_nsIHttpChannel(iface);
1530 FIXME("(%p)->(%p)\n", This, _retval);
1532 return NS_ERROR_NOT_IMPLEMENTED;
1535 static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aTargetURI)
1537 nsChannel *This = impl_from_nsIHttpChannel(iface);
1539 FIXME("(%p)->(%p)\n", This, aTargetURI);
1541 return NS_ERROR_NOT_IMPLEMENTED;
1544 static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID)
1546 nsChannel *This = impl_from_nsIHttpChannel(iface);
1548 FIXME("(%p)->(%p)\n", This, aSchedulingContextID);
1550 return NS_ERROR_NOT_IMPLEMENTED;
1553 static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID)
1555 nsChannel *This = impl_from_nsIHttpChannel(iface);
1557 FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID));
1559 return NS_ERROR_NOT_IMPLEMENTED;
1562 static const nsIHttpChannelVtbl nsChannelVtbl = {
1563 nsChannel_QueryInterface,
1564 nsChannel_AddRef,
1565 nsChannel_Release,
1566 nsChannel_GetName,
1567 nsChannel_IsPending,
1568 nsChannel_GetStatus,
1569 nsChannel_Cancel,
1570 nsChannel_Suspend,
1571 nsChannel_Resume,
1572 nsChannel_GetLoadGroup,
1573 nsChannel_SetLoadGroup,
1574 nsChannel_GetLoadFlags,
1575 nsChannel_SetLoadFlags,
1576 nsChannel_GetOriginalURI,
1577 nsChannel_SetOriginalURI,
1578 nsChannel_GetURI,
1579 nsChannel_GetOwner,
1580 nsChannel_SetOwner,
1581 nsChannel_GetNotificationCallbacks,
1582 nsChannel_SetNotificationCallbacks,
1583 nsChannel_GetSecurityInfo,
1584 nsChannel_GetContentType,
1585 nsChannel_SetContentType,
1586 nsChannel_GetContentCharset,
1587 nsChannel_SetContentCharset,
1588 nsChannel_GetContentLength,
1589 nsChannel_SetContentLength,
1590 nsChannel_Open,
1591 nsChannel_Open2,
1592 nsChannel_AsyncOpen,
1593 nsChannel_AsyncOpen2,
1594 nsChannel_GetContentDisposition,
1595 nsChannel_SetContentDisposition,
1596 nsChannel_GetContentDispositionFilename,
1597 nsChannel_SetContentDispositionFilename,
1598 nsChannel_GetContentDispositionHeader,
1599 nsChannel_GetLoadInfo,
1600 nsChannel_SetLoadInfo,
1601 nsChannel_GetRequestMethod,
1602 nsChannel_SetRequestMethod,
1603 nsChannel_GetReferrer,
1604 nsChannel_SetReferrer,
1605 nsChannel_GetReferrerPolicy,
1606 nsChannel_SetReferrerWithPolicy,
1607 nsHttpChannel_GetProtocolVersion,
1608 nsHttpChannel_GetTransferSize,
1609 nsHttpChannel_GetDecodedBodySize,
1610 nsHttpChannel_GetEncodedBodySize,
1611 nsChannel_GetRequestHeader,
1612 nsChannel_SetRequestHeader,
1613 nsChannel_SetEmptyRequestHeader,
1614 nsChannel_VisitRequestHeaders,
1615 nsChannel_VisitNonDefaultRequestHeaders,
1616 nsChannel_GetAllowPipelining,
1617 nsChannel_SetAllowPipelining,
1618 nsChannel_GetAllowTLS,
1619 nsChannel_SetAllowTLS,
1620 nsChannel_GetRedirectionLimit,
1621 nsChannel_SetRedirectionLimit,
1622 nsChannel_GetResponseStatus,
1623 nsChannel_GetResponseStatusText,
1624 nsChannel_GetRequestSucceeded,
1625 nsChannel_GetIsMainDocumentChannel,
1626 nsChannel_SetIsMainDocumentChannel,
1627 nsChannel_GetResponseHeader,
1628 nsChannel_SetResponseHeader,
1629 nsChannel_VisitResponseHeaders,
1630 nsChannel_IsNoStoreResponse,
1631 nsChannel_IsNoCacheResponse,
1632 nsChannel_IsPrivateResponse,
1633 nsChannel_RedirectTo,
1634 nsHttpChannel_GetSchedulingContextID,
1635 nsHttpChannel_SetSchedulingContextID
1638 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1640 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1643 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1644 void **result)
1646 nsChannel *This = impl_from_nsIUploadChannel(iface);
1647 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1650 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1652 nsChannel *This = impl_from_nsIUploadChannel(iface);
1653 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1656 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1658 nsChannel *This = impl_from_nsIUploadChannel(iface);
1659 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1662 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1663 nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
1665 nsChannel *This = impl_from_nsIUploadChannel(iface);
1666 const char *content_type;
1668 static const WCHAR content_typeW[] =
1669 {'C','o','n','t','e','n','t','-','T','y','p','e'};
1671 TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));
1673 This->post_data_contains_headers = TRUE;
1675 if(aContentType) {
1676 nsACString_GetData(aContentType, &content_type);
1677 if(*content_type) {
1678 WCHAR *ct;
1680 ct = strdupAtoW(content_type);
1681 if(!ct)
1682 return NS_ERROR_UNEXPECTED;
1684 set_http_header(&This->request_headers, content_typeW, ARRAY_SIZE(content_typeW), ct, lstrlenW(ct));
1685 free(ct);
1686 This->post_data_contains_headers = FALSE;
1690 if(aContentLength != -1)
1691 FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));
1693 if(This->post_data_stream)
1694 nsIInputStream_Release(This->post_data_stream);
1695 This->post_data_stream = aStream;
1696 if(aStream)
1697 nsIInputStream_AddRef(aStream);
1699 This->request_method = METHOD_POST;
1700 return NS_OK;
1703 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1704 nsIInputStream **aUploadStream)
1706 nsChannel *This = impl_from_nsIUploadChannel(iface);
1708 TRACE("(%p)->(%p)\n", This, aUploadStream);
1710 if(This->post_data_stream)
1711 nsIInputStream_AddRef(This->post_data_stream);
1713 *aUploadStream = This->post_data_stream;
1714 return NS_OK;
1717 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1718 nsUploadChannel_QueryInterface,
1719 nsUploadChannel_AddRef,
1720 nsUploadChannel_Release,
1721 nsUploadChannel_SetUploadStream,
1722 nsUploadChannel_GetUploadStream
1725 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1727 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1730 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1731 void **result)
1733 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1734 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1737 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1739 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1740 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1743 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1745 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1746 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1749 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1751 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1753 FIXME("(%p)->()\n", This);
1755 return NS_ERROR_NOT_IMPLEMENTED;
1758 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1760 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1762 TRACE("(%p)->() unimplemented\n", This);
1764 return NS_ERROR_NOT_IMPLEMENTED;
1767 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1769 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1771 FIXME("(%p)->()\n", This);
1773 return NS_ERROR_NOT_IMPLEMENTED;
1776 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1778 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1780 FIXME("(%p)->()\n", This);
1782 return NS_ERROR_NOT_IMPLEMENTED;
1785 static nsresult NSAPI nsHttpChannelInternal_TakeAllSecurityMessages(nsIHttpChannelInternal *iface, void *aMessages)
1787 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1789 TRACE("(%p)->(%p) unimplemented\n", This, aMessages);
1791 return NS_ERROR_NOT_IMPLEMENTED;
1794 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1796 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1798 FIXME("(%p)->()\n", This);
1800 return NS_ERROR_NOT_IMPLEMENTED;
1803 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1805 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1807 FIXME("(%p)->()\n", This);
1809 return NS_ERROR_NOT_IMPLEMENTED;
1812 static nsresult NSAPI nsHttpChannelInternal_GetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 *aThirdPartyFlags)
1814 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1815 FIXME("(%p)->(%p)\n", This, aThirdPartyFlags);
1816 return NS_ERROR_NOT_IMPLEMENTED;
1819 static nsresult NSAPI nsHttpChannelInternal_SetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 aThirdPartyFlags)
1821 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1822 FIXME("(%p)->(%x)\n", This, aThirdPartyFlags);
1823 return NS_ERROR_NOT_IMPLEMENTED;
1826 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
1828 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1830 FIXME("(%p)->()\n", This);
1832 return NS_ERROR_NOT_IMPLEMENTED;
1835 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
1837 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1839 FIXME("(%p)->()\n", This);
1841 return NS_ERROR_NOT_IMPLEMENTED;
1844 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1846 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1848 FIXME("(%p)->(%p)\n", This, aCanceled);
1850 return NS_ERROR_NOT_IMPLEMENTED;
1853 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1855 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1857 FIXME("(%p)->(%p)\n", This, aCanceled);
1859 return NS_ERROR_NOT_IMPLEMENTED;
1862 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
1864 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1866 FIXME("(%p)->(%x)\n", This, aCanceled);
1868 return NS_ERROR_NOT_IMPLEMENTED;
1871 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1873 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1875 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1877 return NS_ERROR_NOT_IMPLEMENTED;
1880 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
1882 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1884 FIXME("(%p)->(%p)\n", This, aLocalPort);
1886 return NS_ERROR_NOT_IMPLEMENTED;
1889 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1891 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1893 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1895 return NS_ERROR_NOT_IMPLEMENTED;
1898 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
1900 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1902 FIXME("(%p)->(%p)\n", This, aRemotePort);
1904 return NS_ERROR_NOT_IMPLEMENTED;
1907 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1909 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1911 FIXME("(%p)->(%p)\n", This, cacheKeys);
1913 return NS_ERROR_NOT_IMPLEMENTED;
1916 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1917 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1919 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1920 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1921 return NS_ERROR_NOT_IMPLEMENTED;
1924 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
1926 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1927 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
1928 return NS_ERROR_NOT_IMPLEMENTED;
1931 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
1933 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1934 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
1935 return NS_ERROR_NOT_IMPLEMENTED;
1938 static nsresult NSAPI nsHttpChannelInternal_GetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1939 cpp_bool *aResponseTimeoutEnabled)
1941 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1942 FIXME("(%p)->(%p)\n", This, aResponseTimeoutEnabled);
1943 return NS_ERROR_NOT_IMPLEMENTED;
1946 static nsresult NSAPI nsHttpChannelInternal_SetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1947 cpp_bool aResponseTimeoutEnabled)
1949 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1950 FIXME("(%p)->(%x)\n", This, aResponseTimeoutEnabled);
1951 return NS_ERROR_NOT_IMPLEMENTED;
1954 static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface,
1955 UINT32 *aInitialRwin)
1957 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1958 FIXME("(%p)->(%p)\n", This, aInitialRwin);
1959 return NS_ERROR_NOT_IMPLEMENTED;
1962 static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface,
1963 UINT32 aInitialRwin)
1965 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1966 FIXME("(%p)->(%x)\n", This, aInitialRwin);
1967 return NS_ERROR_NOT_IMPLEMENTED;
1970 static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI)
1972 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1973 FIXME("(%p)->(%p)\n", This, aApiRedirectToURI);
1974 return NS_ERROR_NOT_IMPLEMENTED;
1977 static nsresult NSAPI nsHttpChannelInternal_GetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool *aAllowAltSvc)
1979 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1980 FIXME("(%p)->(%p)\n", This, aAllowAltSvc);
1981 return NS_ERROR_NOT_IMPLEMENTED;
1984 static nsresult NSAPI nsHttpChannelInternal_SetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool aAllowAltSvc)
1986 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1987 FIXME("(%p)->(%x)\n", This, aAllowAltSvc);
1988 return NS_ERROR_NOT_IMPLEMENTED;
1991 static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime)
1993 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1994 FIXME("(%p)->(%p)\n", This, aLastModifiedTime);
1995 return NS_ERROR_NOT_IMPLEMENTED;
1998 static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID)
2000 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2001 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID));
2002 return NS_ERROR_NOT_IMPLEMENTED;
2005 static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized)
2007 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2008 FIXME("(%p, %p)\n", This, ResponseSynthesized);
2009 return NS_ERROR_NOT_IMPLEMENTED;
2012 static nsresult NSAPI nsHttpChannelInternal_GetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2013 cpp_bool *aCorsIncludeCredentials)
2015 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2016 FIXME("(%p)->(%p)\n", This, aCorsIncludeCredentials);
2017 return NS_ERROR_NOT_IMPLEMENTED;
2020 static nsresult NSAPI nsHttpChannelInternal_SetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2021 cpp_bool aCorsIncludeCredentials)
2023 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2024 TRACE("(%p)->(%x)\n", This, aCorsIncludeCredentials);
2025 return NS_OK;
2028 static nsresult NSAPI nsHttpChannelInternal_GetCorsMode(nsIHttpChannelInternal *iface, UINT32 *aCorsMode)
2030 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2031 FIXME("(%p)->(%p)\n", This, aCorsMode);
2032 return NS_ERROR_NOT_IMPLEMENTED;
2035 static nsresult NSAPI nsHttpChannelInternal_SetCorsMode(nsIHttpChannelInternal *iface, UINT32 aCorsMode)
2037 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2038 TRACE("(%p)->(%d)\n", This, aCorsMode);
2039 return NS_OK;
2042 static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode)
2044 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2045 FIXME("(%p)->(%p)\n", This, aRedirectMode);
2046 return NS_ERROR_NOT_IMPLEMENTED;
2049 static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode)
2051 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2052 TRACE("(%p)->(%d) unimplemented\n", This, aRedirectMode);
2053 return NS_ERROR_NOT_IMPLEMENTED;
2056 static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI)
2058 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2059 FIXME("(%p)->(%p)\n", This, aTopWindowURI);
2060 return NS_ERROR_NOT_IMPLEMENTED;
2063 static nsresult NSAPI nsHttpChannelInternal_GetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2064 nsACString *aNetworkInterfaceId)
2066 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2067 FIXME("(%p)->(%p)\n", This, aNetworkInterfaceId);
2068 return NS_ERROR_NOT_IMPLEMENTED;
2071 static nsresult NSAPI nsHttpChannelInternal_SetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2072 const nsACString *aNetworkInterfaceId)
2074 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2075 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aNetworkInterfaceId));
2076 return NS_ERROR_NOT_IMPLEMENTED;
2079 static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI)
2081 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2082 FIXME("(%p)->(%p)\n", This, aProxyURI);
2083 return NS_ERROR_NOT_IMPLEMENTED;
2086 static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface,
2087 const void /*nsTArray<nsCString>*/ *unsafeHeaders)
2089 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2090 FIXME("(%p)->(%p)\n", This, unsafeHeaders);
2091 return NS_ERROR_NOT_IMPLEMENTED;
2094 static nsresult NSAPI nsHttpChannelInternal_GetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool *aBlockAuthPrompt)
2096 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2097 FIXME("(%p)->(%p)\n", This, aBlockAuthPrompt);
2098 return NS_ERROR_NOT_IMPLEMENTED;
2101 static nsresult NSAPI nsHttpChannelInternal_SetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool aBlockAuthPrompt)
2103 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2104 FIXME("(%p)->(%x)\n", This, aBlockAuthPrompt);
2105 return NS_ERROR_NOT_IMPLEMENTED;
2108 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
2109 nsHttpChannelInternal_QueryInterface,
2110 nsHttpChannelInternal_AddRef,
2111 nsHttpChannelInternal_Release,
2112 nsHttpChannelInternal_GetDocumentURI,
2113 nsHttpChannelInternal_SetDocumentURI,
2114 nsHttpChannelInternal_GetRequestVersion,
2115 nsHttpChannelInternal_GetResponseVersion,
2116 nsHttpChannelInternal_TakeAllSecurityMessages,
2117 nsHttpChannelInternal_SetCookie,
2118 nsHttpChannelInternal_SetupFallbackChannel,
2119 nsHttpChannelInternal_GetThirdPartyFlags,
2120 nsHttpChannelInternal_SetThirdPartyFlags,
2121 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
2122 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
2123 nsHttpChannelInternal_GetCanceled,
2124 nsHttpChannelInternal_GetChannelIsForDownload,
2125 nsHttpChannelInternal_SetChannelIsForDownload,
2126 nsHttpChannelInternal_GetLocalAddress,
2127 nsHttpChannelInternal_GetLocalPort,
2128 nsHttpChannelInternal_GetRemoteAddress,
2129 nsHttpChannelInternal_GetRemotePort,
2130 nsHttpChannelInternal_SetCacheKeysRedirectChain,
2131 nsHttpChannelInternal_HTTPUpgrade,
2132 nsHttpChannelInternal_GetAllowSpdy,
2133 nsHttpChannelInternal_SetAllowSpdy,
2134 nsHttpChannelInternal_GetResponseTimeoutEnabled,
2135 nsHttpChannelInternal_SetResponseTimeoutEnabled,
2136 nsHttpChannelInternal_GetInitialRwin,
2137 nsHttpChannelInternal_SetInitialRwin,
2138 nsHttpChannelInternal_GetApiRedirectToURI,
2139 nsHttpChannelInternal_GetAllowAltSvc,
2140 nsHttpChannelInternal_SetAllowAltSvc,
2141 nsHttpChannelInternal_GetLastModifiedTime,
2142 nsHttpChannelInternal_ForceIntercepted,
2143 nsHttpChannelInternal_GetResponseSynthesized,
2144 nsHttpChannelInternal_GetCorsIncludeCredentials,
2145 nsHttpChannelInternal_SetCorsIncludeCredentials,
2146 nsHttpChannelInternal_GetCorsMode,
2147 nsHttpChannelInternal_SetCorsMode,
2148 nsHttpChannelInternal_GetRedirectMode,
2149 nsHttpChannelInternal_SetRedirectMode,
2150 nsHttpChannelInternal_GetTopWindowURI,
2151 nsHttpChannelInternal_GetNetworkInterfaceId,
2152 nsHttpChannelInternal_SetNetworkInterfaceId,
2153 nsHttpChannelInternal_GetProxyURI,
2154 nsHttpChannelInternal_SetCorsPreflightParameters,
2155 nsHttpChannelInternal_GetBlockAuthPrompt,
2156 nsHttpChannelInternal_SetBlockAuthPrompt
2159 static inline nsChannel *impl_from_nsICacheInfoChannel(nsICacheInfoChannel *iface)
2161 return CONTAINING_RECORD(iface, nsChannel, nsICacheInfoChannel_iface);
2164 static nsresult NSAPI nsCacheInfoChannel_QueryInterface(nsICacheInfoChannel *iface, nsIIDRef riid,
2165 void **result)
2167 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2168 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
2171 static nsrefcnt NSAPI nsCacheInfoChannel_AddRef(nsICacheInfoChannel *iface)
2173 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2174 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
2177 static nsrefcnt NSAPI nsCacheInfoChannel_Release(nsICacheInfoChannel *iface)
2179 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2180 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
2183 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenExpirationTime(nsICacheInfoChannel *iface, UINT32 *p)
2185 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2186 FIXME("(%p)->(%p)\n", This, p);
2187 return E_NOTIMPL;
2190 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenCachedCharset(nsICacheInfoChannel *iface, nsACString *p)
2192 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2193 FIXME("(%p)->(%p)\n", This, p);
2194 return E_NOTIMPL;
2197 static nsresult NSAPI nsCacheInfoChannel_SetCacheTokenCachedCharset(nsICacheInfoChannel *iface, const nsACString *p)
2199 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2200 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(p));
2201 return E_NOTIMPL;
2204 static nsresult NSAPI nsCacheInfoChannel_IsFromCache(nsICacheInfoChannel *iface, cpp_bool *p)
2206 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2207 FIXME("(%p)->(%p)\n", This, p);
2208 *p = FALSE;
2209 return NS_OK;
2212 static nsresult NSAPI nsCacheInfoChannel_GetCacheKey(nsICacheInfoChannel *iface, nsISupports **p)
2214 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2215 FIXME("(%p)->(%p)\n", This, p);
2216 return E_NOTIMPL;
2219 static nsresult NSAPI nsCacheInfoChannel_SetCacheKey(nsICacheInfoChannel *iface, nsISupports *key)
2221 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2222 FIXME("(%p)->(%p)\n", This, key);
2223 return E_NOTIMPL;
2226 static nsresult NSAPI nsCacheInfoChannel_GetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool *p)
2228 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2229 FIXME("(%p)->(%p)\n", This, p);
2230 return E_NOTIMPL;
2233 static nsresult NSAPI nsCacheInfoChannel_SetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool allow)
2235 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2236 FIXME("(%p)->(%x)\n", This, allow);
2237 return E_NOTIMPL;
2240 static const nsICacheInfoChannelVtbl nsCacheInfoChannelVtbl = {
2241 nsCacheInfoChannel_QueryInterface,
2242 nsCacheInfoChannel_AddRef,
2243 nsCacheInfoChannel_Release,
2244 nsCacheInfoChannel_GetCacheTokenExpirationTime,
2245 nsCacheInfoChannel_GetCacheTokenCachedCharset,
2246 nsCacheInfoChannel_SetCacheTokenCachedCharset,
2247 nsCacheInfoChannel_IsFromCache,
2248 nsCacheInfoChannel_GetCacheKey,
2249 nsCacheInfoChannel_SetCacheKey,
2250 nsCacheInfoChannel_GetAllowStaleCacheContent,
2251 nsCacheInfoChannel_SetAllowStaleCacheContent
2254 static nsresult NSAPI nsChannel_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb)
2256 nsChannel *This = impl_from_nsIHttpChannel(p);
2258 TRACE("%p\n", This);
2260 describe_cc_node(&This->ccref, "nsChannel", cb);
2262 if(This->owner)
2263 note_cc_edge(This->owner, "owner", cb);
2264 if(This->post_data_stream)
2265 note_cc_edge((nsISupports*)This->post_data_stream, "post_data_stream", cb);
2266 if(This->load_info)
2267 note_cc_edge(This->load_info, "load_info", cb);
2268 if(This->load_group)
2269 note_cc_edge((nsISupports*)This->load_group, "load_group", cb);
2270 if(This->notif_callback)
2271 note_cc_edge((nsISupports*)This->notif_callback, "notif_callback", cb);
2272 if(This->original_uri)
2273 note_cc_edge((nsISupports*)This->original_uri, "original_uri", cb);
2274 if(This->referrer)
2275 note_cc_edge((nsISupports*)This->referrer, "referrer", cb);
2277 return NS_OK;
2280 static nsresult NSAPI nsChannel_unlink(void *p)
2282 nsChannel *This = impl_from_nsIHttpChannel(p);
2284 TRACE("%p\n", This);
2286 if(This->owner) {
2287 nsISupports *owner = This->owner;
2288 This->owner = NULL;
2289 nsISupports_Release(owner);
2291 if(This->post_data_stream) {
2292 nsIInputStream *post_data_stream = This->post_data_stream;
2293 This->post_data_stream = NULL;
2294 nsIInputStream_Release(post_data_stream);
2296 if(This->load_info) {
2297 nsISupports *load_info = This->load_info;
2298 This->load_info = NULL;
2299 nsISupports_Release(load_info);
2301 if(This->load_group) {
2302 nsILoadGroup *load_group = This->load_group;
2303 This->load_group = NULL;
2304 nsILoadGroup_Release(load_group);
2306 if(This->notif_callback) {
2307 nsIInterfaceRequestor *notif_callback = This->notif_callback;
2308 This->notif_callback = NULL;
2309 nsIInterfaceRequestor_Release(notif_callback);
2311 if(This->original_uri) {
2312 nsIURI *original_uri = This->original_uri;
2313 This->original_uri = NULL;
2314 nsIURI_Release(original_uri);
2316 if(This->referrer) {
2317 nsIURI *referrer = This->referrer;
2318 This->referrer = NULL;
2319 nsIURI_Release(referrer);
2322 return NS_OK;
2325 static void NSAPI nsChannel_delete_cycle_collectable(void *p)
2327 nsChannel *This = impl_from_nsIHttpChannel(p);
2328 nsChannel_unlink(p);
2330 TRACE("(%p)\n", This);
2332 nsIFileURL_Release(&This->uri->nsIFileURL_iface);
2333 free_http_headers(&This->response_headers);
2334 free_http_headers(&This->request_headers);
2336 free(This->content_type);
2337 free(This->charset);
2338 free(This);
2341 static void invalidate_uri(nsWineURI *This)
2343 if(This->uri) {
2344 IUri_Release(This->uri);
2345 This->uri = NULL;
2349 static BOOL ensure_uri_builder(nsWineURI *This)
2351 if(!This->is_mutable) {
2352 WARN("Not mutable URI\n");
2353 return FALSE;
2356 if(!This->uri_builder) {
2357 HRESULT hres;
2359 if(!ensure_uri(This))
2360 return FALSE;
2362 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
2363 if(FAILED(hres)) {
2364 WARN("CreateIUriBuilder failed: %08lx\n", hres);
2365 return FALSE;
2369 invalidate_uri(This);
2370 return TRUE;
2373 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
2375 char *vala;
2376 BSTR val;
2377 HRESULT hres;
2379 if(!ensure_uri(This))
2380 return NS_ERROR_UNEXPECTED;
2382 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
2383 if(FAILED(hres)) {
2384 WARN("GetPropertyBSTR failed: %08lx\n", hres);
2385 return NS_ERROR_UNEXPECTED;
2388 vala = strdupWtoU(hres == S_OK ? val : NULL);
2389 SysFreeString(val);
2390 if(hres == S_OK && !vala)
2391 return NS_ERROR_OUT_OF_MEMORY;
2393 TRACE("ret %s\n", debugstr_a(vala));
2394 nsACString_SetData(ret, vala);
2395 free(vala);
2396 return NS_OK;
2399 static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
2401 return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
2404 static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
2406 nsWineURI *This = impl_from_nsIFileURL(iface);
2408 *result = NULL;
2410 if(IsEqualGUID(&IID_nsISupports, riid)) {
2411 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2412 *result = &This->nsIFileURL_iface;
2413 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
2414 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
2415 *result = &This->nsIFileURL_iface;
2416 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
2417 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
2418 *result = &This->nsIFileURL_iface;
2419 }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
2420 TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
2421 *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
2422 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
2423 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
2424 *result = &This->nsIStandardURL_iface;
2425 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
2426 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
2427 *result = &This->nsIStandardURL_iface;
2428 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
2429 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
2430 *result = This;
2433 if(*result) {
2434 nsIFileURL_AddRef(&This->nsIFileURL_iface);
2435 return NS_OK;
2438 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
2439 return NS_NOINTERFACE;
2442 static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
2444 nsWineURI *This = impl_from_nsIFileURL(iface);
2445 LONG ref = InterlockedIncrement(&This->ref);
2447 TRACE("(%p) ref=%ld\n", This, ref);
2449 return ref;
2452 static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
2454 nsWineURI *This = impl_from_nsIFileURL(iface);
2455 LONG ref = InterlockedDecrement(&This->ref);
2457 TRACE("(%p) ref=%ld\n", This, ref);
2459 if(!ref) {
2460 if(This->uri)
2461 IUri_Release(This->uri);
2462 if(This->uri_builder)
2463 IUriBuilder_Release(This->uri_builder);
2464 free(This);
2467 return ref;
2470 static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
2472 nsWineURI *This = impl_from_nsIFileURL(iface);
2474 TRACE("(%p)->(%p)\n", This, aSpec);
2476 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
2479 static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
2481 nsWineURI *This = impl_from_nsIFileURL(iface);
2482 const char *speca;
2483 WCHAR *spec;
2484 IUri *uri;
2485 HRESULT hres;
2487 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
2489 if(!This->is_mutable)
2490 return NS_ERROR_UNEXPECTED;
2492 nsACString_GetData(aSpec, &speca);
2493 spec = strdupUtoW(speca);
2494 if(!spec)
2495 return NS_ERROR_OUT_OF_MEMORY;
2497 hres = create_uri(spec, 0, &uri);
2498 free(spec);
2499 if(FAILED(hres)) {
2500 WARN("create_uri failed: %08lx\n", hres);
2501 return NS_ERROR_FAILURE;
2504 invalidate_uri(This);
2505 if(This->uri_builder) {
2506 IUriBuilder_Release(This->uri_builder);
2507 This->uri_builder = NULL;
2510 This->uri = uri;
2511 return NS_OK;
2514 static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
2516 nsWineURI *This = impl_from_nsIFileURL(iface);
2517 IUriBuilder *uri_builder;
2518 BSTR display_uri;
2519 IUri *uri;
2520 int len;
2521 nsresult nsres;
2522 HRESULT hres;
2524 TRACE("(%p)->(%p)\n", This, aPrePath);
2526 if(!ensure_uri(This))
2527 return NS_ERROR_UNEXPECTED;
2529 hres = CreateIUriBuilder(This->uri, 0, 0, &uri_builder);
2530 if(FAILED(hres))
2531 return NS_ERROR_FAILURE;
2533 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_PATH|Uri_HAS_QUERY|Uri_HAS_FRAGMENT);
2534 if(SUCCEEDED(hres))
2535 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &uri);
2536 IUriBuilder_Release(uri_builder);
2537 if(FAILED(hres))
2538 return NS_ERROR_FAILURE;
2540 hres = IUri_GetDisplayUri(uri, &display_uri);
2541 IUri_Release(uri);
2542 if(FAILED(hres))
2543 return NS_ERROR_FAILURE;
2545 /* Remove trailing slash that may be appended as default path. */
2546 len = SysStringLen(display_uri);
2547 if(len && display_uri[len-1] == '/')
2548 display_uri[len-1] = 0;
2550 nsres = return_wstr_nsacstr(aPrePath, display_uri, -1);
2551 SysFreeString(display_uri);
2552 return nsres;
2555 static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
2557 nsWineURI *This = impl_from_nsIFileURL(iface);
2558 DWORD scheme;
2559 HRESULT hres;
2561 TRACE("(%p)->(%p)\n", This, aScheme);
2563 if(!ensure_uri(This))
2564 return NS_ERROR_UNEXPECTED;
2566 hres = IUri_GetScheme(This->uri, &scheme);
2567 if(FAILED(hres)) {
2568 WARN("GetScheme failed: %08lx\n", hres);
2569 return NS_ERROR_UNEXPECTED;
2572 if(scheme == URL_SCHEME_ABOUT) {
2573 nsACString_SetData(aScheme, "wine");
2574 return NS_OK;
2577 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
2580 static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
2582 nsWineURI *This = impl_from_nsIFileURL(iface);
2583 const char *schemea;
2584 WCHAR *scheme;
2585 HRESULT hres;
2587 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
2589 if(!ensure_uri_builder(This))
2590 return NS_ERROR_UNEXPECTED;
2592 nsACString_GetData(aScheme, &schemea);
2593 scheme = strdupUtoW(schemea);
2594 if(!scheme)
2595 return NS_ERROR_OUT_OF_MEMORY;
2597 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
2598 free(scheme);
2599 if(FAILED(hres))
2600 return NS_ERROR_UNEXPECTED;
2602 return NS_OK;
2605 static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
2607 nsWineURI *This = impl_from_nsIFileURL(iface);
2608 BSTR user, pass;
2609 HRESULT hres;
2611 TRACE("(%p)->(%p)\n", This, aUserPass);
2613 if(!ensure_uri(This))
2614 return NS_ERROR_UNEXPECTED;
2616 hres = IUri_GetUserName(This->uri, &user);
2617 if(FAILED(hres))
2618 return NS_ERROR_FAILURE;
2620 hres = IUri_GetPassword(This->uri, &pass);
2621 if(FAILED(hres)) {
2622 SysFreeString(user);
2623 return NS_ERROR_FAILURE;
2626 if(*user || *pass) {
2627 FIXME("Construct user:pass string\n");
2628 }else {
2629 nsACString_SetData(aUserPass, "");
2632 SysFreeString(user);
2633 SysFreeString(pass);
2634 return NS_OK;
2637 static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
2639 nsWineURI *This = impl_from_nsIFileURL(iface);
2640 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
2641 const char *user_pass;
2642 HRESULT hres;
2644 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
2646 if(!ensure_uri_builder(This))
2647 return NS_ERROR_UNEXPECTED;
2649 nsACString_GetData(aUserPass, &user_pass);
2650 if(*user_pass) {
2651 WCHAR *ptr;
2653 buf = strdupUtoW(user_pass);
2654 if(!buf)
2655 return NS_ERROR_OUT_OF_MEMORY;
2657 ptr = wcschr(buf, ':');
2658 if(!ptr) {
2659 user = buf;
2660 }else if(ptr != buf) {
2661 *ptr++ = 0;
2662 user = buf;
2663 if(*ptr)
2664 pass = ptr;
2665 }else {
2666 pass = buf+1;
2670 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2671 if(SUCCEEDED(hres))
2672 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2674 free(buf);
2675 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2678 static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
2680 nsWineURI *This = impl_from_nsIFileURL(iface);
2682 TRACE("(%p)->(%p)\n", This, aUsername);
2684 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2687 static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
2689 nsWineURI *This = impl_from_nsIFileURL(iface);
2690 const char *usera;
2691 WCHAR *user;
2692 HRESULT hres;
2694 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2696 if(!ensure_uri_builder(This))
2697 return NS_ERROR_UNEXPECTED;
2699 nsACString_GetData(aUsername, &usera);
2700 user = strdupUtoW(usera);
2701 if(!user)
2702 return NS_ERROR_OUT_OF_MEMORY;
2704 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2705 free(user);
2706 if(FAILED(hres))
2707 return NS_ERROR_UNEXPECTED;
2709 return NS_OK;
2712 static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
2714 nsWineURI *This = impl_from_nsIFileURL(iface);
2716 TRACE("(%p)->(%p)\n", This, aPassword);
2718 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2721 static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
2723 nsWineURI *This = impl_from_nsIFileURL(iface);
2724 const char *passa;
2725 WCHAR *pass;
2726 HRESULT hres;
2728 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2730 if(!ensure_uri_builder(This))
2731 return NS_ERROR_UNEXPECTED;
2733 nsACString_GetData(aPassword, &passa);
2734 pass = strdupUtoW(passa);
2735 if(!pass)
2736 return NS_ERROR_OUT_OF_MEMORY;
2738 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2739 free(pass);
2740 if(FAILED(hres))
2741 return NS_ERROR_UNEXPECTED;
2743 return NS_OK;
2746 static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
2748 nsWineURI *This = impl_from_nsIFileURL(iface);
2749 const WCHAR *ptr = NULL;
2750 char *vala;
2751 BSTR val;
2752 HRESULT hres;
2754 TRACE("(%p)->(%p)\n", This, aHostPort);
2756 if(!ensure_uri(This))
2757 return NS_ERROR_UNEXPECTED;
2759 hres = IUri_GetAuthority(This->uri, &val);
2760 if(FAILED(hres)) {
2761 WARN("GetAuthority failed: %08lx\n", hres);
2762 return NS_ERROR_UNEXPECTED;
2765 if(hres == S_OK) {
2766 ptr = wcschr(val, '@');
2767 if(!ptr)
2768 ptr = val;
2770 vala = strdupWtoU(ptr);
2771 SysFreeString(val);
2772 if(hres == S_OK && !vala)
2773 return NS_ERROR_OUT_OF_MEMORY;
2775 TRACE("ret %s\n", debugstr_a(vala));
2776 nsACString_SetData(aHostPort, vala);
2777 free(vala);
2778 return NS_OK;
2781 static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
2783 nsWineURI *This = impl_from_nsIFileURL(iface);
2785 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2787 /* Not implemented by Gecko */
2788 return NS_ERROR_NOT_IMPLEMENTED;
2791 static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
2793 nsWineURI *This = impl_from_nsIFileURL(iface);
2795 TRACE("(%p)->(%p)\n", This, aHost);
2797 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2800 static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
2802 nsWineURI *This = impl_from_nsIFileURL(iface);
2803 const char *hosta;
2804 WCHAR *host;
2805 HRESULT hres;
2807 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2809 if(!ensure_uri_builder(This))
2810 return NS_ERROR_UNEXPECTED;
2812 nsACString_GetData(aHost, &hosta);
2813 host = strdupUtoW(hosta);
2814 if(!host)
2815 return NS_ERROR_OUT_OF_MEMORY;
2817 hres = IUriBuilder_SetHost(This->uri_builder, host);
2818 free(host);
2819 if(FAILED(hres))
2820 return NS_ERROR_UNEXPECTED;
2822 return NS_OK;
2825 static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
2827 nsWineURI *This = impl_from_nsIFileURL(iface);
2828 DWORD port;
2829 HRESULT hres;
2831 TRACE("(%p)->(%p)\n", This, aPort);
2833 if(!ensure_uri(This))
2834 return NS_ERROR_UNEXPECTED;
2836 hres = IUri_GetPort(This->uri, &port);
2837 if(FAILED(hres)) {
2838 WARN("GetPort failed: %08lx\n", hres);
2839 return NS_ERROR_UNEXPECTED;
2842 *aPort = port ? port : -1;
2843 return NS_OK;
2846 static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
2848 nsWineURI *This = impl_from_nsIFileURL(iface);
2849 HRESULT hres;
2851 TRACE("(%p)->(%ld)\n", This, aPort);
2853 if(!ensure_uri_builder(This))
2854 return NS_ERROR_UNEXPECTED;
2856 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2857 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2860 static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
2862 nsWineURI *This = impl_from_nsIFileURL(iface);
2864 TRACE("(%p)->(%p)\n", This, aPath);
2866 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2869 static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
2871 nsWineURI *This = impl_from_nsIFileURL(iface);
2872 const char *patha;
2873 WCHAR *path;
2874 HRESULT hres;
2876 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2878 if(!ensure_uri_builder(This))
2879 return NS_ERROR_UNEXPECTED;
2881 nsACString_GetData(aPath, &patha);
2882 path = strdupUtoW(patha);
2883 if(!path)
2884 return NS_ERROR_OUT_OF_MEMORY;
2886 hres = IUriBuilder_SetPath(This->uri_builder, path);
2887 free(path);
2888 if(FAILED(hres))
2889 return NS_ERROR_UNEXPECTED;
2891 return NS_OK;
2894 static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2896 nsWineURI *This = impl_from_nsIFileURL(iface);
2897 nsWineURI *other_obj;
2898 nsresult nsres;
2899 HRESULT hres;
2901 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2903 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2904 if(NS_FAILED(nsres)) {
2905 TRACE("Could not get nsWineURI interface\n");
2906 *_retval = FALSE;
2907 return NS_OK;
2910 if(ensure_uri(This) && ensure_uri(other_obj)) {
2911 BOOL b;
2913 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2914 if(SUCCEEDED(hres)) {
2915 *_retval = b;
2916 nsres = NS_OK;
2917 }else {
2918 nsres = NS_ERROR_FAILURE;
2920 }else {
2921 nsres = NS_ERROR_UNEXPECTED;
2924 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2925 return nsres;
2928 static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
2930 nsWineURI *This = impl_from_nsIFileURL(iface);
2931 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2932 BSTR scheme_name;
2933 HRESULT hres;
2935 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2937 if(!ensure_uri(This))
2938 return NS_ERROR_UNEXPECTED;
2940 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2941 if(FAILED(hres))
2942 return NS_ERROR_UNEXPECTED;
2944 if(hres != S_OK)
2945 *_retval = FALSE;
2946 else {
2947 MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, ARRAY_SIZE(buf));
2948 *_retval = !wcscmp(scheme_name, buf);
2950 SysFreeString(scheme_name);
2951 return NS_OK;
2954 static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
2956 nsWineURI *This = impl_from_nsIFileURL(iface);
2957 nsWineURI *wine_uri;
2958 nsresult nsres;
2960 TRACE("(%p)->(%p)\n", This, _retval);
2962 if(!ensure_uri(This))
2963 return NS_ERROR_UNEXPECTED;
2965 nsres = create_nsuri(This->uri, &wine_uri);
2966 if(NS_FAILED(nsres)) {
2967 WARN("create_nsuri failed: %08lx\n", nsres);
2968 return nsres;
2971 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2972 return NS_OK;
2975 static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
2976 nsACString *_retval)
2978 nsWineURI *This = impl_from_nsIFileURL(iface);
2979 const char *patha;
2980 IUri *new_uri;
2981 WCHAR *path;
2982 char *reta;
2983 BSTR ret;
2984 HRESULT hres;
2986 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2988 if(!ensure_uri(This))
2989 return NS_ERROR_UNEXPECTED;
2991 nsACString_GetData(aRelativePath, &patha);
2992 path = strdupUtoW(patha);
2993 if(!path)
2994 return NS_ERROR_OUT_OF_MEMORY;
2996 hres = combine_url(This->uri, path, &new_uri);
2997 free(path);
2998 if(FAILED(hres))
2999 return NS_ERROR_FAILURE;
3001 hres = IUri_GetDisplayUri(new_uri, &ret);
3002 IUri_Release(new_uri);
3003 if(FAILED(hres))
3004 return NS_ERROR_FAILURE;
3006 reta = strdupWtoU(ret);
3007 SysFreeString(ret);
3008 if(!reta)
3009 return NS_ERROR_OUT_OF_MEMORY;
3011 TRACE("returning %s\n", debugstr_a(reta));
3012 nsACString_SetData(_retval, reta);
3013 free(reta);
3014 return NS_OK;
3017 static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
3019 nsWineURI *This = impl_from_nsIFileURL(iface);
3021 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
3023 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
3026 static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort)
3028 nsWineURI *This = impl_from_nsIFileURL(iface);
3030 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort);
3032 return nsIFileURL_GetHostPort(&This->nsIFileURL_iface, aAsciiHostPort);
3035 static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
3037 nsWineURI *This = impl_from_nsIFileURL(iface);
3039 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
3041 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
3044 static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
3046 nsWineURI *This = impl_from_nsIFileURL(iface);
3048 TRACE("(%p)->(%p)\n", This, aOriginCharset);
3050 nsACString_SetData(aOriginCharset, NULL); /* assume utf-8, we store URI as utf-16 anyway */
3051 return NS_OK;
3054 static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
3056 nsWineURI *This = impl_from_nsIFileURL(iface);
3057 char *refa = NULL;
3058 BSTR ref;
3059 HRESULT hres;
3061 TRACE("(%p)->(%p)\n", This, aRef);
3063 if(!ensure_uri(This))
3064 return NS_ERROR_UNEXPECTED;
3066 hres = IUri_GetFragment(This->uri, &ref);
3067 if(FAILED(hres))
3068 return NS_ERROR_UNEXPECTED;
3070 refa = strdupWtoU(ref);
3071 SysFreeString(ref);
3072 if(ref && !refa)
3073 return NS_ERROR_OUT_OF_MEMORY;
3075 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
3076 free(refa);
3077 return NS_OK;
3080 static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
3082 nsWineURI *This = impl_from_nsIFileURL(iface);
3083 const char *refa;
3084 WCHAR *ref;
3085 HRESULT hres;
3087 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
3089 if(!ensure_uri_builder(This))
3090 return NS_ERROR_UNEXPECTED;
3092 nsACString_GetData(aRef, &refa);
3093 ref = strdupUtoW(refa);
3094 if(!ref)
3095 return NS_ERROR_OUT_OF_MEMORY;
3097 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
3098 free(ref);
3099 if(FAILED(hres))
3100 return NS_ERROR_UNEXPECTED;
3102 return NS_OK;
3105 static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
3107 nsWineURI *This = impl_from_nsIFileURL(iface);
3108 nsWineURI *other_obj;
3109 nsresult nsres;
3111 TRACE("(%p)->(%p %p)\n", This, other, _retval);
3113 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
3114 if(NS_FAILED(nsres)) {
3115 TRACE("Could not get nsWineURI interface\n");
3116 *_retval = FALSE;
3117 return NS_OK;
3120 if(ensure_uri(This) && ensure_uri(other_obj)) {
3121 *_retval = compare_uri_ignoring_frag(This->uri, other_obj->uri);
3122 nsres = NS_OK;
3123 }else {
3124 nsres = NS_ERROR_UNEXPECTED;
3127 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
3128 return nsres;
3131 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
3133 nsWineURI *This = impl_from_nsIFileURL(iface);
3134 nsWineURI *wine_uri;
3135 IUri *uri;
3136 nsresult nsres;
3138 TRACE("(%p)->(%p)\n", This, _retval);
3140 if(!ensure_uri(This))
3141 return NS_ERROR_UNEXPECTED;
3143 uri = get_uri_nofrag(This->uri);
3144 if(!uri)
3145 return NS_ERROR_FAILURE;
3147 nsres = create_nsuri(uri, &wine_uri);
3148 IUri_Release(uri);
3149 if(NS_FAILED(nsres)) {
3150 WARN("create_nsuri failed: %08lx\n", nsres);
3151 return nsres;
3154 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3155 return NS_OK;
3158 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
3160 nsWineURI *This = impl_from_nsIFileURL(iface);
3162 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
3164 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
3167 static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
3169 nsWineURI *This = impl_from_nsIFileURL(iface);
3170 BOOL b;
3171 HRESULT hres;
3173 TRACE("(%p)->(%p)\n", This, aHasRef);
3175 if(!ensure_uri(This))
3176 return NS_ERROR_UNEXPECTED;
3178 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
3179 if(FAILED(hres))
3180 return NS_ERROR_FAILURE;
3182 *aHasRef = b;
3183 return NS_OK;
3186 static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
3188 nsWineURI *This = impl_from_nsIFileURL(iface);
3190 TRACE("(%p)->(%p)\n", This, aFilePath);
3192 return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
3195 static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
3197 nsWineURI *This = impl_from_nsIFileURL(iface);
3199 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
3201 if(!This->is_mutable)
3202 return NS_ERROR_UNEXPECTED;
3204 return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
3207 static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
3209 nsWineURI *This = impl_from_nsIFileURL(iface);
3210 WCHAR *ptr;
3211 BSTR query;
3212 nsresult nsres;
3213 HRESULT hres;
3215 TRACE("(%p)->(%p)\n", This, aQuery);
3217 if(!ensure_uri(This))
3218 return NS_ERROR_UNEXPECTED;
3220 hres = IUri_GetQuery(This->uri, &query);
3221 if(FAILED(hres))
3222 return NS_ERROR_FAILURE;
3224 ptr = query;
3225 if(ptr && *ptr == '?')
3226 ptr++;
3228 nsres = return_wstr_nsacstr(aQuery, ptr, -1);
3229 SysFreeString(query);
3230 return nsres;
3233 static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
3235 nsWineURI *This = impl_from_nsIFileURL(iface);
3236 const char *querya;
3237 WCHAR *query;
3238 HRESULT hres;
3240 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
3242 if(!ensure_uri_builder(This))
3243 return NS_ERROR_UNEXPECTED;
3245 nsACString_GetData(aQuery, &querya);
3246 query = strdupUtoW(querya);
3247 if(!query)
3248 return NS_ERROR_OUT_OF_MEMORY;
3250 hres = IUriBuilder_SetQuery(This->uri_builder, query);
3251 free(query);
3252 if(FAILED(hres))
3253 return NS_ERROR_UNEXPECTED;
3255 return NS_OK;
3258 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
3260 const WCHAR *ptr;
3261 HRESULT hres;
3263 if(!ensure_uri(This))
3264 return NS_ERROR_UNEXPECTED;
3266 hres = IUri_GetPath(This->uri, path);
3267 if(FAILED(hres))
3268 return NS_ERROR_FAILURE;
3269 if(hres != S_OK) {
3270 SysFreeString(*path);
3271 *ext = *file = *path = NULL;
3272 return NS_OK;
3275 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
3276 if(*ptr == '/' || *ptr == '\\')
3277 ptr++;
3278 *file = ptr;
3280 if(ext) {
3281 ptr = wcsrchr(ptr, '.');
3282 if(!ptr)
3283 ptr = *path + SysStringLen(*path);
3284 *ext = ptr;
3287 return NS_OK;
3290 static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
3292 nsWineURI *This = impl_from_nsIFileURL(iface);
3293 const WCHAR *file;
3294 BSTR path;
3295 nsresult nsres;
3297 TRACE("(%p)->(%p)\n", This, aDirectory);
3299 nsres = get_uri_path(This, &path, &file, NULL);
3300 if(NS_FAILED(nsres))
3301 return nsres;
3303 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
3304 SysFreeString(path);
3305 return nsres;
3308 static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
3310 nsWineURI *This = impl_from_nsIFileURL(iface);
3312 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
3314 /* Not implemented by Gecko */
3315 return NS_ERROR_NOT_IMPLEMENTED;
3318 static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
3320 nsWineURI *This = impl_from_nsIFileURL(iface);
3321 const WCHAR *file;
3322 BSTR path;
3323 nsresult nsres;
3325 TRACE("(%p)->(%p)\n", This, aFileName);
3327 nsres = get_uri_path(This, &path, &file, NULL);
3328 if(NS_FAILED(nsres))
3329 return nsres;
3331 nsres = return_wstr_nsacstr(aFileName, file, -1);
3332 SysFreeString(path);
3333 return nsres;
3336 static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
3338 nsWineURI *This = impl_from_nsIFileURL(iface);
3339 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
3340 return NS_ERROR_NOT_IMPLEMENTED;
3343 static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
3345 nsWineURI *This = impl_from_nsIFileURL(iface);
3346 const WCHAR *file, *ext;
3347 BSTR path;
3348 nsresult nsres;
3350 TRACE("(%p)->(%p)\n", This, aFileBaseName);
3352 nsres = get_uri_path(This, &path, &file, &ext);
3353 if(NS_FAILED(nsres))
3354 return nsres;
3356 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
3357 SysFreeString(path);
3358 return nsres;
3361 static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
3363 nsWineURI *This = impl_from_nsIFileURL(iface);
3364 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
3365 return NS_ERROR_NOT_IMPLEMENTED;
3368 static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
3370 nsWineURI *This = impl_from_nsIFileURL(iface);
3372 TRACE("(%p)->(%p)\n", This, aFileExtension);
3374 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
3377 static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
3379 nsWineURI *This = impl_from_nsIFileURL(iface);
3380 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
3381 return NS_ERROR_NOT_IMPLEMENTED;
3384 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3386 nsWineURI *This = impl_from_nsIFileURL(iface);
3387 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3388 return NS_ERROR_NOT_IMPLEMENTED;
3391 static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3393 nsWineURI *This = impl_from_nsIFileURL(iface);
3394 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3395 return NS_ERROR_NOT_IMPLEMENTED;
3398 static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
3400 nsWineURI *This = impl_from_nsIFileURL(iface);
3401 WCHAR path[MAX_PATH];
3402 DWORD size;
3403 HRESULT hres;
3405 TRACE("(%p)->(%p)\n", This, aFile);
3407 hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
3408 if(FAILED(hres)) {
3409 WARN("CoInternetParseIUri failed: %08lx\n", hres);
3410 return NS_ERROR_FAILURE;
3413 return create_nsfile(path, aFile);
3416 static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
3418 nsWineURI *This = impl_from_nsIFileURL(iface);
3419 FIXME("(%p)->(%p)\n", This, aFile);
3420 return NS_ERROR_NOT_IMPLEMENTED;
3423 static const nsIFileURLVtbl nsFileURLVtbl = {
3424 nsURI_QueryInterface,
3425 nsURI_AddRef,
3426 nsURI_Release,
3427 nsURI_GetSpec,
3428 nsURI_SetSpec,
3429 nsURI_GetPrePath,
3430 nsURI_GetScheme,
3431 nsURI_SetScheme,
3432 nsURI_GetUserPass,
3433 nsURI_SetUserPass,
3434 nsURI_GetUsername,
3435 nsURI_SetUsername,
3436 nsURI_GetPassword,
3437 nsURI_SetPassword,
3438 nsURI_GetHostPort,
3439 nsURI_SetHostPort,
3440 nsURI_GetHost,
3441 nsURI_SetHost,
3442 nsURI_GetPort,
3443 nsURI_SetPort,
3444 nsURI_GetPath,
3445 nsURI_SetPath,
3446 nsURI_Equals,
3447 nsURI_SchemeIs,
3448 nsURI_Clone,
3449 nsURI_Resolve,
3450 nsURI_GetAsciiSpec,
3451 nsURI_GetAsciiHostPort,
3452 nsURI_GetAsciiHost,
3453 nsURI_GetOriginCharset,
3454 nsURL_GetRef,
3455 nsURL_SetRef,
3456 nsURI_EqualsExceptRef,
3457 nsURI_CloneIgnoreRef,
3458 nsURI_GetSpecIgnoringRef,
3459 nsURI_GetHasRef,
3460 nsURL_GetFilePath,
3461 nsURL_SetFilePath,
3462 nsURL_GetQuery,
3463 nsURL_SetQuery,
3464 nsURL_GetDirectory,
3465 nsURL_SetDirectory,
3466 nsURL_GetFileName,
3467 nsURL_SetFileName,
3468 nsURL_GetFileBaseName,
3469 nsURL_SetFileBaseName,
3470 nsURL_GetFileExtension,
3471 nsURL_SetFileExtension,
3472 nsURL_GetCommonBaseSpec,
3473 nsURL_GetRelativeSpec,
3474 nsFileURL_GetFile,
3475 nsFileURL_SetFile
3478 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
3480 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
3483 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
3484 void **result)
3486 nsWineURI *This = impl_from_nsIStandardURL(iface);
3487 return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
3490 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
3492 nsWineURI *This = impl_from_nsIStandardURL(iface);
3493 return nsIFileURL_AddRef(&This->nsIFileURL_iface);
3496 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
3498 nsWineURI *This = impl_from_nsIStandardURL(iface);
3499 return nsIFileURL_Release(&This->nsIFileURL_iface);
3502 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
3504 nsWineURI *This = impl_from_nsIStandardURL(iface);
3506 TRACE("(%p)->(%p)\n", This, aMutable);
3508 *aMutable = This->is_mutable;
3509 return NS_OK;
3512 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
3514 nsWineURI *This = impl_from_nsIStandardURL(iface);
3516 TRACE("(%p)->(%x)\n", This, aMutable);
3518 This->is_mutable = aMutable;
3519 return NS_OK;
3522 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
3523 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
3525 nsWineURI *This = impl_from_nsIStandardURL(iface);
3526 FIXME("(%p)->(%d %ld %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
3527 return NS_ERROR_NOT_IMPLEMENTED;
3530 static nsresult NSAPI nsStandardURL_SetDefaultPort(nsIStandardURL *iface, LONG aNewDefaultPort)
3532 nsWineURI *This = impl_from_nsIStandardURL(iface);
3533 FIXME("(%p)->(%ld)\n", This, aNewDefaultPort);
3534 return NS_ERROR_NOT_IMPLEMENTED;
3537 static const nsIStandardURLVtbl nsStandardURLVtbl = {
3538 nsStandardURL_QueryInterface,
3539 nsStandardURL_AddRef,
3540 nsStandardURL_Release,
3541 nsStandardURL_GetMutable,
3542 nsStandardURL_SetMutable,
3543 nsStandardURL_Init,
3544 nsStandardURL_SetDefaultPort
3547 static nsresult create_nsuri(IUri *iuri, nsWineURI **_retval)
3549 nsWineURI *ret;
3550 HRESULT hres;
3552 ret = calloc(1, sizeof(nsWineURI));
3553 if(!ret)
3554 return NS_ERROR_OUT_OF_MEMORY;
3556 ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
3557 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
3558 ret->ref = 1;
3559 ret->is_mutable = TRUE;
3561 IUri_AddRef(iuri);
3562 ret->uri = iuri;
3564 hres = IUri_GetScheme(iuri, &ret->scheme);
3565 if(hres != S_OK)
3566 ret->scheme = URL_SCHEME_UNKNOWN;
3568 TRACE("retval=%p\n", ret);
3569 *_retval = ret;
3570 return NS_OK;
3573 HRESULT create_doc_uri(IUri *iuri, nsWineURI **ret)
3575 nsresult nsres;
3576 nsres = create_nsuri(iuri, ret);
3577 return NS_SUCCEEDED(nsres) ? S_OK : E_OUTOFMEMORY;
3580 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
3582 nsChannel *channel;
3584 if(!ensure_uri(uri))
3585 return NS_ERROR_UNEXPECTED;
3587 channel = calloc(1, sizeof(nsChannel));
3588 if(!channel)
3589 return NS_ERROR_OUT_OF_MEMORY;
3591 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
3592 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
3593 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
3594 channel->nsICacheInfoChannel_iface.lpVtbl = &nsCacheInfoChannelVtbl;
3595 channel->request_method = METHOD_GET;
3596 list_init(&channel->response_headers);
3597 list_init(&channel->request_headers);
3598 ccref_init(&channel->ccref, 1);
3600 nsIFileURL_AddRef(&uri->nsIFileURL_iface);
3601 channel->uri = uri;
3603 *ret = channel;
3604 return NS_OK;
3607 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
3609 nsChannel *channel;
3610 nsWineURI *uri;
3611 IUri *iuri;
3612 nsresult nsres;
3613 HRESULT hres;
3615 hres = create_uri(url, 0, &iuri);
3616 if(FAILED(hres))
3617 return hres;
3619 nsres = create_nsuri(iuri, &uri);
3620 IUri_Release(iuri);
3621 if(NS_FAILED(nsres))
3622 return E_FAIL;
3624 nsres = create_nschannel(uri, &channel);
3625 nsIFileURL_Release(&uri->nsIFileURL_iface);
3626 if(NS_FAILED(nsres))
3627 return E_FAIL;
3629 if(orig_channel->load_group) {
3630 nsILoadGroup_AddRef(orig_channel->load_group);
3631 channel->load_group = orig_channel->load_group;
3634 if(orig_channel->notif_callback) {
3635 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
3636 channel->notif_callback = orig_channel->notif_callback;
3639 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
3641 if(orig_channel->request_method == METHOD_POST)
3642 FIXME("unsupported POST method\n");
3644 if(orig_channel->original_uri) {
3645 nsIURI_AddRef(orig_channel->original_uri);
3646 channel->original_uri = orig_channel->original_uri;
3649 if(orig_channel->referrer) {
3650 nsIURI_AddRef(orig_channel->referrer);
3651 channel->referrer = orig_channel->referrer;
3654 *ret = channel;
3655 return S_OK;
3658 typedef struct {
3659 nsIProtocolHandler nsIProtocolHandler_iface;
3661 LONG ref;
3663 nsIProtocolHandler *nshandler;
3664 } nsProtocolHandler;
3666 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
3668 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
3671 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
3672 void **result)
3674 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3676 *result = NULL;
3678 if(IsEqualGUID(&IID_nsISupports, riid)) {
3679 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
3680 *result = &This->nsIProtocolHandler_iface;
3681 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
3682 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
3683 *result = &This->nsIProtocolHandler_iface;
3684 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
3685 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
3686 return NS_NOINTERFACE;
3689 if(*result) {
3690 nsISupports_AddRef((nsISupports*)*result);
3691 return NS_OK;
3694 WARN("(%s %p)\n", debugstr_guid(riid), result);
3695 return NS_NOINTERFACE;
3698 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
3700 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3701 LONG ref = InterlockedIncrement(&This->ref);
3703 TRACE("(%p) ref=%ld\n", This, ref);
3705 return ref;
3708 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3710 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3711 LONG ref = InterlockedDecrement(&This->ref);
3713 TRACE("(%p) ref=%ld\n", This, ref);
3715 if(!ref) {
3716 if(This->nshandler)
3717 nsIProtocolHandler_Release(This->nshandler);
3718 free(This);
3721 return ref;
3724 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3726 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3728 TRACE("(%p)->(%p)\n", This, aScheme);
3730 if(This->nshandler)
3731 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3732 return NS_ERROR_NOT_IMPLEMENTED;
3735 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3736 LONG *aDefaultPort)
3738 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3740 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3742 if(This->nshandler)
3743 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3744 return NS_ERROR_NOT_IMPLEMENTED;
3747 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3748 UINT32 *aProtocolFlags)
3750 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3752 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3754 if(This->nshandler)
3755 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3756 return NS_ERROR_NOT_IMPLEMENTED;
3759 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3760 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3762 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3764 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3765 aBaseURI, _retval);
3767 if(This->nshandler)
3768 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3769 return NS_ERROR_NOT_IMPLEMENTED;
3772 static nsresult NSAPI nsProtocolHandler_NewChannel2(nsIProtocolHandler *iface,
3773 nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3775 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3777 TRACE("(%p)->(%p %p %p)\n", This, aURI, aLoadInfo, _retval);
3779 if(This->nshandler)
3780 return nsIProtocolHandler_NewChannel2(This->nshandler, aURI, aLoadInfo, _retval);
3781 return NS_ERROR_NOT_IMPLEMENTED;
3784 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3785 nsIURI *aURI, nsIChannel **_retval)
3787 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3789 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3791 if(This->nshandler)
3792 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3793 return NS_ERROR_NOT_IMPLEMENTED;
3796 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3797 LONG port, const char *scheme, cpp_bool *_retval)
3799 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3801 TRACE("(%p)->(%ld %s %p)\n", This, port, debugstr_a(scheme), _retval);
3803 if(This->nshandler)
3804 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3805 return NS_ERROR_NOT_IMPLEMENTED;
3808 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3809 nsProtocolHandler_QueryInterface,
3810 nsProtocolHandler_AddRef,
3811 nsProtocolHandler_Release,
3812 nsProtocolHandler_GetScheme,
3813 nsProtocolHandler_GetDefaultPort,
3814 nsProtocolHandler_GetProtocolFlags,
3815 nsProtocolHandler_NewURI,
3816 nsProtocolHandler_NewChannel2,
3817 nsProtocolHandler_NewChannel,
3818 nsProtocolHandler_AllowPort
3821 static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid,
3822 void **result)
3824 if(IsEqualGUID(&IID_nsISupports, riid)) {
3825 TRACE("(IID_nsISupports %p)\n", result);
3826 *result = iface;
3827 }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) {
3828 TRACE("(IID_nsIIOServiceHook %p)\n", result);
3829 *result = iface;
3830 }else {
3831 ERR("(%s %p)\n", debugstr_guid(riid), result);
3832 *result = NULL;
3833 return NS_NOINTERFACE;
3836 nsISupports_AddRef((nsISupports*)*result);
3837 return NS_OK;
3840 static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface)
3842 return 2;
3845 static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface)
3847 return 1;
3850 static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI,
3851 nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3853 nsWineURI *wine_uri;
3854 nsChannel *ret;
3855 nsresult nsres;
3857 TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval);
3859 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3860 if(NS_FAILED(nsres)) {
3861 TRACE("Could not get nsWineURI: %08lx\n", nsres);
3862 return NS_SUCCESS_DEFAULT_ACTION;
3865 nsres = create_nschannel(wine_uri, &ret);
3866 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3867 if(NS_FAILED(nsres))
3868 return nsres;
3870 nsIURI_AddRef(aURI);
3871 ret->original_uri = aURI;
3873 if(aLoadInfo)
3874 nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo);
3876 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3877 return NS_OK;
3880 static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler,
3881 nsIProtocolHandler **_retval)
3883 nsIExternalProtocolHandler *nsexthandler;
3884 nsProtocolHandler *ret;
3885 nsresult nsres;
3887 TRACE("(%p %p)\n", aHandler, _retval);
3889 nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler);
3890 if(NS_FAILED(nsres)) {
3891 nsIProtocolHandler_AddRef(aHandler);
3892 *_retval = aHandler;
3893 return NS_OK;
3896 nsIExternalProtocolHandler_Release(nsexthandler);
3898 ret = malloc(sizeof(nsProtocolHandler));
3899 if(!ret)
3900 return NS_ERROR_OUT_OF_MEMORY;
3902 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3903 ret->ref = 1;
3904 nsIProtocolHandler_AddRef(aHandler);
3905 ret->nshandler = aHandler;
3908 *_retval = &ret->nsIProtocolHandler_iface;
3909 TRACE("return %p\n", *_retval);
3910 return NS_OK;
3913 static BOOL is_gecko_special_uri(const char *spec)
3915 static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource://gre/", "resource://gre-resources/", "javascript:", "wyciwyg:"};
3916 unsigned int i;
3918 for(i=0; i < ARRAY_SIZE(special_schemes); i++) {
3919 if(!_strnicmp(spec, special_schemes[i], strlen(special_schemes[i])))
3920 return TRUE;
3923 if(!_strnicmp(spec, "file:", 5)) {
3924 const char *ptr = spec+5;
3925 while(*ptr == '/')
3926 ptr++;
3927 return is_gecko_path(ptr);
3930 return FALSE;
3933 static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec,
3934 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3936 nsWineURI *wine_uri, *base_wine_uri = NULL;
3937 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3938 const char *spec = NULL;
3939 UINT cp = CP_UTF8;
3940 IUri *urlmon_uri;
3941 nsresult nsres;
3942 HRESULT hres;
3944 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3945 aBaseURI, _retval);
3947 nsACString_GetData(aSpec, &spec);
3948 if(is_gecko_special_uri(spec))
3949 return NS_SUCCESS_DEFAULT_ACTION;
3951 if(!strncmp(spec, "wine:", 5))
3952 spec += 5;
3954 if(aOriginCharset && *aOriginCharset && _strnicmp(aOriginCharset, "utf", 3)) {
3955 BSTR charset;
3956 int len;
3958 len = MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, NULL, 0);
3959 charset = SysAllocStringLen(NULL, len-1);
3960 if(!charset)
3961 return NS_ERROR_OUT_OF_MEMORY;
3962 MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, charset, len);
3964 cp = cp_from_charset_string(charset);
3966 SysFreeString(charset);
3969 MultiByteToWideChar(cp, 0, spec, -1, new_spec, ARRAY_SIZE(new_spec));
3971 if(aBaseURI) {
3972 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3973 if(NS_SUCCEEDED(nsres)) {
3974 if(!ensure_uri(base_wine_uri)) {
3975 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3976 return NS_ERROR_UNEXPECTED;
3978 }else {
3979 WARN("Could not get base nsWineURI: %08lx\n", nsres);
3983 if(base_wine_uri) {
3984 hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri);
3985 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3986 }else {
3987 hres = create_uri(new_spec, 0, &urlmon_uri);
3988 if(FAILED(hres))
3989 WARN("create_uri failed: %08lx\n", hres);
3992 if(FAILED(hres))
3993 return NS_SUCCESS_DEFAULT_ACTION;
3995 nsres = create_nsuri(urlmon_uri, &wine_uri);
3996 IUri_Release(urlmon_uri);
3997 if(NS_FAILED(nsres))
3998 return nsres;
4000 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
4001 return nsres;
4004 static const char *debugstr_protocol_flags(UINT32 flags)
4006 switch(flags) {
4007 #define X(f) case f: return #f
4008 X(URI_STD);
4009 X(URI_NORELATIVE);
4010 X(URI_NOAUTH);
4011 X(ALLOWS_PROXY);
4012 X(ALLOWS_PROXY_HTTP);
4013 X(URI_INHERITS_SECURITY_CONTEXT);
4014 X(URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
4015 X(URI_LOADABLE_BY_ANYONE);
4016 X(URI_DANGEROUS_TO_LOAD);
4017 X(URI_IS_UI_RESOURCE);
4018 X(URI_IS_LOCAL_FILE);
4019 X(URI_LOADABLE_BY_SUBSUMERS);
4020 X(URI_DOES_NOT_RETURN_DATA);
4021 X(URI_IS_LOCAL_RESOURCE);
4022 X(URI_OPENING_EXECUTES_SCRIPT);
4023 X(URI_NON_PERSISTABLE);
4024 X(URI_FORBIDS_COOKIE_ACCESS);
4025 X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM);
4026 X(URI_SYNC_LOAD_IS_OK);
4027 X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT);
4028 X(URI_FETCHABLE_BY_ANYONE);
4029 #undef X
4030 default:
4031 return wine_dbg_sprintf("%08x", flags);
4035 static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
4037 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
4038 return NS_SUCCESS_DEFAULT_ACTION;
4041 static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
4043 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
4045 if(aFlags == URI_DOES_NOT_RETURN_DATA) {
4046 *_retval = FALSE;
4047 return S_OK;
4050 return NS_SUCCESS_DEFAULT_ACTION;
4053 static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = {
4054 nsIOServiceHook_QueryInterface,
4055 nsIOServiceHook_AddRef,
4056 nsIOServiceHook_Release,
4057 nsIOServiceHook_NewChannel,
4058 nsIOServiceHook_GetProtocolHandler,
4059 nsIOServiceHook_NewURI,
4060 nsIOServiceHook_ProtocolHasFlags,
4061 nsIOServiceHook_URIChainHasFlags
4064 static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };
4066 void init_nsio(nsIComponentManager *component_manager)
4068 static const CCObjCallback nschannel_ccp_callback = {
4069 nsChannel_traverse,
4070 nsChannel_unlink,
4071 nsChannel_delete_cycle_collectable
4073 nsIFactory *old_factory = NULL;
4074 nsresult nsres;
4076 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
4077 &IID_nsIFactory, (void**)&old_factory);
4078 if(NS_FAILED(nsres)) {
4079 ERR("Could not get factory: %08lx\n", nsres);
4080 return;
4083 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
4084 nsIFactory_Release(old_factory);
4085 if(NS_FAILED(nsres)) {
4086 ERR("Couldn not create nsIOService instance %08lx\n", nsres);
4087 return;
4090 nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
4091 assert(nsres == NS_OK);
4093 ccp_init(&nschannel_ccp, &nschannel_ccp_callback);
4096 void release_nsio(void)
4098 if(nsio) {
4099 nsIIOService_Release(nsio);
4100 nsio = NULL;
4104 nsresult create_onload_blocker_request(nsIRequest **ret)
4106 nsIChannel *channel;
4107 nsACString spec;
4108 nsresult nsres;
4110 nsACString_InitDepend(&spec, "about:wine-script-onload-blocker");
4111 nsres = nsIIOService_NewChannel(nsio, &spec, NULL, NULL, &channel);
4112 nsACString_Finish(&spec);
4113 if(NS_FAILED(nsres)) {
4114 ERR("Failed to create channel: %08lx\n", nsres);
4115 return nsres;
4118 *ret = (nsIRequest *)channel;
4119 return NS_OK;