ntdll: Rename local variables in heap_reallocate.
[wine.git] / dlls / mshtml / nsio.c
blobe0b8bedf79cdc5c498dfc64b8e2f3b98a10bc0ed
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 nsIIOService *nsio = NULL;
50 static const char *request_method_strings[] = {"GET", "PUT", "POST"};
52 struct nsWineURI {
53 nsIFileURL nsIFileURL_iface; /* For non-file URL objects, it's just nsIURL */
54 nsIStandardURL nsIStandardURL_iface;
56 LONG ref;
58 nsChannelBSC *channel_bsc;
59 IUri *uri;
60 IUriBuilder *uri_builder;
61 BOOL is_mutable;
62 DWORD scheme;
65 static BOOL ensure_uri(nsWineURI *This)
67 HRESULT hres;
69 assert(This->uri || This->uri_builder);
71 if(!This->uri) {
72 hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
73 if(FAILED(hres)) {
74 WARN("CreateUriSimple failed: %08lx\n", hres);
75 return FALSE;
79 return TRUE;
82 IUri *nsuri_get_uri(nsWineURI *nsuri)
84 if(!ensure_uri(nsuri))
85 return NULL;
87 IUri_AddRef(nsuri->uri);
88 return nsuri->uri;
91 IUri *get_uri_nofrag(IUri *uri)
93 IUriBuilder *uri_builder;
94 IUri *ret;
95 BOOL b;
96 HRESULT hres;
98 hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
99 if(SUCCEEDED(hres) && !b) {
100 IUri_AddRef(uri);
101 return uri;
104 hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
105 if(FAILED(hres))
106 return NULL;
108 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
109 if(SUCCEEDED(hres))
110 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
111 IUriBuilder_Release(uri_builder);
112 if(FAILED(hres))
113 return NULL;
115 return ret;
118 static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
120 IUri *uri_nofrag1, *uri_nofrag2;
121 BOOL ret = FALSE;
123 uri_nofrag1 = get_uri_nofrag(uri1);
124 if(!uri_nofrag1)
125 return FALSE;
127 uri_nofrag2 = get_uri_nofrag(uri2);
128 if(uri_nofrag2) {
129 IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
130 IUri_Release(uri_nofrag2);
133 IUri_Release(uri_nofrag1);
134 return ret;
137 static HRESULT combine_url(IUri *base_uri, const WCHAR *rel_url, IUri **ret)
139 IUri *uri_nofrag;
140 HRESULT hres;
142 uri_nofrag = get_uri_nofrag(base_uri);
143 if(!uri_nofrag)
144 return E_FAIL;
146 hres = CoInternetCombineUrlEx(uri_nofrag, rel_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
147 ret, 0);
148 IUri_Release(uri_nofrag);
149 if(FAILED(hres))
150 WARN("CoInternetCombineUrlEx failed: %08lx\n", hres);
151 return hres;
154 static nsresult create_nsuri(IUri*,nsWineURI**);
156 static const char *debugstr_nsacstr(const nsACString *nsstr)
158 const char *data;
160 nsACString_GetData(nsstr, &data);
161 return debugstr_a(data);
164 static nsresult return_wstr_nsacstr(nsACString *ret_str, const WCHAR *str, int len)
166 char *stra;
167 int lena;
169 TRACE("returning %s\n", debugstr_wn(str, len));
171 if(!*str) {
172 nsACString_SetData(ret_str, "");
173 return NS_OK;
176 lena = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
177 stra = heap_alloc(lena+1);
178 if(!stra)
179 return NS_ERROR_OUT_OF_MEMORY;
181 WideCharToMultiByte(CP_UTF8, 0, str, len, stra, lena, NULL, NULL);
182 stra[lena] = 0;
184 nsACString_SetData(ret_str, stra);
185 heap_free(stra);
186 return NS_OK;
189 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
191 const WCHAR *ptr = nsuri;
193 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
195 if(!wcsncmp(nsuri, wine_prefixW, ARRAY_SIZE(wine_prefixW)))
196 ptr += ARRAY_SIZE(wine_prefixW);
198 if(*ptr || ret_empty) {
199 *ret = SysAllocString(ptr);
200 if(!*ret)
201 return E_OUTOFMEMORY;
202 }else {
203 *ret = NULL;
206 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
207 return S_OK;
210 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
212 IOleCommandTarget *cmdtrg = NULL;
213 HRESULT hres;
215 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
216 if(SUCCEEDED(hres)) {
217 VARIANT varUrl, varRes;
219 V_VT(&varUrl) = VT_BSTR;
220 V_BSTR(&varUrl) = url;
221 V_VT(&varRes) = VT_BOOL;
223 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
225 IOleCommandTarget_Release(cmdtrg);
227 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
228 TRACE("got VARIANT_FALSE, do not load\n");
229 return FALSE;
233 return TRUE;
236 static nsresult before_async_open(nsChannel *channel, GeckoBrowser *container, BOOL *cancel)
238 HTMLDocumentObj *doc = container->doc;
239 BSTR display_uri;
240 HRESULT hres;
242 if(!doc->client) {
243 *cancel = TRUE;
244 return NS_OK;
247 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
248 if(FAILED(hres))
249 return NS_ERROR_FAILURE;
251 if(doc->hostui) {
252 OLECHAR *new_url;
253 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, display_uri, &new_url);
254 if(hres == S_OK && new_url) {
255 if(wcscmp(display_uri, new_url)) {
256 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(display_uri), debugstr_w(new_url));
257 CoTaskMemFree(new_url);
258 *cancel = TRUE;
259 return NS_OK;
261 CoTaskMemFree(new_url);
265 if(!exec_shldocvw_67(doc, display_uri)) {
266 SysFreeString(display_uri);
267 *cancel = FALSE;
268 return NS_OK;
271 hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, 0, cancel);
272 SysFreeString(display_uri);
273 if(FAILED(hres))
274 *cancel = TRUE;
275 return NS_OK;
278 HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsIInputStream *post_stream,
279 nsChannelBSC *channelbsc, DWORD flags)
281 nsIWebNavigation *web_navigation;
282 nsIDocShellLoadInfo *load_info;
283 nsIDocShell *doc_shell;
284 HTMLDocumentNode *doc;
285 nsresult nsres;
287 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
288 if(NS_FAILED(nsres)) {
289 ERR("Could not get nsIWebNavigation interface: %08lx\n", nsres);
290 return E_FAIL;
293 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
294 nsIWebNavigation_Release(web_navigation);
295 if(NS_FAILED(nsres)) {
296 ERR("Could not get nsIDocShell: %08lx\n", nsres);
297 return E_FAIL;
300 nsres = nsIDocShell_CreateLoadInfo(doc_shell, &load_info);
301 if(NS_FAILED(nsres)) {
302 nsIDocShell_Release(doc_shell);
303 return E_FAIL;
306 nsres = nsIDocShellLoadInfo_SetLoadType(load_info, (flags & LOAD_FLAGS_BYPASS_CACHE) ? loadNormalBypassCache : loadNormal);
307 assert(nsres == NS_OK);
309 if(post_stream) {
310 nsres = nsIDocShellLoadInfo_SetPostDataStream(load_info, post_stream);
311 assert(nsres == NS_OK);
314 if(window->uri_nofrag) {
315 nsWineURI *referrer_uri;
316 nsres = create_nsuri(window->uri_nofrag, &referrer_uri);
317 if(NS_SUCCEEDED(nsres)) {
318 nsres = nsIDocShellLoadInfo_SetReferrer(load_info, (nsIURI*)&referrer_uri->nsIFileURL_iface);
319 assert(nsres == NS_OK);
320 nsIFileURL_Release(&referrer_uri->nsIFileURL_iface);
324 uri->channel_bsc = channelbsc;
325 doc = window->base.inner_window->doc;
326 doc->skip_mutation_notif = TRUE;
327 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, load_info, flags, FALSE);
328 if(doc == window->base.inner_window->doc)
329 doc->skip_mutation_notif = FALSE;
330 uri->channel_bsc = NULL;
331 nsIDocShell_Release(doc_shell);
332 nsIDocShellLoadInfo_Release(load_info);
333 if(NS_FAILED(nsres)) {
334 WARN("LoadURI failed: %08lx\n", nsres);
335 return E_FAIL;
338 return S_OK;
341 static inline BOOL is_http_channel(nsChannel *This)
343 return This->uri->scheme == URL_SCHEME_HTTP || This->uri->scheme == URL_SCHEME_HTTPS;
346 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
348 http_header_t *iter;
350 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
351 if(!wcsnicmp(iter->header, name, len) && !iter->header[len])
352 return iter;
355 return NULL;
358 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
359 nsACString *_retval)
361 const char *header_namea;
362 http_header_t *header;
363 WCHAR *header_name;
364 char *data;
366 nsACString_GetData(header_name_str, &header_namea);
367 header_name = heap_strdupAtoW(header_namea);
368 if(!header_name)
369 return NS_ERROR_UNEXPECTED;
371 header = find_http_header(headers, header_name, lstrlenW(header_name));
372 heap_free(header_name);
373 if(!header)
374 return NS_ERROR_NOT_AVAILABLE;
376 data = heap_strdupWtoA(header->data);
377 if(!data)
378 return NS_ERROR_UNEXPECTED;
380 TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
381 nsACString_SetData(_retval, data);
382 heap_free(data);
383 return NS_OK;
386 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
387 const WCHAR *value, int value_len)
389 http_header_t *header;
391 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
393 header = find_http_header(headers, name, name_len);
394 if(header) {
395 WCHAR *new_data;
397 new_data = heap_strndupW(value, value_len);
398 if(!new_data)
399 return E_OUTOFMEMORY;
401 heap_free(header->data);
402 header->data = new_data;
403 }else {
404 header = heap_alloc(sizeof(http_header_t));
405 if(!header)
406 return E_OUTOFMEMORY;
408 header->header = heap_strndupW(name, name_len);
409 header->data = heap_strndupW(value, value_len);
410 if(!header->header || !header->data) {
411 heap_free(header->header);
412 heap_free(header->data);
413 heap_free(header);
414 return E_OUTOFMEMORY;
417 list_add_tail(headers, &header->entry);
420 return S_OK;
423 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
424 const nsACString *value_str)
426 const char *namea, *valuea;
427 WCHAR *name, *value;
428 HRESULT hres;
430 nsACString_GetData(name_str, &namea);
431 name = heap_strdupAtoW(namea);
432 if(!name)
433 return NS_ERROR_UNEXPECTED;
435 nsACString_GetData(value_str, &valuea);
436 value = heap_strdupAtoW(valuea);
437 if(!value) {
438 heap_free(name);
439 return NS_ERROR_UNEXPECTED;
442 hres = set_http_header(headers, name, lstrlenW(name), value, lstrlenW(value));
444 heap_free(name);
445 heap_free(value);
446 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
449 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
451 nsACString header_str, value_str;
452 char *header, *value;
453 http_header_t *iter;
454 nsresult nsres;
456 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
457 header = heap_strdupWtoA(iter->header);
458 if(!header)
459 return NS_ERROR_OUT_OF_MEMORY;
461 value = heap_strdupWtoA(iter->data);
462 if(!value) {
463 heap_free(header);
464 return NS_ERROR_OUT_OF_MEMORY;
467 nsACString_InitDepend(&header_str, header);
468 nsACString_InitDepend(&value_str, value);
469 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
470 nsACString_Finish(&header_str);
471 nsACString_Finish(&value_str);
472 heap_free(header);
473 heap_free(value);
474 if(NS_FAILED(nsres))
475 break;
478 return NS_OK;
481 static void free_http_headers(struct list *list)
483 http_header_t *iter, *iter_next;
485 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
486 list_remove(&iter->entry);
487 heap_free(iter->header);
488 heap_free(iter->data);
489 heap_free(iter);
493 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
495 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
498 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
500 nsChannel *This = impl_from_nsIHttpChannel(iface);
502 if(IsEqualGUID(&IID_nsISupports, riid)) {
503 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
504 *result = &This->nsIHttpChannel_iface;
505 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
506 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
507 *result = &This->nsIHttpChannel_iface;
508 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
509 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
510 *result = &This->nsIHttpChannel_iface;
511 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
512 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
513 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
514 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
515 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
516 *result = &This->nsIUploadChannel_iface;
517 }else if(IsEqualGUID(&IID_nsIFormPOSTActionChannel, riid)) {
518 TRACE("(%p)->(IID_nsIFormPOSTActionChannel %p)\n", This, result);
519 *result = &This->nsIUploadChannel_iface;
520 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
521 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
522 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
523 }else if(IsEqualGUID(&IID_nsICacheInfoChannel, riid)) {
524 TRACE("(%p)->(IID_nsICacheInfoChannel %p)\n", This, result);
525 *result = is_http_channel(This) ? &This->nsICacheInfoChannel_iface : NULL;
526 }else {
527 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
528 *result = NULL;
531 if(*result) {
532 nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
533 return NS_OK;
536 return NS_NOINTERFACE;
539 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
541 nsChannel *This = impl_from_nsIHttpChannel(iface);
542 nsrefcnt ref = InterlockedIncrement(&This->ref);
544 TRACE("(%p) ref=%ld\n", This, ref);
546 return ref;
549 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
551 nsChannel *This = impl_from_nsIHttpChannel(iface);
552 LONG ref = InterlockedDecrement(&This->ref);
554 if(!ref) {
555 nsIFileURL_Release(&This->uri->nsIFileURL_iface);
556 if(This->owner)
557 nsISupports_Release(This->owner);
558 if(This->post_data_stream)
559 nsIInputStream_Release(This->post_data_stream);
560 if(This->load_group)
561 nsILoadGroup_Release(This->load_group);
562 if(This->notif_callback)
563 nsIInterfaceRequestor_Release(This->notif_callback);
564 if(This->original_uri)
565 nsIURI_Release(This->original_uri);
566 if(This->referrer)
567 nsIURI_Release(This->referrer);
569 free_http_headers(&This->response_headers);
570 free_http_headers(&This->request_headers);
572 heap_free(This->content_type);
573 heap_free(This->charset);
574 heap_free(This);
577 return ref;
580 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
582 nsChannel *This = impl_from_nsIHttpChannel(iface);
584 TRACE("(%p)->(%p)\n", This, aName);
586 return nsIFileURL_GetSpec(&This->uri->nsIFileURL_iface, aName);
589 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, cpp_bool *_retval)
591 nsChannel *This = impl_from_nsIHttpChannel(iface);
593 FIXME("(%p)->(%p)\n", This, _retval);
595 return NS_ERROR_NOT_IMPLEMENTED;
598 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
600 nsChannel *This = impl_from_nsIHttpChannel(iface);
602 WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
604 return *aStatus = NS_OK;
607 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
609 nsChannel *This = impl_from_nsIHttpChannel(iface);
611 TRACE("(%p)->(%08lx)\n", This, aStatus);
613 if(This->binding && This->binding->bsc.binding)
614 IBinding_Abort(This->binding->bsc.binding);
615 else
616 WARN("No binding to cancel\n");
617 return NS_OK;
620 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
622 nsChannel *This = impl_from_nsIHttpChannel(iface);
624 FIXME("(%p)\n", This);
626 return NS_ERROR_NOT_IMPLEMENTED;
629 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
631 nsChannel *This = impl_from_nsIHttpChannel(iface);
633 FIXME("(%p)\n", This);
635 return NS_ERROR_NOT_IMPLEMENTED;
638 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
640 nsChannel *This = impl_from_nsIHttpChannel(iface);
642 TRACE("(%p)->(%p)\n", This, aLoadGroup);
644 if(This->load_group)
645 nsILoadGroup_AddRef(This->load_group);
647 *aLoadGroup = This->load_group;
648 return NS_OK;
651 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
653 nsChannel *This = impl_from_nsIHttpChannel(iface);
655 TRACE("(%p)->(%p)\n", This, aLoadGroup);
657 if(This->load_group)
658 nsILoadGroup_Release(This->load_group);
659 if(aLoadGroup)
660 nsILoadGroup_AddRef(aLoadGroup);
661 This->load_group = aLoadGroup;
663 return NS_OK;
666 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
668 nsChannel *This = impl_from_nsIHttpChannel(iface);
670 TRACE("(%p)->(%p)\n", This, aLoadFlags);
672 *aLoadFlags = This->load_flags;
673 return NS_OK;
676 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
678 nsChannel *This = impl_from_nsIHttpChannel(iface);
680 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
682 This->load_flags = aLoadFlags;
683 return NS_OK;
686 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
688 nsChannel *This = impl_from_nsIHttpChannel(iface);
690 TRACE("(%p)->(%p)\n", This, aOriginalURI);
692 if(This->original_uri)
693 nsIURI_AddRef(This->original_uri);
695 *aOriginalURI = This->original_uri;
696 return NS_OK;
699 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
701 nsChannel *This = impl_from_nsIHttpChannel(iface);
703 TRACE("(%p)->(%p)\n", This, aOriginalURI);
705 if(This->original_uri)
706 nsIURI_Release(This->original_uri);
708 nsIURI_AddRef(aOriginalURI);
709 This->original_uri = aOriginalURI;
710 return NS_OK;
713 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
715 nsChannel *This = impl_from_nsIHttpChannel(iface);
717 TRACE("(%p)->(%p)\n", This, aURI);
719 nsIFileURL_AddRef(&This->uri->nsIFileURL_iface);
720 *aURI = (nsIURI*)&This->uri->nsIFileURL_iface;
722 return NS_OK;
725 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
727 nsChannel *This = impl_from_nsIHttpChannel(iface);
729 TRACE("(%p)->(%p)\n", This, aOwner);
731 if(This->owner)
732 nsISupports_AddRef(This->owner);
733 *aOwner = This->owner;
735 return NS_OK;
738 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
740 nsChannel *This = impl_from_nsIHttpChannel(iface);
742 TRACE("(%p)->(%p)\n", This, aOwner);
744 if(aOwner)
745 nsISupports_AddRef(aOwner);
746 if(This->owner)
747 nsISupports_Release(This->owner);
748 This->owner = aOwner;
750 return NS_OK;
753 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
754 nsIInterfaceRequestor **aNotificationCallbacks)
756 nsChannel *This = impl_from_nsIHttpChannel(iface);
758 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
760 if(This->notif_callback)
761 nsIInterfaceRequestor_AddRef(This->notif_callback);
762 *aNotificationCallbacks = This->notif_callback;
764 return NS_OK;
767 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
768 nsIInterfaceRequestor *aNotificationCallbacks)
770 nsChannel *This = impl_from_nsIHttpChannel(iface);
772 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
774 if(This->notif_callback)
775 nsIInterfaceRequestor_Release(This->notif_callback);
776 if(aNotificationCallbacks)
777 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
779 This->notif_callback = aNotificationCallbacks;
781 return NS_OK;
784 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
786 nsChannel *This = impl_from_nsIHttpChannel(iface);
788 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
790 return NS_ERROR_NOT_IMPLEMENTED;
793 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
795 nsChannel *This = impl_from_nsIHttpChannel(iface);
797 TRACE("(%p)->(%p)\n", This, aContentType);
799 if(This->content_type) {
800 nsACString_SetData(aContentType, This->content_type);
801 return S_OK;
804 if(This->load_flags & LOAD_DOCUMENT_URI) {
805 WARN("Document channel with no MIME set. Assuming text/html\n");
806 nsACString_SetData(aContentType, "text/html");
807 return S_OK;
810 WARN("unknown type\n");
811 return NS_ERROR_FAILURE;
814 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
815 const nsACString *aContentType)
817 nsChannel *This = impl_from_nsIHttpChannel(iface);
818 const char *content_type;
820 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
822 nsACString_GetData(aContentType, &content_type);
823 heap_free(This->content_type);
824 This->content_type = heap_strdupA(content_type);
826 return NS_OK;
829 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
830 nsACString *aContentCharset)
832 nsChannel *This = impl_from_nsIHttpChannel(iface);
834 TRACE("(%p)->(%p)\n", This, aContentCharset);
836 if(This->charset) {
837 nsACString_SetData(aContentCharset, This->charset);
838 return NS_OK;
841 nsACString_SetData(aContentCharset, "");
842 return NS_OK;
845 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
846 const nsACString *aContentCharset)
848 nsChannel *This = impl_from_nsIHttpChannel(iface);
849 const char *data;
850 char *charset;
852 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
854 nsACString_GetData(aContentCharset, &data);
855 charset = heap_strdupA(data);
856 if(!charset)
857 return NS_ERROR_OUT_OF_MEMORY;
859 heap_free(This->charset);
860 This->charset = charset;
861 return NS_OK;
864 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, INT64 *aContentLength)
866 nsChannel *This = impl_from_nsIHttpChannel(iface);
868 FIXME("(%p)->(%p)\n", This, aContentLength);
870 return NS_ERROR_NOT_IMPLEMENTED;
873 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, INT64 aContentLength)
875 nsChannel *This = impl_from_nsIHttpChannel(iface);
877 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aContentLength));
879 return NS_ERROR_NOT_IMPLEMENTED;
882 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
884 nsChannel *This = impl_from_nsIHttpChannel(iface);
886 FIXME("(%p)->(%p)\n", This, _retval);
888 return NS_ERROR_NOT_IMPLEMENTED;
891 static nsresult NSAPI nsChannel_Open2(nsIHttpChannel *iface, nsIInputStream **_retval)
893 nsChannel *This = impl_from_nsIHttpChannel(iface);
895 FIXME("(%p)->(%p)\n", This, _retval);
897 return NS_ERROR_NOT_IMPLEMENTED;
900 static HTMLOuterWindow *get_channel_window(nsChannel *This)
902 nsIWebProgress *web_progress = NULL;
903 mozIDOMWindowProxy *mozwindow;
904 HTMLOuterWindow *window;
905 nsresult nsres;
907 if(This->load_group) {
908 nsIRequestObserver *req_observer;
910 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
911 if(NS_FAILED(nsres)) {
912 ERR("GetGroupObserver failed: %08lx\n", nsres);
913 return NULL;
916 if(req_observer) {
917 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
918 nsIRequestObserver_Release(req_observer);
919 if(NS_FAILED(nsres)) {
920 ERR("Could not get nsIWebProgress iface: %08lx\n", nsres);
921 return NULL;
926 if(!web_progress && This->notif_callback) {
927 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
928 if(NS_FAILED(nsres)) {
929 ERR("GetInterface(IID_nsIWebProgress failed: %08lx\n", nsres);
930 return NULL;
934 if(!web_progress) {
935 ERR("Could not find nsIWebProgress\n");
936 return NULL;
939 nsres = nsIWebProgress_GetDOMWindow(web_progress, &mozwindow);
940 nsIWebProgress_Release(web_progress);
941 if(NS_FAILED(nsres) || !mozwindow) {
942 ERR("GetDOMWindow failed: %08lx\n", nsres);
943 return NULL;
946 window = mozwindow_to_window(mozwindow);
947 mozIDOMWindowProxy_Release(mozwindow);
949 if(window)
950 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
951 else
952 FIXME("NULL window for %p\n", mozwindow);
953 return window;
956 typedef struct {
957 task_t header;
958 HTMLInnerWindow *window;
959 nsChannelBSC *bscallback;
960 } start_binding_task_t;
962 static void start_binding_proc(task_t *_task)
964 start_binding_task_t *task = (start_binding_task_t*)_task;
966 start_binding(task->window, (BSCallback*)task->bscallback, NULL);
969 static void start_binding_task_destr(task_t *_task)
971 start_binding_task_t *task = (start_binding_task_t*)_task;
973 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
974 heap_free(task);
977 static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
978 nsISupports *context)
980 nsChannelBSC *bscallback;
981 IMoniker *mon = NULL;
982 HRESULT hres;
984 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
985 if(FAILED(hres)) {
986 WARN("CreateURLMoniker failed: %08lx\n", hres);
987 return NS_ERROR_UNEXPECTED;
990 if(is_doc_channel)
991 set_current_mon(window, mon, BINDING_NAVIGATED);
993 hres = create_channelbsc(mon, NULL, NULL, 0, is_doc_channel, &bscallback);
994 IMoniker_Release(mon);
995 if(FAILED(hres))
996 return NS_ERROR_UNEXPECTED;
998 channelbsc_set_channel(bscallback, This, listener, context);
1000 if(is_doc_channel) {
1001 hres = create_pending_window(window, bscallback);
1002 if(SUCCEEDED(hres))
1003 async_start_doc_binding(window, window->pending_window);
1004 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1005 if(FAILED(hres))
1006 return NS_ERROR_UNEXPECTED;
1007 }else {
1008 start_binding_task_t *task;
1010 task = heap_alloc(sizeof(start_binding_task_t));
1011 if(!task) {
1012 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1013 return NS_ERROR_OUT_OF_MEMORY;
1016 task->window = window->base.inner_window;
1017 task->bscallback = bscallback;
1018 hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic);
1019 if(FAILED(hres))
1020 return NS_ERROR_OUT_OF_MEMORY;
1023 return NS_OK;
1026 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
1027 nsISupports *aContext)
1029 nsChannel *This = impl_from_nsIHttpChannel(iface);
1030 HTMLOuterWindow *window = NULL;
1031 BOOL is_document_channel;
1032 BOOL cancel = FALSE;
1033 nsresult nsres = NS_OK;
1035 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1037 if(!ensure_uri(This->uri))
1038 return NS_ERROR_FAILURE;
1040 if(TRACE_ON(mshtml)) {
1041 HRESULT hres;
1042 BSTR uri_str;
1044 hres = IUri_GetDisplayUri(This->uri->uri, &uri_str);
1045 if(SUCCEEDED(hres)) {
1046 TRACE("opening %s\n", debugstr_w(uri_str));
1047 SysFreeString(uri_str);
1048 }else {
1049 WARN("GetDisplayUri failed: %08lx\n", hres);
1053 window = get_channel_window(This);
1054 if(!window) {
1055 ERR("window = NULL\n");
1056 return NS_ERROR_UNEXPECTED;
1059 is_document_channel = !!(This->load_flags & LOAD_DOCUMENT_URI);
1061 if(is_document_channel) {
1062 if(This->uri->channel_bsc) {
1063 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1064 cancel = TRUE;
1067 if(is_main_content_window(window)) {
1068 if(!This->uri->channel_bsc) {
1069 /* top window navigation initiated by Gecko */
1070 nsres = before_async_open(This, window->browser, &cancel);
1071 if(NS_SUCCEEDED(nsres) && cancel) {
1072 TRACE("canceled\n");
1073 nsres = NS_BINDING_ABORTED;
1075 }else if(window->browser->doc->mime) {
1076 heap_free(This->content_type);
1077 This->content_type = heap_strdupWtoA(window->browser->doc->mime);
1082 if(!cancel)
1083 nsres = async_open(This, window, is_document_channel, aListener, aContext);
1085 if(NS_SUCCEEDED(nsres) && This->load_group) {
1086 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1087 aContext);
1088 if(NS_FAILED(nsres))
1089 ERR("AddRequest failed: %08lx\n", nsres);
1092 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
1093 return nsres;
1096 static nsresult NSAPI nsChannel_AsyncOpen2(nsIHttpChannel *iface, nsIStreamListener *aListener)
1098 nsChannel *This = impl_from_nsIHttpChannel(iface);
1099 FIXME("(%p)->(%p)\n", This, aListener);
1100 return nsIHttpChannel_AsyncOpen(&This->nsIHttpChannel_iface, aListener, NULL);
1103 static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition)
1105 nsChannel *This = impl_from_nsIHttpChannel(iface);
1106 TRACE("(%p)->(%p) unimplemented\n", This, aContentDisposition);
1107 return NS_ERROR_NOT_IMPLEMENTED;
1110 static nsresult NSAPI nsChannel_SetContentDisposition(nsIHttpChannel *iface, UINT32 aContentDisposition)
1112 nsChannel *This = impl_from_nsIHttpChannel(iface);
1113 FIXME("(%p)->(%u)\n", This, aContentDisposition);
1114 return NS_ERROR_NOT_IMPLEMENTED;
1117 static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
1119 nsChannel *This = impl_from_nsIHttpChannel(iface);
1120 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1121 return NS_ERROR_NOT_IMPLEMENTED;
1124 static nsresult NSAPI nsChannel_SetContentDispositionFilename(nsIHttpChannel *iface, const nsAString *aContentDispositionFilename)
1126 nsChannel *This = impl_from_nsIHttpChannel(iface);
1127 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1128 return NS_ERROR_NOT_IMPLEMENTED;
1131 static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
1133 nsChannel *This = impl_from_nsIHttpChannel(iface);
1134 TRACE("(%p)->(%p) unimplemented\n", This, aContentDispositionHeader);
1135 return NS_ERROR_NOT_IMPLEMENTED;
1138 static nsresult NSAPI nsChannel_GetLoadInfo(nsIHttpChannel *iface, nsILoadInfo **aLoadInfo)
1140 nsChannel *This = impl_from_nsIHttpChannel(iface);
1142 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1144 if(This->load_info)
1145 nsISupports_AddRef(This->load_info);
1146 *aLoadInfo = This->load_info;
1147 return NS_OK;
1150 static nsresult NSAPI nsChannel_SetLoadInfo(nsIHttpChannel *iface, nsILoadInfo *aLoadInfo)
1152 nsChannel *This = impl_from_nsIHttpChannel(iface);
1154 TRACE("(%p)->(%p)\n", This, aLoadInfo);
1156 if(This->load_info)
1157 nsISupports_Release(This->load_info);
1158 This->load_info = aLoadInfo;
1159 if(This->load_info)
1160 nsISupports_AddRef(This->load_info);
1161 return NS_OK;
1164 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1166 nsChannel *This = impl_from_nsIHttpChannel(iface);
1168 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1170 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1171 return NS_OK;
1174 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1175 const nsACString *aRequestMethod)
1177 nsChannel *This = impl_from_nsIHttpChannel(iface);
1178 const char *method;
1179 unsigned i;
1181 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1183 nsACString_GetData(aRequestMethod, &method);
1184 for(i=0; i < ARRAY_SIZE(request_method_strings); i++) {
1185 if(!stricmp(method, request_method_strings[i])) {
1186 This->request_method = i;
1187 return NS_OK;
1191 ERR("Invalid method %s\n", debugstr_a(method));
1192 return NS_ERROR_UNEXPECTED;
1195 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1197 nsChannel *This = impl_from_nsIHttpChannel(iface);
1199 TRACE("(%p)->(%p)\n", This, aReferrer);
1201 if(This->referrer)
1202 nsIURI_AddRef(This->referrer);
1203 *aReferrer = This->referrer;
1204 return NS_OK;
1207 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1209 nsChannel *This = impl_from_nsIHttpChannel(iface);
1211 TRACE("(%p)->(%p)\n", This, aReferrer);
1213 return nsIHttpChannel_SetReferrerWithPolicy(&This->nsIHttpChannel_iface, aReferrer, 0);
1216 static nsresult NSAPI nsChannel_GetReferrerPolicy(nsIHttpChannel *iface, UINT32 *aReferrerPolicy)
1218 nsChannel *This = impl_from_nsIHttpChannel(iface);
1219 TRACE("(%p)->(%p) unimplemented\n", This, aReferrerPolicy);
1220 return NS_ERROR_NOT_IMPLEMENTED;
1223 static nsresult NSAPI nsChannel_SetReferrerWithPolicy(nsIHttpChannel *iface, nsIURI *aReferrer, UINT32 aReferrerPolicy)
1225 nsChannel *This = impl_from_nsIHttpChannel(iface);
1226 DWORD channel_scheme, referrer_scheme;
1227 nsWineURI *referrer;
1228 BSTR referrer_uri;
1229 nsresult nsres;
1230 HRESULT hres;
1232 static const WCHAR refererW[] = {'R','e','f','e','r','e','r'};
1234 TRACE("(%p)->(%p %d)\n", This, aReferrer, aReferrerPolicy);
1236 if(aReferrerPolicy)
1237 FIXME("refferer policy %d not implemented\n", aReferrerPolicy);
1239 if(This->referrer) {
1240 nsIURI_Release(This->referrer);
1241 This->referrer = NULL;
1243 if(!aReferrer)
1244 return NS_OK;
1246 nsres = nsIURI_QueryInterface(aReferrer, &IID_nsWineURI, (void**)&referrer);
1247 if(NS_FAILED(nsres))
1248 return NS_OK;
1250 if(!ensure_uri(referrer)) {
1251 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1252 return NS_ERROR_UNEXPECTED;
1255 if(!ensure_uri(This->uri) || FAILED(IUri_GetScheme(This->uri->uri, &channel_scheme)))
1256 channel_scheme = INTERNET_SCHEME_UNKNOWN;
1258 if(FAILED(IUri_GetScheme(referrer->uri, &referrer_scheme)))
1259 referrer_scheme = INTERNET_SCHEME_UNKNOWN;
1261 if(referrer_scheme == INTERNET_SCHEME_HTTPS && channel_scheme != INTERNET_SCHEME_HTTPS) {
1262 TRACE("Ignoring https referrer on non-https channel\n");
1263 nsIFileURL_Release(&referrer->nsIFileURL_iface);
1264 return NS_OK;
1267 hres = IUri_GetDisplayUri(referrer->uri, &referrer_uri);
1268 if(SUCCEEDED(hres)) {
1269 set_http_header(&This->request_headers, refererW, ARRAY_SIZE(refererW), referrer_uri, SysStringLen(referrer_uri));
1270 SysFreeString(referrer_uri);
1273 This->referrer = (nsIURI*)&referrer->nsIFileURL_iface;
1274 return NS_OK;
1277 static nsresult NSAPI nsHttpChannel_GetProtocolVersion(nsIHttpChannel *iface, nsACString *aProtocolVersion)
1279 nsChannel *This = impl_from_nsIHttpChannel(iface);
1280 FIXME("(%p)->(%p)\n", This, aProtocolVersion);
1281 return NS_ERROR_NOT_IMPLEMENTED;
1284 static nsresult NSAPI nsHttpChannel_GetTransferSize(nsIHttpChannel *iface, UINT64 *aTransferSize)
1286 nsChannel *This = impl_from_nsIHttpChannel(iface);
1287 FIXME("(%p)->(%p)\n", This, aTransferSize);
1288 return NS_ERROR_NOT_IMPLEMENTED;
1291 static nsresult NSAPI nsHttpChannel_GetDecodedBodySize(nsIHttpChannel *iface, UINT64 *aDecodedBodySize)
1293 nsChannel *This = impl_from_nsIHttpChannel(iface);
1294 FIXME("(%p)->(%p)\n", This, aDecodedBodySize);
1295 return NS_ERROR_NOT_IMPLEMENTED;
1298 static nsresult NSAPI nsHttpChannel_GetEncodedBodySize(nsIHttpChannel *iface, UINT64 *aEncodedBodySize)
1300 nsChannel *This = impl_from_nsIHttpChannel(iface);
1301 FIXME("(%p)->(%p)\n", This, aEncodedBodySize);
1302 return NS_ERROR_NOT_IMPLEMENTED;
1305 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1306 const nsACString *aHeader, nsACString *_retval)
1308 nsChannel *This = impl_from_nsIHttpChannel(iface);
1310 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1312 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1315 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1316 const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
1318 nsChannel *This = impl_from_nsIHttpChannel(iface);
1320 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1322 if(aMerge)
1323 FIXME("aMerge not supported\n");
1325 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1328 static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader)
1330 nsChannel *This = impl_from_nsIHttpChannel(iface);
1331 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader));
1332 return NS_ERROR_NOT_IMPLEMENTED;
1335 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1336 nsIHttpHeaderVisitor *aVisitor)
1338 nsChannel *This = impl_from_nsIHttpChannel(iface);
1340 FIXME("(%p)->(%p)\n", This, aVisitor);
1342 return NS_ERROR_NOT_IMPLEMENTED;
1345 static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor)
1347 nsChannel *This = impl_from_nsIHttpChannel(iface);
1348 FIXME("(%p)->(%p)\n", This, aVisitor);
1349 return NS_ERROR_NOT_IMPLEMENTED;
1352 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
1354 nsChannel *This = impl_from_nsIHttpChannel(iface);
1356 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1358 return NS_ERROR_NOT_IMPLEMENTED;
1361 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
1363 nsChannel *This = impl_from_nsIHttpChannel(iface);
1365 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1367 return NS_ERROR_NOT_IMPLEMENTED;
1370 static nsresult NSAPI nsChannel_GetAllowTLS(nsIHttpChannel *iface, cpp_bool *aAllowTLS)
1372 nsChannel *This = impl_from_nsIHttpChannel(iface);
1373 FIXME("(%p)->(%p)\n", This, aAllowTLS);
1374 return NS_ERROR_NOT_IMPLEMENTED;
1377 static nsresult NSAPI nsChannel_SetAllowTLS(nsIHttpChannel *iface, cpp_bool aAllowTLS)
1379 nsChannel *This = impl_from_nsIHttpChannel(iface);
1380 FIXME("(%p)->(%x)\n", This, aAllowTLS);
1381 return NS_ERROR_NOT_IMPLEMENTED;
1384 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
1386 nsChannel *This = impl_from_nsIHttpChannel(iface);
1388 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1390 return NS_ERROR_NOT_IMPLEMENTED;
1393 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
1395 nsChannel *This = impl_from_nsIHttpChannel(iface);
1397 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1399 return NS_ERROR_NOT_IMPLEMENTED;
1402 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
1404 nsChannel *This = impl_from_nsIHttpChannel(iface);
1406 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1408 if(This->response_status) {
1409 *aResponseStatus = This->response_status;
1410 return NS_OK;
1413 WARN("No response status\n");
1414 return NS_ERROR_UNEXPECTED;
1417 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1418 nsACString *aResponseStatusText)
1420 nsChannel *This = impl_from_nsIHttpChannel(iface);
1422 TRACE("(%p)->(%p)\n", This, aResponseStatusText);
1424 nsACString_SetData(aResponseStatusText, This->response_status_text);
1425 return NS_OK;
1428 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1429 cpp_bool *aRequestSucceeded)
1431 nsChannel *This = impl_from_nsIHttpChannel(iface);
1433 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1435 if(!This->response_status)
1436 return NS_ERROR_NOT_AVAILABLE;
1438 *aRequestSucceeded = This->response_status/100 == 2;
1440 return NS_OK;
1443 static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel)
1445 nsChannel *This = impl_from_nsIHttpChannel(iface);
1446 FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel);
1447 return NS_ERROR_NOT_IMPLEMENTED;
1450 static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel)
1452 nsChannel *This = impl_from_nsIHttpChannel(iface);
1453 FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel);
1454 return NS_ERROR_NOT_IMPLEMENTED;
1457 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1458 const nsACString *header, nsACString *_retval)
1460 nsChannel *This = impl_from_nsIHttpChannel(iface);
1462 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1464 return get_channel_http_header(&This->response_headers, header, _retval);
1467 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1468 const nsACString *header, const nsACString *value, cpp_bool merge)
1470 nsChannel *This = impl_from_nsIHttpChannel(iface);
1472 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1474 return NS_ERROR_NOT_IMPLEMENTED;
1477 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1478 nsIHttpHeaderVisitor *aVisitor)
1480 nsChannel *This = impl_from_nsIHttpChannel(iface);
1482 TRACE("(%p)->(%p)\n", This, aVisitor);
1484 return visit_http_headers(&This->response_headers, aVisitor);
1487 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1489 nsChannel *This = impl_from_nsIHttpChannel(iface);
1490 http_header_t *header;
1492 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1494 TRACE("(%p)->(%p)\n", This, _retval);
1496 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1497 *_retval = header && !wcsicmp(header->data, L"no-store");
1498 return NS_OK;
1501 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1503 nsChannel *This = impl_from_nsIHttpChannel(iface);
1504 http_header_t *header;
1506 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1508 TRACE("(%p)->(%p)\n", This, _retval);
1510 header = find_http_header(&This->response_headers, cache_controlW, ARRAY_SIZE(cache_controlW));
1511 *_retval = header && !wcsicmp(header->data, L"no-cache");
1512 /* FIXME: Gecko also checks if max-age is in the past */
1513 return NS_OK;
1516 static nsresult NSAPI nsChannel_IsPrivateResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1518 nsChannel *This = impl_from_nsIHttpChannel(iface);
1520 FIXME("(%p)->(%p)\n", This, _retval);
1522 return NS_ERROR_NOT_IMPLEMENTED;
1525 static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aTargetURI)
1527 nsChannel *This = impl_from_nsIHttpChannel(iface);
1529 FIXME("(%p)->(%p)\n", This, aTargetURI);
1531 return NS_ERROR_NOT_IMPLEMENTED;
1534 static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID)
1536 nsChannel *This = impl_from_nsIHttpChannel(iface);
1538 FIXME("(%p)->(%p)\n", This, aSchedulingContextID);
1540 return NS_ERROR_NOT_IMPLEMENTED;
1543 static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID)
1545 nsChannel *This = impl_from_nsIHttpChannel(iface);
1547 FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID));
1549 return NS_ERROR_NOT_IMPLEMENTED;
1552 static const nsIHttpChannelVtbl nsChannelVtbl = {
1553 nsChannel_QueryInterface,
1554 nsChannel_AddRef,
1555 nsChannel_Release,
1556 nsChannel_GetName,
1557 nsChannel_IsPending,
1558 nsChannel_GetStatus,
1559 nsChannel_Cancel,
1560 nsChannel_Suspend,
1561 nsChannel_Resume,
1562 nsChannel_GetLoadGroup,
1563 nsChannel_SetLoadGroup,
1564 nsChannel_GetLoadFlags,
1565 nsChannel_SetLoadFlags,
1566 nsChannel_GetOriginalURI,
1567 nsChannel_SetOriginalURI,
1568 nsChannel_GetURI,
1569 nsChannel_GetOwner,
1570 nsChannel_SetOwner,
1571 nsChannel_GetNotificationCallbacks,
1572 nsChannel_SetNotificationCallbacks,
1573 nsChannel_GetSecurityInfo,
1574 nsChannel_GetContentType,
1575 nsChannel_SetContentType,
1576 nsChannel_GetContentCharset,
1577 nsChannel_SetContentCharset,
1578 nsChannel_GetContentLength,
1579 nsChannel_SetContentLength,
1580 nsChannel_Open,
1581 nsChannel_Open2,
1582 nsChannel_AsyncOpen,
1583 nsChannel_AsyncOpen2,
1584 nsChannel_GetContentDisposition,
1585 nsChannel_SetContentDisposition,
1586 nsChannel_GetContentDispositionFilename,
1587 nsChannel_SetContentDispositionFilename,
1588 nsChannel_GetContentDispositionHeader,
1589 nsChannel_GetLoadInfo,
1590 nsChannel_SetLoadInfo,
1591 nsChannel_GetRequestMethod,
1592 nsChannel_SetRequestMethod,
1593 nsChannel_GetReferrer,
1594 nsChannel_SetReferrer,
1595 nsChannel_GetReferrerPolicy,
1596 nsChannel_SetReferrerWithPolicy,
1597 nsHttpChannel_GetProtocolVersion,
1598 nsHttpChannel_GetTransferSize,
1599 nsHttpChannel_GetDecodedBodySize,
1600 nsHttpChannel_GetEncodedBodySize,
1601 nsChannel_GetRequestHeader,
1602 nsChannel_SetRequestHeader,
1603 nsChannel_SetEmptyRequestHeader,
1604 nsChannel_VisitRequestHeaders,
1605 nsChannel_VisitNonDefaultRequestHeaders,
1606 nsChannel_GetAllowPipelining,
1607 nsChannel_SetAllowPipelining,
1608 nsChannel_GetAllowTLS,
1609 nsChannel_SetAllowTLS,
1610 nsChannel_GetRedirectionLimit,
1611 nsChannel_SetRedirectionLimit,
1612 nsChannel_GetResponseStatus,
1613 nsChannel_GetResponseStatusText,
1614 nsChannel_GetRequestSucceeded,
1615 nsChannel_GetIsMainDocumentChannel,
1616 nsChannel_SetIsMainDocumentChannel,
1617 nsChannel_GetResponseHeader,
1618 nsChannel_SetResponseHeader,
1619 nsChannel_VisitResponseHeaders,
1620 nsChannel_IsNoStoreResponse,
1621 nsChannel_IsNoCacheResponse,
1622 nsChannel_IsPrivateResponse,
1623 nsChannel_RedirectTo,
1624 nsHttpChannel_GetSchedulingContextID,
1625 nsHttpChannel_SetSchedulingContextID
1628 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1630 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1633 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1634 void **result)
1636 nsChannel *This = impl_from_nsIUploadChannel(iface);
1637 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1640 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1642 nsChannel *This = impl_from_nsIUploadChannel(iface);
1643 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1646 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1648 nsChannel *This = impl_from_nsIUploadChannel(iface);
1649 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1652 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1653 nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
1655 nsChannel *This = impl_from_nsIUploadChannel(iface);
1656 const char *content_type;
1658 static const WCHAR content_typeW[] =
1659 {'C','o','n','t','e','n','t','-','T','y','p','e'};
1661 TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));
1663 This->post_data_contains_headers = TRUE;
1665 if(aContentType) {
1666 nsACString_GetData(aContentType, &content_type);
1667 if(*content_type) {
1668 WCHAR *ct;
1670 ct = heap_strdupAtoW(content_type);
1671 if(!ct)
1672 return NS_ERROR_UNEXPECTED;
1674 set_http_header(&This->request_headers, content_typeW, ARRAY_SIZE(content_typeW), ct, lstrlenW(ct));
1675 heap_free(ct);
1676 This->post_data_contains_headers = FALSE;
1680 if(aContentLength != -1)
1681 FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));
1683 if(This->post_data_stream)
1684 nsIInputStream_Release(This->post_data_stream);
1685 This->post_data_stream = aStream;
1686 if(aStream)
1687 nsIInputStream_AddRef(aStream);
1689 This->request_method = METHOD_POST;
1690 return NS_OK;
1693 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1694 nsIInputStream **aUploadStream)
1696 nsChannel *This = impl_from_nsIUploadChannel(iface);
1698 TRACE("(%p)->(%p)\n", This, aUploadStream);
1700 if(This->post_data_stream)
1701 nsIInputStream_AddRef(This->post_data_stream);
1703 *aUploadStream = This->post_data_stream;
1704 return NS_OK;
1707 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1708 nsUploadChannel_QueryInterface,
1709 nsUploadChannel_AddRef,
1710 nsUploadChannel_Release,
1711 nsUploadChannel_SetUploadStream,
1712 nsUploadChannel_GetUploadStream
1715 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1717 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1720 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1721 void **result)
1723 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1724 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1727 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1729 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1730 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1733 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1735 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1736 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1739 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1741 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1743 FIXME("(%p)->()\n", This);
1745 return NS_ERROR_NOT_IMPLEMENTED;
1748 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1750 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1752 TRACE("(%p)->() unimplemented\n", This);
1754 return NS_ERROR_NOT_IMPLEMENTED;
1757 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1759 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1761 FIXME("(%p)->()\n", This);
1763 return NS_ERROR_NOT_IMPLEMENTED;
1766 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1768 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1770 FIXME("(%p)->()\n", This);
1772 return NS_ERROR_NOT_IMPLEMENTED;
1775 static nsresult NSAPI nsHttpChannelInternal_TakeAllSecurityMessages(nsIHttpChannelInternal *iface, void *aMessages)
1777 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1779 TRACE("(%p)->(%p) unimplemented\n", This, aMessages);
1781 return NS_ERROR_NOT_IMPLEMENTED;
1784 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1786 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1788 FIXME("(%p)->()\n", This);
1790 return NS_ERROR_NOT_IMPLEMENTED;
1793 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1795 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1797 FIXME("(%p)->()\n", This);
1799 return NS_ERROR_NOT_IMPLEMENTED;
1802 static nsresult NSAPI nsHttpChannelInternal_GetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 *aThirdPartyFlags)
1804 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1805 FIXME("(%p)->(%p)\n", This, aThirdPartyFlags);
1806 return NS_ERROR_NOT_IMPLEMENTED;
1809 static nsresult NSAPI nsHttpChannelInternal_SetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 aThirdPartyFlags)
1811 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1812 FIXME("(%p)->(%x)\n", This, aThirdPartyFlags);
1813 return NS_ERROR_NOT_IMPLEMENTED;
1816 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
1818 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1820 FIXME("(%p)->()\n", This);
1822 return NS_ERROR_NOT_IMPLEMENTED;
1825 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
1827 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1829 FIXME("(%p)->()\n", This);
1831 return NS_ERROR_NOT_IMPLEMENTED;
1834 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1836 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1838 FIXME("(%p)->(%p)\n", This, aCanceled);
1840 return NS_ERROR_NOT_IMPLEMENTED;
1843 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1845 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1847 FIXME("(%p)->(%p)\n", This, aCanceled);
1849 return NS_ERROR_NOT_IMPLEMENTED;
1852 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
1854 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1856 FIXME("(%p)->(%x)\n", This, aCanceled);
1858 return NS_ERROR_NOT_IMPLEMENTED;
1861 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1863 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1865 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1867 return NS_ERROR_NOT_IMPLEMENTED;
1870 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
1872 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1874 FIXME("(%p)->(%p)\n", This, aLocalPort);
1876 return NS_ERROR_NOT_IMPLEMENTED;
1879 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1881 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1883 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1885 return NS_ERROR_NOT_IMPLEMENTED;
1888 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
1890 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1892 FIXME("(%p)->(%p)\n", This, aRemotePort);
1894 return NS_ERROR_NOT_IMPLEMENTED;
1897 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1899 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1901 FIXME("(%p)->(%p)\n", This, cacheKeys);
1903 return NS_ERROR_NOT_IMPLEMENTED;
1906 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1907 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1909 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1910 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1911 return NS_ERROR_NOT_IMPLEMENTED;
1914 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
1916 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1917 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
1918 return NS_ERROR_NOT_IMPLEMENTED;
1921 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
1923 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1924 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
1925 return NS_ERROR_NOT_IMPLEMENTED;
1928 static nsresult NSAPI nsHttpChannelInternal_GetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1929 cpp_bool *aResponseTimeoutEnabled)
1931 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1932 FIXME("(%p)->(%p)\n", This, aResponseTimeoutEnabled);
1933 return NS_ERROR_NOT_IMPLEMENTED;
1936 static nsresult NSAPI nsHttpChannelInternal_SetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
1937 cpp_bool aResponseTimeoutEnabled)
1939 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1940 FIXME("(%p)->(%x)\n", This, aResponseTimeoutEnabled);
1941 return NS_ERROR_NOT_IMPLEMENTED;
1944 static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface,
1945 UINT32 *aInitialRwin)
1947 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1948 FIXME("(%p)->(%p)\n", This, aInitialRwin);
1949 return NS_ERROR_NOT_IMPLEMENTED;
1952 static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface,
1953 UINT32 aInitialRwin)
1955 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1956 FIXME("(%p)->(%x)\n", This, aInitialRwin);
1957 return NS_ERROR_NOT_IMPLEMENTED;
1960 static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI)
1962 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1963 FIXME("(%p)->(%p)\n", This, aApiRedirectToURI);
1964 return NS_ERROR_NOT_IMPLEMENTED;
1967 static nsresult NSAPI nsHttpChannelInternal_GetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool *aAllowAltSvc)
1969 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1970 FIXME("(%p)->(%p)\n", This, aAllowAltSvc);
1971 return NS_ERROR_NOT_IMPLEMENTED;
1974 static nsresult NSAPI nsHttpChannelInternal_SetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool aAllowAltSvc)
1976 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1977 FIXME("(%p)->(%x)\n", This, aAllowAltSvc);
1978 return NS_ERROR_NOT_IMPLEMENTED;
1981 static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime)
1983 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1984 FIXME("(%p)->(%p)\n", This, aLastModifiedTime);
1985 return NS_ERROR_NOT_IMPLEMENTED;
1988 static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID)
1990 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1991 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID));
1992 return NS_ERROR_NOT_IMPLEMENTED;
1995 static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized)
1997 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1998 FIXME("(%p, %p)\n", This, ResponseSynthesized);
1999 return NS_ERROR_NOT_IMPLEMENTED;
2002 static nsresult NSAPI nsHttpChannelInternal_GetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2003 cpp_bool *aCorsIncludeCredentials)
2005 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2006 FIXME("(%p)->(%p)\n", This, aCorsIncludeCredentials);
2007 return NS_ERROR_NOT_IMPLEMENTED;
2010 static nsresult NSAPI nsHttpChannelInternal_SetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
2011 cpp_bool aCorsIncludeCredentials)
2013 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2014 TRACE("(%p)->(%x)\n", This, aCorsIncludeCredentials);
2015 return NS_OK;
2018 static nsresult NSAPI nsHttpChannelInternal_GetCorsMode(nsIHttpChannelInternal *iface, UINT32 *aCorsMode)
2020 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2021 FIXME("(%p)->(%p)\n", This, aCorsMode);
2022 return NS_ERROR_NOT_IMPLEMENTED;
2025 static nsresult NSAPI nsHttpChannelInternal_SetCorsMode(nsIHttpChannelInternal *iface, UINT32 aCorsMode)
2027 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2028 TRACE("(%p)->(%d)\n", This, aCorsMode);
2029 return NS_OK;
2032 static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode)
2034 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2035 FIXME("(%p)->(%p)\n", This, aRedirectMode);
2036 return NS_ERROR_NOT_IMPLEMENTED;
2039 static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode)
2041 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2042 TRACE("(%p)->(%d) unimplemented\n", This, aRedirectMode);
2043 return NS_ERROR_NOT_IMPLEMENTED;
2046 static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI)
2048 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2049 FIXME("(%p)->(%p)\n", This, aTopWindowURI);
2050 return NS_ERROR_NOT_IMPLEMENTED;
2053 static nsresult NSAPI nsHttpChannelInternal_GetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2054 nsACString *aNetworkInterfaceId)
2056 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2057 FIXME("(%p)->(%p)\n", This, aNetworkInterfaceId);
2058 return NS_ERROR_NOT_IMPLEMENTED;
2061 static nsresult NSAPI nsHttpChannelInternal_SetNetworkInterfaceId(nsIHttpChannelInternal *iface,
2062 const nsACString *aNetworkInterfaceId)
2064 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2065 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aNetworkInterfaceId));
2066 return NS_ERROR_NOT_IMPLEMENTED;
2069 static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI)
2071 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2072 FIXME("(%p)->(%p)\n", This, aProxyURI);
2073 return NS_ERROR_NOT_IMPLEMENTED;
2076 static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface,
2077 const void /*nsTArray<nsCString>*/ *unsafeHeaders)
2079 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2080 FIXME("(%p)->(%p)\n", This, unsafeHeaders);
2081 return NS_ERROR_NOT_IMPLEMENTED;
2084 static nsresult NSAPI nsHttpChannelInternal_GetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool *aBlockAuthPrompt)
2086 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2087 FIXME("(%p)->(%p)\n", This, aBlockAuthPrompt);
2088 return NS_ERROR_NOT_IMPLEMENTED;
2091 static nsresult NSAPI nsHttpChannelInternal_SetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool aBlockAuthPrompt)
2093 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
2094 FIXME("(%p)->(%x)\n", This, aBlockAuthPrompt);
2095 return NS_ERROR_NOT_IMPLEMENTED;
2098 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
2099 nsHttpChannelInternal_QueryInterface,
2100 nsHttpChannelInternal_AddRef,
2101 nsHttpChannelInternal_Release,
2102 nsHttpChannelInternal_GetDocumentURI,
2103 nsHttpChannelInternal_SetDocumentURI,
2104 nsHttpChannelInternal_GetRequestVersion,
2105 nsHttpChannelInternal_GetResponseVersion,
2106 nsHttpChannelInternal_TakeAllSecurityMessages,
2107 nsHttpChannelInternal_SetCookie,
2108 nsHttpChannelInternal_SetupFallbackChannel,
2109 nsHttpChannelInternal_GetThirdPartyFlags,
2110 nsHttpChannelInternal_SetThirdPartyFlags,
2111 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
2112 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
2113 nsHttpChannelInternal_GetCanceled,
2114 nsHttpChannelInternal_GetChannelIsForDownload,
2115 nsHttpChannelInternal_SetChannelIsForDownload,
2116 nsHttpChannelInternal_GetLocalAddress,
2117 nsHttpChannelInternal_GetLocalPort,
2118 nsHttpChannelInternal_GetRemoteAddress,
2119 nsHttpChannelInternal_GetRemotePort,
2120 nsHttpChannelInternal_SetCacheKeysRedirectChain,
2121 nsHttpChannelInternal_HTTPUpgrade,
2122 nsHttpChannelInternal_GetAllowSpdy,
2123 nsHttpChannelInternal_SetAllowSpdy,
2124 nsHttpChannelInternal_GetResponseTimeoutEnabled,
2125 nsHttpChannelInternal_SetResponseTimeoutEnabled,
2126 nsHttpChannelInternal_GetInitialRwin,
2127 nsHttpChannelInternal_SetInitialRwin,
2128 nsHttpChannelInternal_GetApiRedirectToURI,
2129 nsHttpChannelInternal_GetAllowAltSvc,
2130 nsHttpChannelInternal_SetAllowAltSvc,
2131 nsHttpChannelInternal_GetLastModifiedTime,
2132 nsHttpChannelInternal_ForceIntercepted,
2133 nsHttpChannelInternal_GetResponseSynthesized,
2134 nsHttpChannelInternal_GetCorsIncludeCredentials,
2135 nsHttpChannelInternal_SetCorsIncludeCredentials,
2136 nsHttpChannelInternal_GetCorsMode,
2137 nsHttpChannelInternal_SetCorsMode,
2138 nsHttpChannelInternal_GetRedirectMode,
2139 nsHttpChannelInternal_SetRedirectMode,
2140 nsHttpChannelInternal_GetTopWindowURI,
2141 nsHttpChannelInternal_GetNetworkInterfaceId,
2142 nsHttpChannelInternal_SetNetworkInterfaceId,
2143 nsHttpChannelInternal_GetProxyURI,
2144 nsHttpChannelInternal_SetCorsPreflightParameters,
2145 nsHttpChannelInternal_GetBlockAuthPrompt,
2146 nsHttpChannelInternal_SetBlockAuthPrompt
2149 static inline nsChannel *impl_from_nsICacheInfoChannel(nsICacheInfoChannel *iface)
2151 return CONTAINING_RECORD(iface, nsChannel, nsICacheInfoChannel_iface);
2154 static nsresult NSAPI nsCacheInfoChannel_QueryInterface(nsICacheInfoChannel *iface, nsIIDRef riid,
2155 void **result)
2157 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2158 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
2161 static nsrefcnt NSAPI nsCacheInfoChannel_AddRef(nsICacheInfoChannel *iface)
2163 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2164 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
2167 static nsrefcnt NSAPI nsCacheInfoChannel_Release(nsICacheInfoChannel *iface)
2169 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2170 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
2173 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenExpirationTime(nsICacheInfoChannel *iface, UINT32 *p)
2175 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2176 FIXME("(%p)->(%p)\n", This, p);
2177 return E_NOTIMPL;
2180 static nsresult NSAPI nsCacheInfoChannel_GetCacheTokenCachedCharset(nsICacheInfoChannel *iface, nsACString *p)
2182 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2183 FIXME("(%p)->(%p)\n", This, p);
2184 return E_NOTIMPL;
2187 static nsresult NSAPI nsCacheInfoChannel_SetCacheTokenCachedCharset(nsICacheInfoChannel *iface, const nsACString *p)
2189 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2190 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(p));
2191 return E_NOTIMPL;
2194 static nsresult NSAPI nsCacheInfoChannel_IsFromCache(nsICacheInfoChannel *iface, cpp_bool *p)
2196 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2197 FIXME("(%p)->(%p)\n", This, p);
2198 *p = FALSE;
2199 return NS_OK;
2202 static nsresult NSAPI nsCacheInfoChannel_GetCacheKey(nsICacheInfoChannel *iface, nsISupports **p)
2204 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2205 FIXME("(%p)->(%p)\n", This, p);
2206 return E_NOTIMPL;
2209 static nsresult NSAPI nsCacheInfoChannel_SetCacheKey(nsICacheInfoChannel *iface, nsISupports *key)
2211 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2212 FIXME("(%p)->(%p)\n", This, key);
2213 return E_NOTIMPL;
2216 static nsresult NSAPI nsCacheInfoChannel_GetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool *p)
2218 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2219 FIXME("(%p)->(%p)\n", This, p);
2220 return E_NOTIMPL;
2223 static nsresult NSAPI nsCacheInfoChannel_SetAllowStaleCacheContent(nsICacheInfoChannel *iface, cpp_bool allow)
2225 nsChannel *This = impl_from_nsICacheInfoChannel(iface);
2226 FIXME("(%p)->(%x)\n", This, allow);
2227 return E_NOTIMPL;
2230 static const nsICacheInfoChannelVtbl nsCacheInfoChannelVtbl = {
2231 nsCacheInfoChannel_QueryInterface,
2232 nsCacheInfoChannel_AddRef,
2233 nsCacheInfoChannel_Release,
2234 nsCacheInfoChannel_GetCacheTokenExpirationTime,
2235 nsCacheInfoChannel_GetCacheTokenCachedCharset,
2236 nsCacheInfoChannel_SetCacheTokenCachedCharset,
2237 nsCacheInfoChannel_IsFromCache,
2238 nsCacheInfoChannel_GetCacheKey,
2239 nsCacheInfoChannel_SetCacheKey,
2240 nsCacheInfoChannel_GetAllowStaleCacheContent,
2241 nsCacheInfoChannel_SetAllowStaleCacheContent
2244 static void invalidate_uri(nsWineURI *This)
2246 if(This->uri) {
2247 IUri_Release(This->uri);
2248 This->uri = NULL;
2252 static BOOL ensure_uri_builder(nsWineURI *This)
2254 if(!This->is_mutable) {
2255 WARN("Not mutable URI\n");
2256 return FALSE;
2259 if(!This->uri_builder) {
2260 HRESULT hres;
2262 if(!ensure_uri(This))
2263 return FALSE;
2265 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
2266 if(FAILED(hres)) {
2267 WARN("CreateIUriBuilder failed: %08lx\n", hres);
2268 return FALSE;
2272 invalidate_uri(This);
2273 return TRUE;
2276 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
2278 char *vala;
2279 BSTR val;
2280 HRESULT hres;
2282 if(!ensure_uri(This))
2283 return NS_ERROR_UNEXPECTED;
2285 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
2286 if(FAILED(hres)) {
2287 WARN("GetPropertyBSTR failed: %08lx\n", hres);
2288 return NS_ERROR_UNEXPECTED;
2291 vala = heap_strdupWtoU(val);
2292 SysFreeString(val);
2293 if(!vala)
2294 return NS_ERROR_OUT_OF_MEMORY;
2296 TRACE("ret %s\n", debugstr_a(vala));
2297 nsACString_SetData(ret, vala);
2298 heap_free(vala);
2299 return NS_OK;
2302 static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
2304 return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
2307 static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
2309 nsWineURI *This = impl_from_nsIFileURL(iface);
2311 *result = NULL;
2313 if(IsEqualGUID(&IID_nsISupports, riid)) {
2314 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
2315 *result = &This->nsIFileURL_iface;
2316 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
2317 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
2318 *result = &This->nsIFileURL_iface;
2319 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
2320 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
2321 *result = &This->nsIFileURL_iface;
2322 }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
2323 TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
2324 *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
2325 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
2326 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
2327 *result = &This->nsIStandardURL_iface;
2328 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
2329 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
2330 *result = &This->nsIStandardURL_iface;
2331 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
2332 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
2333 *result = This;
2336 if(*result) {
2337 nsIFileURL_AddRef(&This->nsIFileURL_iface);
2338 return NS_OK;
2341 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
2342 return NS_NOINTERFACE;
2345 static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
2347 nsWineURI *This = impl_from_nsIFileURL(iface);
2348 LONG ref = InterlockedIncrement(&This->ref);
2350 TRACE("(%p) ref=%ld\n", This, ref);
2352 return ref;
2355 static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
2357 nsWineURI *This = impl_from_nsIFileURL(iface);
2358 LONG ref = InterlockedDecrement(&This->ref);
2360 TRACE("(%p) ref=%ld\n", This, ref);
2362 if(!ref) {
2363 if(This->uri)
2364 IUri_Release(This->uri);
2365 if(This->uri_builder)
2366 IUriBuilder_Release(This->uri_builder);
2367 heap_free(This);
2370 return ref;
2373 static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
2375 nsWineURI *This = impl_from_nsIFileURL(iface);
2377 TRACE("(%p)->(%p)\n", This, aSpec);
2379 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
2382 static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
2384 nsWineURI *This = impl_from_nsIFileURL(iface);
2385 const char *speca;
2386 WCHAR *spec;
2387 IUri *uri;
2388 HRESULT hres;
2390 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
2392 if(!This->is_mutable)
2393 return NS_ERROR_UNEXPECTED;
2395 nsACString_GetData(aSpec, &speca);
2396 spec = heap_strdupUtoW(speca);
2397 if(!spec)
2398 return NS_ERROR_OUT_OF_MEMORY;
2400 hres = create_uri(spec, 0, &uri);
2401 heap_free(spec);
2402 if(FAILED(hres)) {
2403 WARN("create_uri failed: %08lx\n", hres);
2404 return NS_ERROR_FAILURE;
2407 invalidate_uri(This);
2408 if(This->uri_builder) {
2409 IUriBuilder_Release(This->uri_builder);
2410 This->uri_builder = NULL;
2413 This->uri = uri;
2414 return NS_OK;
2417 static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
2419 nsWineURI *This = impl_from_nsIFileURL(iface);
2420 IUriBuilder *uri_builder;
2421 BSTR display_uri;
2422 IUri *uri;
2423 int len;
2424 nsresult nsres;
2425 HRESULT hres;
2427 TRACE("(%p)->(%p)\n", This, aPrePath);
2429 if(!ensure_uri(This))
2430 return NS_ERROR_UNEXPECTED;
2432 hres = CreateIUriBuilder(This->uri, 0, 0, &uri_builder);
2433 if(FAILED(hres))
2434 return NS_ERROR_FAILURE;
2436 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_PATH|Uri_HAS_QUERY|Uri_HAS_FRAGMENT);
2437 if(SUCCEEDED(hres))
2438 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &uri);
2439 IUriBuilder_Release(uri_builder);
2440 if(FAILED(hres))
2441 return NS_ERROR_FAILURE;
2443 hres = IUri_GetDisplayUri(uri, &display_uri);
2444 IUri_Release(uri);
2445 if(FAILED(hres))
2446 return NS_ERROR_FAILURE;
2448 /* Remove trailing slash that may be appended as default path. */
2449 len = SysStringLen(display_uri);
2450 if(len && display_uri[len-1] == '/')
2451 display_uri[len-1] = 0;
2453 nsres = return_wstr_nsacstr(aPrePath, display_uri, -1);
2454 SysFreeString(display_uri);
2455 return nsres;
2458 static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
2460 nsWineURI *This = impl_from_nsIFileURL(iface);
2461 DWORD scheme;
2462 HRESULT hres;
2464 TRACE("(%p)->(%p)\n", This, aScheme);
2466 if(!ensure_uri(This))
2467 return NS_ERROR_UNEXPECTED;
2469 hres = IUri_GetScheme(This->uri, &scheme);
2470 if(FAILED(hres)) {
2471 WARN("GetScheme failed: %08lx\n", hres);
2472 return NS_ERROR_UNEXPECTED;
2475 if(scheme == URL_SCHEME_ABOUT) {
2476 nsACString_SetData(aScheme, "wine");
2477 return NS_OK;
2480 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
2483 static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
2485 nsWineURI *This = impl_from_nsIFileURL(iface);
2486 const char *schemea;
2487 WCHAR *scheme;
2488 HRESULT hres;
2490 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
2492 if(!ensure_uri_builder(This))
2493 return NS_ERROR_UNEXPECTED;
2495 nsACString_GetData(aScheme, &schemea);
2496 scheme = heap_strdupUtoW(schemea);
2497 if(!scheme)
2498 return NS_ERROR_OUT_OF_MEMORY;
2500 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
2501 heap_free(scheme);
2502 if(FAILED(hres))
2503 return NS_ERROR_UNEXPECTED;
2505 return NS_OK;
2508 static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
2510 nsWineURI *This = impl_from_nsIFileURL(iface);
2511 BSTR user, pass;
2512 HRESULT hres;
2514 TRACE("(%p)->(%p)\n", This, aUserPass);
2516 if(!ensure_uri(This))
2517 return NS_ERROR_UNEXPECTED;
2519 hres = IUri_GetUserName(This->uri, &user);
2520 if(FAILED(hres))
2521 return NS_ERROR_FAILURE;
2523 hres = IUri_GetPassword(This->uri, &pass);
2524 if(FAILED(hres)) {
2525 SysFreeString(user);
2526 return NS_ERROR_FAILURE;
2529 if(*user || *pass) {
2530 FIXME("Construct user:pass string\n");
2531 }else {
2532 nsACString_SetData(aUserPass, "");
2535 SysFreeString(user);
2536 SysFreeString(pass);
2537 return NS_OK;
2540 static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
2542 nsWineURI *This = impl_from_nsIFileURL(iface);
2543 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
2544 const char *user_pass;
2545 HRESULT hres;
2547 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
2549 if(!ensure_uri_builder(This))
2550 return NS_ERROR_UNEXPECTED;
2552 nsACString_GetData(aUserPass, &user_pass);
2553 if(*user_pass) {
2554 WCHAR *ptr;
2556 buf = heap_strdupUtoW(user_pass);
2557 if(!buf)
2558 return NS_ERROR_OUT_OF_MEMORY;
2560 ptr = wcschr(buf, ':');
2561 if(!ptr) {
2562 user = buf;
2563 }else if(ptr != buf) {
2564 *ptr++ = 0;
2565 user = buf;
2566 if(*ptr)
2567 pass = ptr;
2568 }else {
2569 pass = buf+1;
2573 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2574 if(SUCCEEDED(hres))
2575 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2577 heap_free(buf);
2578 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2581 static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
2583 nsWineURI *This = impl_from_nsIFileURL(iface);
2585 TRACE("(%p)->(%p)\n", This, aUsername);
2587 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2590 static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
2592 nsWineURI *This = impl_from_nsIFileURL(iface);
2593 const char *usera;
2594 WCHAR *user;
2595 HRESULT hres;
2597 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2599 if(!ensure_uri_builder(This))
2600 return NS_ERROR_UNEXPECTED;
2602 nsACString_GetData(aUsername, &usera);
2603 user = heap_strdupUtoW(usera);
2604 if(!user)
2605 return NS_ERROR_OUT_OF_MEMORY;
2607 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2608 heap_free(user);
2609 if(FAILED(hres))
2610 return NS_ERROR_UNEXPECTED;
2612 return NS_OK;
2615 static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
2617 nsWineURI *This = impl_from_nsIFileURL(iface);
2619 TRACE("(%p)->(%p)\n", This, aPassword);
2621 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2624 static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
2626 nsWineURI *This = impl_from_nsIFileURL(iface);
2627 const char *passa;
2628 WCHAR *pass;
2629 HRESULT hres;
2631 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2633 if(!ensure_uri_builder(This))
2634 return NS_ERROR_UNEXPECTED;
2636 nsACString_GetData(aPassword, &passa);
2637 pass = heap_strdupUtoW(passa);
2638 if(!pass)
2639 return NS_ERROR_OUT_OF_MEMORY;
2641 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2642 heap_free(pass);
2643 if(FAILED(hres))
2644 return NS_ERROR_UNEXPECTED;
2646 return NS_OK;
2649 static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
2651 nsWineURI *This = impl_from_nsIFileURL(iface);
2652 const WCHAR *ptr;
2653 char *vala;
2654 BSTR val;
2655 HRESULT hres;
2657 TRACE("(%p)->(%p)\n", This, aHostPort);
2659 if(!ensure_uri(This))
2660 return NS_ERROR_UNEXPECTED;
2662 hres = IUri_GetAuthority(This->uri, &val);
2663 if(FAILED(hres)) {
2664 WARN("GetAuthority failed: %08lx\n", hres);
2665 return NS_ERROR_UNEXPECTED;
2668 ptr = wcschr(val, '@');
2669 if(!ptr)
2670 ptr = val;
2672 vala = heap_strdupWtoU(ptr);
2673 SysFreeString(val);
2674 if(!vala)
2675 return NS_ERROR_OUT_OF_MEMORY;
2677 TRACE("ret %s\n", debugstr_a(vala));
2678 nsACString_SetData(aHostPort, vala);
2679 heap_free(vala);
2680 return NS_OK;
2683 static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
2685 nsWineURI *This = impl_from_nsIFileURL(iface);
2687 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2689 /* Not implemented by Gecko */
2690 return NS_ERROR_NOT_IMPLEMENTED;
2693 static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
2695 nsWineURI *This = impl_from_nsIFileURL(iface);
2697 TRACE("(%p)->(%p)\n", This, aHost);
2699 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2702 static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
2704 nsWineURI *This = impl_from_nsIFileURL(iface);
2705 const char *hosta;
2706 WCHAR *host;
2707 HRESULT hres;
2709 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2711 if(!ensure_uri_builder(This))
2712 return NS_ERROR_UNEXPECTED;
2714 nsACString_GetData(aHost, &hosta);
2715 host = heap_strdupUtoW(hosta);
2716 if(!host)
2717 return NS_ERROR_OUT_OF_MEMORY;
2719 hres = IUriBuilder_SetHost(This->uri_builder, host);
2720 heap_free(host);
2721 if(FAILED(hres))
2722 return NS_ERROR_UNEXPECTED;
2724 return NS_OK;
2727 static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
2729 nsWineURI *This = impl_from_nsIFileURL(iface);
2730 DWORD port;
2731 HRESULT hres;
2733 TRACE("(%p)->(%p)\n", This, aPort);
2735 if(!ensure_uri(This))
2736 return NS_ERROR_UNEXPECTED;
2738 hres = IUri_GetPort(This->uri, &port);
2739 if(FAILED(hres)) {
2740 WARN("GetPort failed: %08lx\n", hres);
2741 return NS_ERROR_UNEXPECTED;
2744 *aPort = port ? port : -1;
2745 return NS_OK;
2748 static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
2750 nsWineURI *This = impl_from_nsIFileURL(iface);
2751 HRESULT hres;
2753 TRACE("(%p)->(%ld)\n", This, aPort);
2755 if(!ensure_uri_builder(This))
2756 return NS_ERROR_UNEXPECTED;
2758 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2759 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2762 static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
2764 nsWineURI *This = impl_from_nsIFileURL(iface);
2766 TRACE("(%p)->(%p)\n", This, aPath);
2768 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2771 static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
2773 nsWineURI *This = impl_from_nsIFileURL(iface);
2774 const char *patha;
2775 WCHAR *path;
2776 HRESULT hres;
2778 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2780 if(!ensure_uri_builder(This))
2781 return NS_ERROR_UNEXPECTED;
2783 nsACString_GetData(aPath, &patha);
2784 path = heap_strdupUtoW(patha);
2785 if(!path)
2786 return NS_ERROR_OUT_OF_MEMORY;
2788 hres = IUriBuilder_SetPath(This->uri_builder, path);
2789 heap_free(path);
2790 if(FAILED(hres))
2791 return NS_ERROR_UNEXPECTED;
2793 return NS_OK;
2796 static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2798 nsWineURI *This = impl_from_nsIFileURL(iface);
2799 nsWineURI *other_obj;
2800 nsresult nsres;
2801 HRESULT hres;
2803 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2805 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2806 if(NS_FAILED(nsres)) {
2807 TRACE("Could not get nsWineURI interface\n");
2808 *_retval = FALSE;
2809 return NS_OK;
2812 if(ensure_uri(This) && ensure_uri(other_obj)) {
2813 BOOL b;
2815 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2816 if(SUCCEEDED(hres)) {
2817 *_retval = b;
2818 nsres = NS_OK;
2819 }else {
2820 nsres = NS_ERROR_FAILURE;
2822 }else {
2823 nsres = NS_ERROR_UNEXPECTED;
2826 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2827 return nsres;
2830 static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
2832 nsWineURI *This = impl_from_nsIFileURL(iface);
2833 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2834 BSTR scheme_name;
2835 HRESULT hres;
2837 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2839 if(!ensure_uri(This))
2840 return NS_ERROR_UNEXPECTED;
2842 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2843 if(FAILED(hres))
2844 return NS_ERROR_UNEXPECTED;
2846 MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, ARRAY_SIZE(buf));
2847 *_retval = !wcscmp(scheme_name, buf);
2848 SysFreeString(scheme_name);
2849 return NS_OK;
2852 static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
2854 nsWineURI *This = impl_from_nsIFileURL(iface);
2855 nsWineURI *wine_uri;
2856 nsresult nsres;
2858 TRACE("(%p)->(%p)\n", This, _retval);
2860 if(!ensure_uri(This))
2861 return NS_ERROR_UNEXPECTED;
2863 nsres = create_nsuri(This->uri, &wine_uri);
2864 if(NS_FAILED(nsres)) {
2865 WARN("create_nsuri failed: %08lx\n", nsres);
2866 return nsres;
2869 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2870 return NS_OK;
2873 static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
2874 nsACString *_retval)
2876 nsWineURI *This = impl_from_nsIFileURL(iface);
2877 const char *patha;
2878 IUri *new_uri;
2879 WCHAR *path;
2880 char *reta;
2881 BSTR ret;
2882 HRESULT hres;
2884 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2886 if(!ensure_uri(This))
2887 return NS_ERROR_UNEXPECTED;
2889 nsACString_GetData(aRelativePath, &patha);
2890 path = heap_strdupUtoW(patha);
2891 if(!path)
2892 return NS_ERROR_OUT_OF_MEMORY;
2894 hres = combine_url(This->uri, path, &new_uri);
2895 heap_free(path);
2896 if(FAILED(hres))
2897 return NS_ERROR_FAILURE;
2899 hres = IUri_GetDisplayUri(new_uri, &ret);
2900 IUri_Release(new_uri);
2901 if(FAILED(hres))
2902 return NS_ERROR_FAILURE;
2904 reta = heap_strdupWtoU(ret);
2905 SysFreeString(ret);
2906 if(!reta)
2907 return NS_ERROR_OUT_OF_MEMORY;
2909 TRACE("returning %s\n", debugstr_a(reta));
2910 nsACString_SetData(_retval, reta);
2911 heap_free(reta);
2912 return NS_OK;
2915 static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
2917 nsWineURI *This = impl_from_nsIFileURL(iface);
2919 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2921 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
2924 static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort)
2926 nsWineURI *This = impl_from_nsIFileURL(iface);
2928 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort);
2930 return nsIFileURL_GetHostPort(&This->nsIFileURL_iface, aAsciiHostPort);
2933 static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
2935 nsWineURI *This = impl_from_nsIFileURL(iface);
2937 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2939 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
2942 static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
2944 nsWineURI *This = impl_from_nsIFileURL(iface);
2946 TRACE("(%p)->(%p)\n", This, aOriginCharset);
2948 nsACString_SetData(aOriginCharset, NULL); /* assume utf-8, we store URI as utf-16 anyway */
2949 return NS_OK;
2952 static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
2954 nsWineURI *This = impl_from_nsIFileURL(iface);
2955 char *refa = NULL;
2956 BSTR ref;
2957 HRESULT hres;
2959 TRACE("(%p)->(%p)\n", This, aRef);
2961 if(!ensure_uri(This))
2962 return NS_ERROR_UNEXPECTED;
2964 hres = IUri_GetFragment(This->uri, &ref);
2965 if(FAILED(hres))
2966 return NS_ERROR_UNEXPECTED;
2968 refa = heap_strdupWtoU(ref);
2969 SysFreeString(ref);
2970 if(ref && !refa)
2971 return NS_ERROR_OUT_OF_MEMORY;
2973 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
2974 heap_free(refa);
2975 return NS_OK;
2978 static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
2980 nsWineURI *This = impl_from_nsIFileURL(iface);
2981 const char *refa;
2982 WCHAR *ref;
2983 HRESULT hres;
2985 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
2987 if(!ensure_uri_builder(This))
2988 return NS_ERROR_UNEXPECTED;
2990 nsACString_GetData(aRef, &refa);
2991 ref = heap_strdupUtoW(refa);
2992 if(!ref)
2993 return NS_ERROR_OUT_OF_MEMORY;
2995 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
2996 heap_free(ref);
2997 if(FAILED(hres))
2998 return NS_ERROR_UNEXPECTED;
3000 return NS_OK;
3003 static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
3005 nsWineURI *This = impl_from_nsIFileURL(iface);
3006 nsWineURI *other_obj;
3007 nsresult nsres;
3009 TRACE("(%p)->(%p %p)\n", This, other, _retval);
3011 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
3012 if(NS_FAILED(nsres)) {
3013 TRACE("Could not get nsWineURI interface\n");
3014 *_retval = FALSE;
3015 return NS_OK;
3018 if(ensure_uri(This) && ensure_uri(other_obj)) {
3019 *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
3020 nsres = NS_OK;
3021 }else {
3022 nsres = NS_ERROR_UNEXPECTED;
3025 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
3026 return nsres;
3029 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
3031 nsWineURI *This = impl_from_nsIFileURL(iface);
3032 nsWineURI *wine_uri;
3033 IUri *uri;
3034 nsresult nsres;
3036 TRACE("(%p)->(%p)\n", This, _retval);
3038 if(!ensure_uri(This))
3039 return NS_ERROR_UNEXPECTED;
3041 uri = get_uri_nofrag(This->uri);
3042 if(!uri)
3043 return NS_ERROR_FAILURE;
3045 nsres = create_nsuri(uri, &wine_uri);
3046 IUri_Release(uri);
3047 if(NS_FAILED(nsres)) {
3048 WARN("create_nsuri failed: %08lx\n", nsres);
3049 return nsres;
3052 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3053 return NS_OK;
3056 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
3058 nsWineURI *This = impl_from_nsIFileURL(iface);
3060 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
3062 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
3065 static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
3067 nsWineURI *This = impl_from_nsIFileURL(iface);
3068 BOOL b;
3069 HRESULT hres;
3071 TRACE("(%p)->(%p)\n", This, aHasRef);
3073 if(!ensure_uri(This))
3074 return NS_ERROR_UNEXPECTED;
3076 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
3077 if(FAILED(hres))
3078 return NS_ERROR_FAILURE;
3080 *aHasRef = b;
3081 return NS_OK;
3084 static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
3086 nsWineURI *This = impl_from_nsIFileURL(iface);
3088 TRACE("(%p)->(%p)\n", This, aFilePath);
3090 return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
3093 static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
3095 nsWineURI *This = impl_from_nsIFileURL(iface);
3097 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
3099 if(!This->is_mutable)
3100 return NS_ERROR_UNEXPECTED;
3102 return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
3105 static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
3107 nsWineURI *This = impl_from_nsIFileURL(iface);
3108 WCHAR *ptr;
3109 BSTR query;
3110 nsresult nsres;
3111 HRESULT hres;
3113 TRACE("(%p)->(%p)\n", This, aQuery);
3115 if(!ensure_uri(This))
3116 return NS_ERROR_UNEXPECTED;
3118 hres = IUri_GetQuery(This->uri, &query);
3119 if(FAILED(hres))
3120 return NS_ERROR_FAILURE;
3122 ptr = query;
3123 if(ptr && *ptr == '?')
3124 ptr++;
3126 nsres = return_wstr_nsacstr(aQuery, ptr, -1);
3127 SysFreeString(query);
3128 return nsres;
3131 static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
3133 nsWineURI *This = impl_from_nsIFileURL(iface);
3134 const char *querya;
3135 WCHAR *query;
3136 HRESULT hres;
3138 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
3140 if(!ensure_uri_builder(This))
3141 return NS_ERROR_UNEXPECTED;
3143 nsACString_GetData(aQuery, &querya);
3144 query = heap_strdupUtoW(querya);
3145 if(!query)
3146 return NS_ERROR_OUT_OF_MEMORY;
3148 hres = IUriBuilder_SetQuery(This->uri_builder, query);
3149 heap_free(query);
3150 if(FAILED(hres))
3151 return NS_ERROR_UNEXPECTED;
3153 return NS_OK;
3156 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
3158 const WCHAR *ptr;
3159 HRESULT hres;
3161 if(!ensure_uri(This))
3162 return NS_ERROR_UNEXPECTED;
3164 hres = IUri_GetPath(This->uri, path);
3165 if(FAILED(hres))
3166 return NS_ERROR_FAILURE;
3168 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
3169 if(*ptr == '/' || *ptr == '\\')
3170 ptr++;
3171 *file = ptr;
3173 if(ext) {
3174 ptr = wcsrchr(ptr, '.');
3175 if(!ptr)
3176 ptr = *path + SysStringLen(*path);
3177 *ext = ptr;
3180 return NS_OK;
3183 static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
3185 nsWineURI *This = impl_from_nsIFileURL(iface);
3186 const WCHAR *file;
3187 BSTR path;
3188 nsresult nsres;
3190 TRACE("(%p)->(%p)\n", This, aDirectory);
3192 nsres = get_uri_path(This, &path, &file, NULL);
3193 if(NS_FAILED(nsres))
3194 return nsres;
3196 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
3197 SysFreeString(path);
3198 return nsres;
3201 static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
3203 nsWineURI *This = impl_from_nsIFileURL(iface);
3205 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
3207 /* Not implemented by Gecko */
3208 return NS_ERROR_NOT_IMPLEMENTED;
3211 static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
3213 nsWineURI *This = impl_from_nsIFileURL(iface);
3214 const WCHAR *file;
3215 BSTR path;
3216 nsresult nsres;
3218 TRACE("(%p)->(%p)\n", This, aFileName);
3220 nsres = get_uri_path(This, &path, &file, NULL);
3221 if(NS_FAILED(nsres))
3222 return nsres;
3224 nsres = return_wstr_nsacstr(aFileName, file, -1);
3225 SysFreeString(path);
3226 return nsres;
3229 static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
3231 nsWineURI *This = impl_from_nsIFileURL(iface);
3232 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
3233 return NS_ERROR_NOT_IMPLEMENTED;
3236 static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
3238 nsWineURI *This = impl_from_nsIFileURL(iface);
3239 const WCHAR *file, *ext;
3240 BSTR path;
3241 nsresult nsres;
3243 TRACE("(%p)->(%p)\n", This, aFileBaseName);
3245 nsres = get_uri_path(This, &path, &file, &ext);
3246 if(NS_FAILED(nsres))
3247 return nsres;
3249 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
3250 SysFreeString(path);
3251 return nsres;
3254 static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
3256 nsWineURI *This = impl_from_nsIFileURL(iface);
3257 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
3258 return NS_ERROR_NOT_IMPLEMENTED;
3261 static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
3263 nsWineURI *This = impl_from_nsIFileURL(iface);
3265 TRACE("(%p)->(%p)\n", This, aFileExtension);
3267 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
3270 static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
3272 nsWineURI *This = impl_from_nsIFileURL(iface);
3273 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
3274 return NS_ERROR_NOT_IMPLEMENTED;
3277 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3279 nsWineURI *This = impl_from_nsIFileURL(iface);
3280 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3281 return NS_ERROR_NOT_IMPLEMENTED;
3284 static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
3286 nsWineURI *This = impl_from_nsIFileURL(iface);
3287 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
3288 return NS_ERROR_NOT_IMPLEMENTED;
3291 static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
3293 nsWineURI *This = impl_from_nsIFileURL(iface);
3294 WCHAR path[MAX_PATH];
3295 DWORD size;
3296 HRESULT hres;
3298 TRACE("(%p)->(%p)\n", This, aFile);
3300 hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
3301 if(FAILED(hres)) {
3302 WARN("CoInternetParseIUri failed: %08lx\n", hres);
3303 return NS_ERROR_FAILURE;
3306 return create_nsfile(path, aFile);
3309 static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
3311 nsWineURI *This = impl_from_nsIFileURL(iface);
3312 FIXME("(%p)->(%p)\n", This, aFile);
3313 return NS_ERROR_NOT_IMPLEMENTED;
3316 static const nsIFileURLVtbl nsFileURLVtbl = {
3317 nsURI_QueryInterface,
3318 nsURI_AddRef,
3319 nsURI_Release,
3320 nsURI_GetSpec,
3321 nsURI_SetSpec,
3322 nsURI_GetPrePath,
3323 nsURI_GetScheme,
3324 nsURI_SetScheme,
3325 nsURI_GetUserPass,
3326 nsURI_SetUserPass,
3327 nsURI_GetUsername,
3328 nsURI_SetUsername,
3329 nsURI_GetPassword,
3330 nsURI_SetPassword,
3331 nsURI_GetHostPort,
3332 nsURI_SetHostPort,
3333 nsURI_GetHost,
3334 nsURI_SetHost,
3335 nsURI_GetPort,
3336 nsURI_SetPort,
3337 nsURI_GetPath,
3338 nsURI_SetPath,
3339 nsURI_Equals,
3340 nsURI_SchemeIs,
3341 nsURI_Clone,
3342 nsURI_Resolve,
3343 nsURI_GetAsciiSpec,
3344 nsURI_GetAsciiHostPort,
3345 nsURI_GetAsciiHost,
3346 nsURI_GetOriginCharset,
3347 nsURL_GetRef,
3348 nsURL_SetRef,
3349 nsURI_EqualsExceptRef,
3350 nsURI_CloneIgnoreRef,
3351 nsURI_GetSpecIgnoringRef,
3352 nsURI_GetHasRef,
3353 nsURL_GetFilePath,
3354 nsURL_SetFilePath,
3355 nsURL_GetQuery,
3356 nsURL_SetQuery,
3357 nsURL_GetDirectory,
3358 nsURL_SetDirectory,
3359 nsURL_GetFileName,
3360 nsURL_SetFileName,
3361 nsURL_GetFileBaseName,
3362 nsURL_SetFileBaseName,
3363 nsURL_GetFileExtension,
3364 nsURL_SetFileExtension,
3365 nsURL_GetCommonBaseSpec,
3366 nsURL_GetRelativeSpec,
3367 nsFileURL_GetFile,
3368 nsFileURL_SetFile
3371 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
3373 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
3376 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
3377 void **result)
3379 nsWineURI *This = impl_from_nsIStandardURL(iface);
3380 return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
3383 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
3385 nsWineURI *This = impl_from_nsIStandardURL(iface);
3386 return nsIFileURL_AddRef(&This->nsIFileURL_iface);
3389 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
3391 nsWineURI *This = impl_from_nsIStandardURL(iface);
3392 return nsIFileURL_Release(&This->nsIFileURL_iface);
3395 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
3397 nsWineURI *This = impl_from_nsIStandardURL(iface);
3399 TRACE("(%p)->(%p)\n", This, aMutable);
3401 *aMutable = This->is_mutable;
3402 return NS_OK;
3405 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
3407 nsWineURI *This = impl_from_nsIStandardURL(iface);
3409 TRACE("(%p)->(%x)\n", This, aMutable);
3411 This->is_mutable = aMutable;
3412 return NS_OK;
3415 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
3416 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
3418 nsWineURI *This = impl_from_nsIStandardURL(iface);
3419 FIXME("(%p)->(%d %ld %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
3420 return NS_ERROR_NOT_IMPLEMENTED;
3423 static nsresult NSAPI nsStandardURL_SetDefaultPort(nsIStandardURL *iface, LONG aNewDefaultPort)
3425 nsWineURI *This = impl_from_nsIStandardURL(iface);
3426 FIXME("(%p)->(%ld)\n", This, aNewDefaultPort);
3427 return NS_ERROR_NOT_IMPLEMENTED;
3430 static const nsIStandardURLVtbl nsStandardURLVtbl = {
3431 nsStandardURL_QueryInterface,
3432 nsStandardURL_AddRef,
3433 nsStandardURL_Release,
3434 nsStandardURL_GetMutable,
3435 nsStandardURL_SetMutable,
3436 nsStandardURL_Init,
3437 nsStandardURL_SetDefaultPort
3440 static nsresult create_nsuri(IUri *iuri, nsWineURI **_retval)
3442 nsWineURI *ret;
3443 HRESULT hres;
3445 ret = heap_alloc_zero(sizeof(nsWineURI));
3446 if(!ret)
3447 return NS_ERROR_OUT_OF_MEMORY;
3449 ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
3450 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
3451 ret->ref = 1;
3452 ret->is_mutable = TRUE;
3454 IUri_AddRef(iuri);
3455 ret->uri = iuri;
3457 hres = IUri_GetScheme(iuri, &ret->scheme);
3458 if(FAILED(hres))
3459 ret->scheme = URL_SCHEME_UNKNOWN;
3461 TRACE("retval=%p\n", ret);
3462 *_retval = ret;
3463 return NS_OK;
3466 HRESULT create_doc_uri(IUri *iuri, nsWineURI **ret)
3468 nsresult nsres;
3469 nsres = create_nsuri(iuri, ret);
3470 return NS_SUCCEEDED(nsres) ? S_OK : E_OUTOFMEMORY;
3473 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
3475 nsChannel *channel;
3477 if(!ensure_uri(uri))
3478 return NS_ERROR_UNEXPECTED;
3480 channel = heap_alloc_zero(sizeof(nsChannel));
3481 if(!channel)
3482 return NS_ERROR_OUT_OF_MEMORY;
3484 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
3485 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
3486 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
3487 channel->nsICacheInfoChannel_iface.lpVtbl = &nsCacheInfoChannelVtbl;
3488 channel->ref = 1;
3489 channel->request_method = METHOD_GET;
3490 list_init(&channel->response_headers);
3491 list_init(&channel->request_headers);
3493 nsIFileURL_AddRef(&uri->nsIFileURL_iface);
3494 channel->uri = uri;
3496 *ret = channel;
3497 return NS_OK;
3500 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
3502 nsChannel *channel;
3503 nsWineURI *uri;
3504 IUri *iuri;
3505 nsresult nsres;
3506 HRESULT hres;
3508 hres = create_uri(url, 0, &iuri);
3509 if(FAILED(hres))
3510 return hres;
3512 nsres = create_nsuri(iuri, &uri);
3513 IUri_Release(iuri);
3514 if(NS_FAILED(nsres))
3515 return E_FAIL;
3517 nsres = create_nschannel(uri, &channel);
3518 nsIFileURL_Release(&uri->nsIFileURL_iface);
3519 if(NS_FAILED(nsres))
3520 return E_FAIL;
3522 if(orig_channel->load_group) {
3523 nsILoadGroup_AddRef(orig_channel->load_group);
3524 channel->load_group = orig_channel->load_group;
3527 if(orig_channel->notif_callback) {
3528 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
3529 channel->notif_callback = orig_channel->notif_callback;
3532 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
3534 if(orig_channel->request_method == METHOD_POST)
3535 FIXME("unsupported POST method\n");
3537 if(orig_channel->original_uri) {
3538 nsIURI_AddRef(orig_channel->original_uri);
3539 channel->original_uri = orig_channel->original_uri;
3542 if(orig_channel->referrer) {
3543 nsIURI_AddRef(orig_channel->referrer);
3544 channel->referrer = orig_channel->referrer;
3547 *ret = channel;
3548 return S_OK;
3551 typedef struct {
3552 nsIProtocolHandler nsIProtocolHandler_iface;
3554 LONG ref;
3556 nsIProtocolHandler *nshandler;
3557 } nsProtocolHandler;
3559 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
3561 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
3564 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
3565 void **result)
3567 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3569 *result = NULL;
3571 if(IsEqualGUID(&IID_nsISupports, riid)) {
3572 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
3573 *result = &This->nsIProtocolHandler_iface;
3574 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
3575 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
3576 *result = &This->nsIProtocolHandler_iface;
3577 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
3578 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
3579 return NS_NOINTERFACE;
3582 if(*result) {
3583 nsISupports_AddRef((nsISupports*)*result);
3584 return NS_OK;
3587 WARN("(%s %p)\n", debugstr_guid(riid), result);
3588 return NS_NOINTERFACE;
3591 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
3593 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3594 LONG ref = InterlockedIncrement(&This->ref);
3596 TRACE("(%p) ref=%ld\n", This, ref);
3598 return ref;
3601 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3603 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3604 LONG ref = InterlockedDecrement(&This->ref);
3606 TRACE("(%p) ref=%ld\n", This, ref);
3608 if(!ref) {
3609 if(This->nshandler)
3610 nsIProtocolHandler_Release(This->nshandler);
3611 heap_free(This);
3614 return ref;
3617 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3619 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3621 TRACE("(%p)->(%p)\n", This, aScheme);
3623 if(This->nshandler)
3624 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3625 return NS_ERROR_NOT_IMPLEMENTED;
3628 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3629 LONG *aDefaultPort)
3631 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3633 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3635 if(This->nshandler)
3636 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3637 return NS_ERROR_NOT_IMPLEMENTED;
3640 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3641 UINT32 *aProtocolFlags)
3643 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3645 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3647 if(This->nshandler)
3648 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3649 return NS_ERROR_NOT_IMPLEMENTED;
3652 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3653 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3655 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3657 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3658 aBaseURI, _retval);
3660 if(This->nshandler)
3661 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3662 return NS_ERROR_NOT_IMPLEMENTED;
3665 static nsresult NSAPI nsProtocolHandler_NewChannel2(nsIProtocolHandler *iface,
3666 nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3668 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3670 TRACE("(%p)->(%p %p %p)\n", This, aURI, aLoadInfo, _retval);
3672 if(This->nshandler)
3673 return nsIProtocolHandler_NewChannel2(This->nshandler, aURI, aLoadInfo, _retval);
3674 return NS_ERROR_NOT_IMPLEMENTED;
3677 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3678 nsIURI *aURI, nsIChannel **_retval)
3680 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3682 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3684 if(This->nshandler)
3685 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3686 return NS_ERROR_NOT_IMPLEMENTED;
3689 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3690 LONG port, const char *scheme, cpp_bool *_retval)
3692 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3694 TRACE("(%p)->(%ld %s %p)\n", This, port, debugstr_a(scheme), _retval);
3696 if(This->nshandler)
3697 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3698 return NS_ERROR_NOT_IMPLEMENTED;
3701 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3702 nsProtocolHandler_QueryInterface,
3703 nsProtocolHandler_AddRef,
3704 nsProtocolHandler_Release,
3705 nsProtocolHandler_GetScheme,
3706 nsProtocolHandler_GetDefaultPort,
3707 nsProtocolHandler_GetProtocolFlags,
3708 nsProtocolHandler_NewURI,
3709 nsProtocolHandler_NewChannel2,
3710 nsProtocolHandler_NewChannel,
3711 nsProtocolHandler_AllowPort
3714 static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid,
3715 void **result)
3717 if(IsEqualGUID(&IID_nsISupports, riid)) {
3718 TRACE("(IID_nsISupports %p)\n", result);
3719 *result = iface;
3720 }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) {
3721 TRACE("(IID_nsIIOServiceHook %p)\n", result);
3722 *result = iface;
3723 }else {
3724 ERR("(%s %p)\n", debugstr_guid(riid), result);
3725 *result = NULL;
3726 return NS_NOINTERFACE;
3729 nsISupports_AddRef((nsISupports*)*result);
3730 return NS_OK;
3733 static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface)
3735 return 2;
3738 static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface)
3740 return 1;
3743 static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI,
3744 nsILoadInfo *aLoadInfo, nsIChannel **_retval)
3746 nsWineURI *wine_uri;
3747 nsChannel *ret;
3748 nsresult nsres;
3750 TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval);
3752 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3753 if(NS_FAILED(nsres)) {
3754 TRACE("Could not get nsWineURI: %08lx\n", nsres);
3755 return NS_SUCCESS_DEFAULT_ACTION;
3758 nsres = create_nschannel(wine_uri, &ret);
3759 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3760 if(NS_FAILED(nsres))
3761 return nsres;
3763 nsIURI_AddRef(aURI);
3764 ret->original_uri = aURI;
3766 if(aLoadInfo)
3767 nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo);
3769 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3770 return NS_OK;
3773 static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler,
3774 nsIProtocolHandler **_retval)
3776 nsIExternalProtocolHandler *nsexthandler;
3777 nsProtocolHandler *ret;
3778 nsresult nsres;
3780 TRACE("(%p %p)\n", aHandler, _retval);
3782 nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler);
3783 if(NS_FAILED(nsres)) {
3784 nsIProtocolHandler_AddRef(aHandler);
3785 *_retval = aHandler;
3786 return NS_OK;
3789 nsIExternalProtocolHandler_Release(nsexthandler);
3791 ret = heap_alloc(sizeof(nsProtocolHandler));
3792 if(!ret)
3793 return NS_ERROR_OUT_OF_MEMORY;
3795 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3796 ret->ref = 1;
3797 nsIProtocolHandler_AddRef(aHandler);
3798 ret->nshandler = aHandler;
3801 *_retval = &ret->nsIProtocolHandler_iface;
3802 TRACE("return %p\n", *_retval);
3803 return NS_OK;
3806 static BOOL is_gecko_special_uri(const char *spec)
3808 static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource://gre/", "resource://gre-resources/", "javascript:", "wyciwyg:"};
3809 unsigned int i;
3811 for(i=0; i < ARRAY_SIZE(special_schemes); i++) {
3812 if(!_strnicmp(spec, special_schemes[i], strlen(special_schemes[i])))
3813 return TRUE;
3816 if(!_strnicmp(spec, "file:", 5)) {
3817 const char *ptr = spec+5;
3818 while(*ptr == '/')
3819 ptr++;
3820 return is_gecko_path(ptr);
3823 return FALSE;
3826 static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec,
3827 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3829 nsWineURI *wine_uri, *base_wine_uri = NULL;
3830 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3831 const char *spec = NULL;
3832 UINT cp = CP_UTF8;
3833 IUri *urlmon_uri;
3834 nsresult nsres;
3835 HRESULT hres;
3837 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3838 aBaseURI, _retval);
3840 nsACString_GetData(aSpec, &spec);
3841 if(is_gecko_special_uri(spec))
3842 return NS_SUCCESS_DEFAULT_ACTION;
3844 if(!strncmp(spec, "wine:", 5))
3845 spec += 5;
3847 if(aBaseURI) {
3848 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3849 if(NS_SUCCEEDED(nsres)) {
3850 if(!ensure_uri(base_wine_uri))
3851 return NS_ERROR_UNEXPECTED;
3852 }else {
3853 WARN("Could not get base nsWineURI: %08lx\n", nsres);
3857 if(aOriginCharset && *aOriginCharset && _strnicmp(aOriginCharset, "utf", 3)) {
3858 BSTR charset;
3859 int len;
3861 len = MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, NULL, 0);
3862 charset = SysAllocStringLen(NULL, len-1);
3863 if(!charset)
3864 return NS_ERROR_OUT_OF_MEMORY;
3865 MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, charset, len);
3867 cp = cp_from_charset_string(charset);
3869 SysFreeString(charset);
3872 MultiByteToWideChar(cp, 0, spec, -1, new_spec, ARRAY_SIZE(new_spec));
3874 if(base_wine_uri) {
3875 hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri);
3876 }else {
3877 hres = create_uri(new_spec, 0, &urlmon_uri);
3878 if(FAILED(hres))
3879 WARN("create_uri failed: %08lx\n", hres);
3882 if(FAILED(hres))
3883 return NS_SUCCESS_DEFAULT_ACTION;
3885 nsres = create_nsuri(urlmon_uri, &wine_uri);
3886 IUri_Release(urlmon_uri);
3887 if(base_wine_uri)
3888 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3889 if(NS_FAILED(nsres))
3890 return nsres;
3892 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3893 return nsres;
3896 static const char *debugstr_protocol_flags(UINT32 flags)
3898 switch(flags) {
3899 #define X(f) case f: return #f
3900 X(URI_STD);
3901 X(URI_NORELATIVE);
3902 X(URI_NOAUTH);
3903 X(ALLOWS_PROXY);
3904 X(ALLOWS_PROXY_HTTP);
3905 X(URI_INHERITS_SECURITY_CONTEXT);
3906 X(URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
3907 X(URI_LOADABLE_BY_ANYONE);
3908 X(URI_DANGEROUS_TO_LOAD);
3909 X(URI_IS_UI_RESOURCE);
3910 X(URI_IS_LOCAL_FILE);
3911 X(URI_LOADABLE_BY_SUBSUMERS);
3912 X(URI_DOES_NOT_RETURN_DATA);
3913 X(URI_IS_LOCAL_RESOURCE);
3914 X(URI_OPENING_EXECUTES_SCRIPT);
3915 X(URI_NON_PERSISTABLE);
3916 X(URI_FORBIDS_COOKIE_ACCESS);
3917 X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM);
3918 X(URI_SYNC_LOAD_IS_OK);
3919 X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT);
3920 X(URI_FETCHABLE_BY_ANYONE);
3921 #undef X
3922 default:
3923 return wine_dbg_sprintf("%08x", flags);
3927 static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3929 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3930 return NS_SUCCESS_DEFAULT_ACTION;
3933 static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3935 TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
3937 if(aFlags == URI_DOES_NOT_RETURN_DATA) {
3938 *_retval = FALSE;
3939 return S_OK;
3942 return NS_SUCCESS_DEFAULT_ACTION;
3945 static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = {
3946 nsIOServiceHook_QueryInterface,
3947 nsIOServiceHook_AddRef,
3948 nsIOServiceHook_Release,
3949 nsIOServiceHook_NewChannel,
3950 nsIOServiceHook_GetProtocolHandler,
3951 nsIOServiceHook_NewURI,
3952 nsIOServiceHook_ProtocolHasFlags,
3953 nsIOServiceHook_URIChainHasFlags
3956 static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };
3958 void init_nsio(nsIComponentManager *component_manager)
3960 nsIFactory *old_factory = NULL;
3961 nsresult nsres;
3963 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
3964 &IID_nsIFactory, (void**)&old_factory);
3965 if(NS_FAILED(nsres)) {
3966 ERR("Could not get factory: %08lx\n", nsres);
3967 return;
3970 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
3971 if(NS_FAILED(nsres)) {
3972 ERR("Couldn not create nsIOService instance %08lx\n", nsres);
3973 nsIFactory_Release(old_factory);
3974 return;
3977 nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
3978 assert(nsres == NS_OK);
3981 void release_nsio(void)
3983 if(nsio) {
3984 nsIIOService_Release(nsio);
3985 nsio = NULL;
3989 nsresult create_onload_blocker_request(nsIRequest **ret)
3991 nsIChannel *channel;
3992 nsACString spec;
3993 nsresult nsres;
3995 nsACString_InitDepend(&spec, "about:wine-script-onload-blocker");
3996 nsres = nsIIOService_NewChannel(nsio, &spec, NULL, NULL, &channel);
3997 nsACString_Finish(&spec);
3998 if(NS_FAILED(nsres)) {
3999 ERR("Failed to create channel: %08lx\n", nsres);
4000 return nsres;
4003 *ret = (nsIRequest *)channel;
4004 return NS_OK;