2 * IXMLHTTPRequest implementation
4 * Copyright 2008 Alistair Leslie-Hughes
5 * Copyright 2010-2012 Nikolay Sivov for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define NONAMELESSUNION
29 # include <libxml/parser.h>
30 # include <libxml/xmlerror.h>
31 # include <libxml/encoding.h>
47 #include "msxml_private.h"
49 #include "wine/debug.h"
50 #include "wine/list.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
56 static const WCHAR colspaceW
[] = {':',' ',0};
57 static const WCHAR crlfW
[] = {'\r','\n',0};
58 static const DWORD safety_supported_options
=
59 INTERFACESAFE_FOR_UNTRUSTED_CALLER
|
60 INTERFACESAFE_FOR_UNTRUSTED_DATA
|
61 INTERFACE_USES_SECURITY_MANAGER
;
63 typedef struct BindStatusCallback BindStatusCallback
;
74 IXMLHTTPRequest IXMLHTTPRequest_iface
;
75 IObjectWithSite IObjectWithSite_iface
;
76 IObjectSafety IObjectSafety_iface
;
88 struct list reqheaders
;
89 /* cached resulting custom request headers string length in WCHARs */
91 /* use UTF-8 content type */
92 BOOL use_utf8_content
;
94 /* response headers */
95 struct list respheaders
;
103 BindStatusCallback
*bsc
;
117 IServerXMLHTTPRequest IServerXMLHTTPRequest_iface
;
121 static inline httprequest
*impl_from_IXMLHTTPRequest( IXMLHTTPRequest
*iface
)
123 return CONTAINING_RECORD(iface
, httprequest
, IXMLHTTPRequest_iface
);
126 static inline httprequest
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
128 return CONTAINING_RECORD(iface
, httprequest
, IObjectWithSite_iface
);
131 static inline httprequest
*impl_from_IObjectSafety(IObjectSafety
*iface
)
133 return CONTAINING_RECORD(iface
, httprequest
, IObjectSafety_iface
);
136 static inline serverhttp
*impl_from_IServerXMLHTTPRequest(IServerXMLHTTPRequest
*iface
)
138 return CONTAINING_RECORD(iface
, serverhttp
, IServerXMLHTTPRequest_iface
);
141 static void httprequest_setreadystate(httprequest
*This
, READYSTATE state
)
143 READYSTATE last
= This
->state
;
144 static const char* readystates
[] = {
145 "READYSTATE_UNINITIALIZED",
146 "READYSTATE_LOADING",
148 "READYSTATE_INTERACTIVE",
149 "READYSTATE_COMPLETE"};
153 TRACE("state %s\n", readystates
[state
]);
155 if (This
->sink
&& last
!= state
)
159 memset(¶ms
, 0, sizeof(params
));
160 IDispatch_Invoke(This
->sink
, 0, &IID_NULL
, LOCALE_SYSTEM_DEFAULT
, DISPATCH_METHOD
, ¶ms
, 0, 0, 0);
164 static void free_response_headers(httprequest
*This
)
166 struct httpheader
*header
, *header2
;
168 LIST_FOR_EACH_ENTRY_SAFE(header
, header2
, &This
->respheaders
, struct httpheader
, entry
)
170 list_remove(&header
->entry
);
171 SysFreeString(header
->header
);
172 SysFreeString(header
->value
);
176 SysFreeString(This
->raw_respheaders
);
177 This
->raw_respheaders
= NULL
;
180 struct BindStatusCallback
182 IBindStatusCallback IBindStatusCallback_iface
;
183 IHttpNegotiate IHttpNegotiate_iface
;
184 IAuthenticate IAuthenticate_iface
;
188 httprequest
*request
;
193 /* request body data */
197 static inline BindStatusCallback
*impl_from_IBindStatusCallback( IBindStatusCallback
*iface
)
199 return CONTAINING_RECORD(iface
, BindStatusCallback
, IBindStatusCallback_iface
);
202 static inline BindStatusCallback
*impl_from_IHttpNegotiate( IHttpNegotiate
*iface
)
204 return CONTAINING_RECORD(iface
, BindStatusCallback
, IHttpNegotiate_iface
);
207 static inline BindStatusCallback
*impl_from_IAuthenticate( IAuthenticate
*iface
)
209 return CONTAINING_RECORD(iface
, BindStatusCallback
, IAuthenticate_iface
);
212 static void BindStatusCallback_Detach(BindStatusCallback
*bsc
)
216 if (bsc
->binding
) IBinding_Abort(bsc
->binding
);
217 bsc
->request
->bsc
= NULL
;
219 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
223 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
224 REFIID riid
, void **ppv
)
226 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
230 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
232 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
233 IsEqualGUID(&IID_IBindStatusCallback
, riid
))
235 *ppv
= &This
->IBindStatusCallback_iface
;
237 else if (IsEqualGUID(&IID_IHttpNegotiate
, riid
))
239 *ppv
= &This
->IHttpNegotiate_iface
;
241 else if (IsEqualGUID(&IID_IAuthenticate
, riid
))
243 *ppv
= &This
->IAuthenticate_iface
;
245 else if (IsEqualGUID(&IID_IServiceProvider
, riid
) ||
246 IsEqualGUID(&IID_IBindStatusCallbackEx
, riid
) ||
247 IsEqualGUID(&IID_IInternetProtocol
, riid
) ||
248 IsEqualGUID(&IID_IHttpNegotiate2
, riid
))
250 return E_NOINTERFACE
;
255 IBindStatusCallback_AddRef(iface
);
259 FIXME("Unsupported riid = %s\n", debugstr_guid(riid
));
261 return E_NOINTERFACE
;
264 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
266 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
267 LONG ref
= InterlockedIncrement(&This
->ref
);
269 TRACE("(%p) ref = %d\n", This
, ref
);
274 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
276 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
277 LONG ref
= InterlockedDecrement(&This
->ref
);
279 TRACE("(%p) ref = %d\n", This
, ref
);
283 if (This
->binding
) IBinding_Release(This
->binding
);
284 if (This
->stream
) IStream_Release(This
->stream
);
285 if (This
->body
) GlobalFree(This
->body
);
292 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
293 DWORD reserved
, IBinding
*pbind
)
295 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
297 TRACE("(%p)->(%d %p)\n", This
, reserved
, pbind
);
299 if (!pbind
) return E_INVALIDARG
;
301 This
->binding
= pbind
;
302 IBinding_AddRef(pbind
);
304 httprequest_setreadystate(This
->request
, READYSTATE_LOADED
);
306 return CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
309 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pPriority
)
311 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
313 TRACE("(%p)->(%p)\n", This
, pPriority
);
318 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
320 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
322 TRACE("(%p)->(%d)\n", This
, reserved
);
327 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
328 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
330 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
332 TRACE("(%p)->(%u %u %u %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
333 debugstr_w(szStatusText
));
338 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
339 HRESULT hr
, LPCWSTR error
)
341 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
343 TRACE("(%p)->(0x%08x %s)\n", This
, hr
, debugstr_w(error
));
347 IBinding_Release(This
->binding
);
348 This
->binding
= NULL
;
353 BindStatusCallback_Detach(This
->request
->bsc
);
354 This
->request
->bsc
= This
;
355 httprequest_setreadystate(This
->request
, READYSTATE_COMPLETE
);
361 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
362 DWORD
*bind_flags
, BINDINFO
*pbindinfo
)
364 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
366 TRACE("(%p)->(%p %p)\n", This
, bind_flags
, pbindinfo
);
369 if (This
->request
->async
) *bind_flags
|= BINDF_ASYNCHRONOUS
;
371 if (This
->request
->verb
!= BINDVERB_GET
&& This
->body
)
373 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
374 pbindinfo
->stgmedData
.u
.hGlobal
= This
->body
;
375 pbindinfo
->cbstgmedData
= GlobalSize(This
->body
);
376 /* callback owns passed body pointer */
377 IBindStatusCallback_QueryInterface(iface
, &IID_IUnknown
, (void**)&pbindinfo
->stgmedData
.pUnkForRelease
);
380 pbindinfo
->dwBindVerb
= This
->request
->verb
;
381 if (This
->request
->verb
== BINDVERB_CUSTOM
)
383 pbindinfo
->szCustomVerb
= CoTaskMemAlloc(SysStringByteLen(This
->request
->custom
));
384 strcpyW(pbindinfo
->szCustomVerb
, This
->request
->custom
);
390 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
391 DWORD flags
, DWORD size
, FORMATETC
*format
, STGMEDIUM
*stgmed
)
393 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
398 TRACE("(%p)->(%08x %d %p %p)\n", This
, flags
, size
, format
, stgmed
);
402 hr
= IStream_Read(stgmed
->u
.pstm
, buf
, sizeof(buf
), &read
);
403 if (hr
!= S_OK
) break;
405 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
406 } while((hr
== S_OK
) && written
!= 0 && read
!= 0);
408 httprequest_setreadystate(This
->request
, READYSTATE_INTERACTIVE
);
413 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
414 REFIID riid
, IUnknown
*punk
)
416 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
418 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_guid(riid
), punk
);
423 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
424 BindStatusCallback_QueryInterface
,
425 BindStatusCallback_AddRef
,
426 BindStatusCallback_Release
,
427 BindStatusCallback_OnStartBinding
,
428 BindStatusCallback_GetPriority
,
429 BindStatusCallback_OnLowResource
,
430 BindStatusCallback_OnProgress
,
431 BindStatusCallback_OnStopBinding
,
432 BindStatusCallback_GetBindInfo
,
433 BindStatusCallback_OnDataAvailable
,
434 BindStatusCallback_OnObjectAvailable
437 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate
*iface
,
438 REFIID riid
, void **ppv
)
440 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
441 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallback_iface
, riid
, ppv
);
444 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate
*iface
)
446 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
447 return IBindStatusCallback_AddRef(&This
->IBindStatusCallback_iface
);
450 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate
*iface
)
452 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
453 return IBindStatusCallback_Release(&This
->IBindStatusCallback_iface
);
456 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
457 LPCWSTR url
, LPCWSTR headers
, DWORD reserved
, LPWSTR
*add_headers
)
459 static const WCHAR content_type_utf8W
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
460 't','e','x','t','/','p','l','a','i','n',';','c','h','a','r','s','e','t','=','u','t','f','-','8','\r','\n',0};
462 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
463 const struct httpheader
*entry
;
467 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(url
), debugstr_w(headers
), reserved
, add_headers
);
471 if (This
->request
->use_utf8_content
)
472 size
= sizeof(content_type_utf8W
);
474 if (!list_empty(&This
->request
->reqheaders
))
475 size
+= This
->request
->reqheader_size
*sizeof(WCHAR
);
477 if (!size
) return S_OK
;
479 buff
= CoTaskMemAlloc(size
);
480 if (!buff
) return E_OUTOFMEMORY
;
483 if (This
->request
->use_utf8_content
)
485 lstrcpyW(ptr
, content_type_utf8W
);
486 ptr
+= sizeof(content_type_utf8W
)/sizeof(WCHAR
)-1;
490 LIST_FOR_EACH_ENTRY(entry
, &This
->request
->reqheaders
, struct httpheader
, entry
)
492 lstrcpyW(ptr
, entry
->header
);
493 ptr
+= SysStringLen(entry
->header
);
495 lstrcpyW(ptr
, colspaceW
);
496 ptr
+= sizeof(colspaceW
)/sizeof(WCHAR
)-1;
498 lstrcpyW(ptr
, entry
->value
);
499 ptr
+= SysStringLen(entry
->value
);
501 lstrcpyW(ptr
, crlfW
);
502 ptr
+= sizeof(crlfW
)/sizeof(WCHAR
)-1;
510 static void add_response_header(httprequest
*This
, const WCHAR
*data
, int len
)
512 struct httpheader
*entry
;
513 const WCHAR
*ptr
= data
;
520 header
= SysAllocStringLen(data
, ptr
-data
);
521 /* skip leading spaces for a value */
522 while (*++ptr
== ' ')
524 value
= SysAllocStringLen(ptr
, len
-(ptr
-data
));
533 TRACE("got header %s:%s\n", debugstr_w(header
), debugstr_w(value
));
535 entry
= heap_alloc(sizeof(*entry
));
536 entry
->header
= header
;
537 entry
->value
= value
;
538 list_add_head(&This
->respheaders
, &entry
->entry
);
541 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate
*iface
, DWORD code
,
542 LPCWSTR resp_headers
, LPCWSTR req_headers
, LPWSTR
*add_reqheaders
)
544 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
546 TRACE("(%p)->(%d %s %s %p)\n", This
, code
, debugstr_w(resp_headers
),
547 debugstr_w(req_headers
), add_reqheaders
);
549 This
->request
->status
= code
;
550 /* store headers and status text */
551 free_response_headers(This
->request
);
552 SysFreeString(This
->request
->status_text
);
553 This
->request
->status_text
= NULL
;
556 const WCHAR
*ptr
, *line
, *status_text
;
558 ptr
= line
= resp_headers
;
560 /* skip HTTP-Version */
561 ptr
= strchrW(ptr
, ' ');
564 /* skip Status-Code */
565 ptr
= strchrW(++ptr
, ' ');
569 /* now it supposed to end with CRLF */
572 if (*ptr
== '\r' && *(ptr
+1) == '\n')
575 This
->request
->status_text
= SysAllocStringLen(status_text
, ptr
-status_text
);
576 TRACE("status text %s\n", debugstr_w(This
->request
->status_text
));
584 /* store as unparsed string for now */
585 This
->request
->raw_respheaders
= SysAllocString(line
);
591 static const IHttpNegotiateVtbl BSCHttpNegotiateVtbl
= {
592 BSCHttpNegotiate_QueryInterface
,
593 BSCHttpNegotiate_AddRef
,
594 BSCHttpNegotiate_Release
,
595 BSCHttpNegotiate_BeginningTransaction
,
596 BSCHttpNegotiate_OnResponse
599 static HRESULT WINAPI
Authenticate_QueryInterface(IAuthenticate
*iface
,
600 REFIID riid
, void **ppv
)
602 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
603 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallback_iface
, riid
, ppv
);
606 static ULONG WINAPI
Authenticate_AddRef(IAuthenticate
*iface
)
608 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
609 return IBindStatusCallback_AddRef(&This
->IBindStatusCallback_iface
);
612 static ULONG WINAPI
Authenticate_Release(IAuthenticate
*iface
)
614 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
615 return IBindStatusCallback_Release(&This
->IBindStatusCallback_iface
);
618 static HRESULT WINAPI
Authenticate_Authenticate(IAuthenticate
*iface
,
619 HWND
*hwnd
, LPWSTR
*username
, LPWSTR
*password
)
621 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
622 FIXME("(%p)->(%p %p %p)\n", This
, hwnd
, username
, password
);
626 static const IAuthenticateVtbl AuthenticateVtbl
= {
627 Authenticate_QueryInterface
,
629 Authenticate_Release
,
630 Authenticate_Authenticate
633 static HRESULT
BindStatusCallback_create(httprequest
* This
, BindStatusCallback
**obj
, const VARIANT
*body
)
635 BindStatusCallback
*bsc
;
640 hr
= CreateBindCtx(0, &pbc
);
641 if (hr
!= S_OK
) return hr
;
643 bsc
= heap_alloc(sizeof(*bsc
));
646 IBindCtx_Release(pbc
);
647 return E_OUTOFMEMORY
;
650 bsc
->IBindStatusCallback_iface
.lpVtbl
= &BindStatusCallbackVtbl
;
651 bsc
->IHttpNegotiate_iface
.lpVtbl
= &BSCHttpNegotiateVtbl
;
652 bsc
->IAuthenticate_iface
.lpVtbl
= &AuthenticateVtbl
;
659 TRACE("(%p)->(%p)\n", This
, bsc
);
661 This
->use_utf8_content
= FALSE
;
663 if (This
->verb
!= BINDVERB_GET
)
665 void *send_data
, *ptr
;
666 SAFEARRAY
*sa
= NULL
;
668 if (V_VT(body
) == (VT_VARIANT
|VT_BYREF
))
669 body
= V_VARIANTREF(body
);
675 int len
= SysStringLen(V_BSTR(body
));
676 const WCHAR
*str
= V_BSTR(body
);
679 for (i
= 0; i
< len
; i
++)
688 size
= WideCharToMultiByte(cp
, 0, str
, len
, NULL
, 0, NULL
, NULL
);
689 if (!(ptr
= heap_alloc(size
)))
692 return E_OUTOFMEMORY
;
694 WideCharToMultiByte(cp
, 0, str
, len
, ptr
, size
, NULL
, NULL
);
695 if (cp
== CP_UTF8
) This
->use_utf8_content
= TRUE
;
698 case VT_ARRAY
|VT_UI1
:
701 if ((hr
= SafeArrayAccessData(sa
, (void **)&ptr
)) != S_OK
)
706 if ((hr
= SafeArrayGetUBound(sa
, 1, &size
) != S_OK
))
708 SafeArrayUnaccessData(sa
);
716 FIXME("unsupported body data type %d\n", V_VT(body
));
725 bsc
->body
= GlobalAlloc(GMEM_FIXED
, size
);
728 if (V_VT(body
) == VT_BSTR
)
730 else if (V_VT(body
) == (VT_ARRAY
|VT_UI1
))
731 SafeArrayUnaccessData(sa
);
734 return E_OUTOFMEMORY
;
737 send_data
= GlobalLock(bsc
->body
);
738 memcpy(send_data
, ptr
, size
);
739 GlobalUnlock(bsc
->body
);
741 if (V_VT(body
) == VT_BSTR
)
743 else if (V_VT(body
) == (VT_ARRAY
|VT_UI1
))
744 SafeArrayUnaccessData(sa
);
747 hr
= RegisterBindStatusCallback(pbc
, &bsc
->IBindStatusCallback_iface
, NULL
, 0);
752 hr
= CreateURLMonikerEx2(NULL
, This
->uri
, &moniker
, URL_MK_UNIFORM
);
757 hr
= IMoniker_BindToStorage(moniker
, pbc
, NULL
, &IID_IStream
, (void**)&stream
);
758 IMoniker_Release(moniker
);
759 if (stream
) IStream_Release(stream
);
761 IBindCtx_Release(pbc
);
766 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
774 static HRESULT
verify_uri(httprequest
*This
, IUri
*uri
)
776 DWORD scheme
, base_scheme
;
777 BSTR host
, base_host
;
780 if(!(This
->safeopt
& INTERFACESAFE_FOR_UNTRUSTED_DATA
))
784 return E_ACCESSDENIED
;
786 hr
= IUri_GetScheme(uri
, &scheme
);
790 hr
= IUri_GetScheme(This
->base_uri
, &base_scheme
);
794 if(scheme
!= base_scheme
) {
795 WARN("Schemes don't match\n");
796 return E_ACCESSDENIED
;
799 if(scheme
== INTERNET_SCHEME_UNKNOWN
) {
800 FIXME("Unknown scheme\n");
801 return E_ACCESSDENIED
;
804 hr
= IUri_GetHost(uri
, &host
);
808 hr
= IUri_GetHost(This
->base_uri
, &base_host
);
810 if(strcmpiW(host
, base_host
)) {
811 WARN("Hosts don't match\n");
814 SysFreeString(base_host
);
821 static HRESULT
httprequest_open(httprequest
*This
, BSTR method
, BSTR url
,
822 VARIANT async
, VARIANT user
, VARIANT password
)
824 static const WCHAR MethodGetW
[] = {'G','E','T',0};
825 static const WCHAR MethodPutW
[] = {'P','U','T',0};
826 static const WCHAR MethodPostW
[] = {'P','O','S','T',0};
827 static const WCHAR MethodDeleteW
[] = {'D','E','L','E','T','E',0};
828 static const WCHAR MethodPropFindW
[] = {'P','R','O','P','F','I','N','D',0};
829 VARIANT str
, is_async
;
833 if (!method
|| !url
) return E_INVALIDARG
;
835 /* free previously set data */
837 IUri_Release(This
->uri
);
841 SysFreeString(This
->user
);
842 SysFreeString(This
->password
);
843 This
->user
= This
->password
= NULL
;
845 if (!strcmpiW(method
, MethodGetW
))
847 This
->verb
= BINDVERB_GET
;
849 else if (!strcmpiW(method
, MethodPutW
))
851 This
->verb
= BINDVERB_PUT
;
853 else if (!strcmpiW(method
, MethodPostW
))
855 This
->verb
= BINDVERB_POST
;
857 else if (!strcmpiW(method
, MethodDeleteW
) ||
858 !strcmpiW(method
, MethodPropFindW
))
860 This
->verb
= BINDVERB_CUSTOM
;
861 SysReAllocString(&This
->custom
, method
);
865 FIXME("unsupported request type %s\n", debugstr_w(method
));
871 hr
= CoInternetCombineUrlEx(This
->base_uri
, url
, 0, &uri
, 0);
873 hr
= CreateUri(url
, 0, 0, &uri
);
875 WARN("Could not create IUri object: %08x\n", hr
);
879 hr
= verify_uri(This
, uri
);
887 VariantInit(&is_async
);
888 hr
= VariantChangeType(&is_async
, &async
, 0, VT_BOOL
);
889 This
->async
= hr
== S_OK
&& V_BOOL(&is_async
);
892 hr
= VariantChangeType(&str
, &user
, 0, VT_BSTR
);
894 This
->user
= V_BSTR(&str
);
897 hr
= VariantChangeType(&str
, &password
, 0, VT_BSTR
);
899 This
->password
= V_BSTR(&str
);
901 httprequest_setreadystate(This
, READYSTATE_LOADING
);
906 static HRESULT
httprequest_setRequestHeader(httprequest
*This
, BSTR header
, BSTR value
)
908 struct httpheader
*entry
;
910 if (!header
|| !*header
) return E_INVALIDARG
;
911 if (This
->state
!= READYSTATE_LOADING
) return E_FAIL
;
912 if (!value
) return E_INVALIDARG
;
914 /* replace existing header value if already added */
915 LIST_FOR_EACH_ENTRY(entry
, &This
->reqheaders
, struct httpheader
, entry
)
917 if (lstrcmpW(entry
->header
, header
) == 0)
919 LONG length
= SysStringLen(entry
->value
);
922 hr
= SysReAllocString(&entry
->value
, value
) ? S_OK
: E_OUTOFMEMORY
;
925 This
->reqheader_size
+= (SysStringLen(entry
->value
) - length
);
931 entry
= heap_alloc(sizeof(*entry
));
932 if (!entry
) return E_OUTOFMEMORY
;
935 entry
->header
= SysAllocString(header
);
936 entry
->value
= SysAllocString(value
);
938 /* header length including null terminator */
939 This
->reqheader_size
+= SysStringLen(entry
->header
) + sizeof(colspaceW
)/sizeof(WCHAR
) +
940 SysStringLen(entry
->value
) + sizeof(crlfW
)/sizeof(WCHAR
) - 1;
942 list_add_head(&This
->reqheaders
, &entry
->entry
);
947 static HRESULT
httprequest_getResponseHeader(httprequest
*This
, BSTR header
, BSTR
*value
)
949 struct httpheader
*entry
;
951 if (!header
|| !value
) return E_INVALIDARG
;
953 if (This
->raw_respheaders
&& list_empty(&This
->respheaders
))
957 ptr
= line
= This
->raw_respheaders
;
960 if (*ptr
== '\r' && *(ptr
+1) == '\n')
962 add_response_header(This
, line
, ptr
-line
);
970 LIST_FOR_EACH_ENTRY(entry
, &This
->respheaders
, struct httpheader
, entry
)
972 if (!strcmpiW(entry
->header
, header
))
974 *value
= SysAllocString(entry
->value
);
975 TRACE("header value %s\n", debugstr_w(*value
));
983 static HRESULT
httprequest_getAllResponseHeaders(httprequest
*This
, BSTR
*respheaders
)
985 if (!respheaders
) return E_INVALIDARG
;
987 *respheaders
= SysAllocString(This
->raw_respheaders
);
992 static HRESULT
httprequest_send(httprequest
*This
, VARIANT body
)
994 BindStatusCallback
*bsc
= NULL
;
997 if (This
->state
!= READYSTATE_LOADING
) return E_FAIL
;
999 hr
= BindStatusCallback_create(This
, &bsc
, &body
);
1001 /* success path to detach it is OnStopBinding call */
1002 BindStatusCallback_Detach(bsc
);
1007 static HRESULT
httprequest_abort(httprequest
*This
)
1009 BindStatusCallback_Detach(This
->bsc
);
1011 httprequest_setreadystate(This
, READYSTATE_UNINITIALIZED
);
1016 static HRESULT
httprequest_get_status(httprequest
*This
, LONG
*status
)
1018 if (!status
) return E_INVALIDARG
;
1019 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
1021 *status
= This
->status
;
1026 static HRESULT
httprequest_get_statusText(httprequest
*This
, BSTR
*status
)
1028 if (!status
) return E_INVALIDARG
;
1029 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
1031 *status
= SysAllocString(This
->status_text
);
1036 static HRESULT
httprequest_get_responseText(httprequest
*This
, BSTR
*body
)
1041 if (!body
) return E_INVALIDARG
;
1042 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
1044 hr
= GetHGlobalFromStream(This
->bsc
->stream
, &hglobal
);
1047 xmlChar
*ptr
= GlobalLock(hglobal
);
1048 DWORD size
= GlobalSize(hglobal
);
1049 xmlCharEncoding encoding
= XML_CHAR_ENCODING_UTF8
;
1051 /* try to determine data encoding */
1054 encoding
= xmlDetectCharEncoding(ptr
, 4);
1055 TRACE("detected encoding: %s\n", debugstr_a(xmlGetCharEncodingName(encoding
)));
1056 if ( encoding
!= XML_CHAR_ENCODING_UTF8
&&
1057 encoding
!= XML_CHAR_ENCODING_UTF16LE
&&
1058 encoding
!= XML_CHAR_ENCODING_NONE
)
1060 FIXME("unsupported encoding: %s\n", debugstr_a(xmlGetCharEncodingName(encoding
)));
1061 GlobalUnlock(hglobal
);
1066 /* without BOM assume UTF-8 */
1067 if (encoding
== XML_CHAR_ENCODING_UTF8
||
1068 encoding
== XML_CHAR_ENCODING_NONE
)
1070 DWORD length
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)ptr
, size
, NULL
, 0);
1072 *body
= SysAllocStringLen(NULL
, length
);
1074 MultiByteToWideChar( CP_UTF8
, 0, (LPCSTR
)ptr
, size
, *body
, length
);
1077 *body
= SysAllocStringByteLen((LPCSTR
)ptr
, size
);
1079 if (!*body
) hr
= E_OUTOFMEMORY
;
1080 GlobalUnlock(hglobal
);
1086 static HRESULT
httprequest_get_responseXML(httprequest
*This
, IDispatch
**body
)
1088 IXMLDOMDocument3
*doc
;
1092 if (!body
) return E_INVALIDARG
;
1093 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
1095 hr
= DOMDocument_create(MSXML_DEFAULT
, NULL
, (void**)&doc
);
1096 if (hr
!= S_OK
) return hr
;
1098 hr
= httprequest_get_responseText(This
, &str
);
1103 hr
= IXMLDOMDocument3_loadXML(doc
, str
, &ok
);
1107 IXMLDOMDocument3_QueryInterface(doc
, &IID_IDispatch
, (void**)body
);
1108 IXMLDOMDocument3_Release(doc
);
1113 static HRESULT
httprequest_get_responseBody(httprequest
*This
, VARIANT
*body
)
1118 if (!body
) return E_INVALIDARG
;
1119 V_VT(body
) = VT_EMPTY
;
1121 if (This
->state
!= READYSTATE_COMPLETE
) return E_PENDING
;
1123 hr
= GetHGlobalFromStream(This
->bsc
->stream
, &hglobal
);
1126 void *ptr
= GlobalLock(hglobal
);
1127 DWORD size
= GlobalSize(hglobal
);
1129 SAFEARRAYBOUND bound
;
1133 bound
.cElements
= size
;
1134 array
= SafeArrayCreate(VT_UI1
, 1, &bound
);
1140 V_VT(body
) = VT_ARRAY
| VT_UI1
;
1141 V_ARRAY(body
) = array
;
1143 hr
= SafeArrayAccessData(array
, &dest
);
1146 memcpy(dest
, ptr
, size
);
1147 SafeArrayUnaccessData(array
);
1157 GlobalUnlock(hglobal
);
1163 static HRESULT
httprequest_get_responseStream(httprequest
*This
, VARIANT
*body
)
1169 if (!body
) return E_INVALIDARG
;
1170 V_VT(body
) = VT_EMPTY
;
1172 if (This
->state
!= READYSTATE_COMPLETE
) return E_PENDING
;
1174 hr
= IStream_Clone(This
->bsc
->stream
, &stream
);
1177 IStream_Seek(stream
, move
, STREAM_SEEK_SET
, NULL
);
1179 V_VT(body
) = VT_UNKNOWN
;
1180 V_UNKNOWN(body
) = (IUnknown
*)stream
;
1185 static HRESULT
httprequest_get_readyState(httprequest
*This
, LONG
*state
)
1187 if (!state
) return E_INVALIDARG
;
1189 *state
= This
->state
;
1193 static HRESULT
httprequest_put_onreadystatechange(httprequest
*This
, IDispatch
*sink
)
1195 if (This
->sink
) IDispatch_Release(This
->sink
);
1196 if ((This
->sink
= sink
)) IDispatch_AddRef(This
->sink
);
1201 static void httprequest_release(httprequest
*This
)
1203 struct httpheader
*header
, *header2
;
1206 IUnknown_Release( This
->site
);
1208 IUri_Release(This
->uri
);
1210 IUri_Release(This
->base_uri
);
1212 SysFreeString(This
->custom
);
1213 SysFreeString(This
->user
);
1214 SysFreeString(This
->password
);
1216 /* request headers */
1217 LIST_FOR_EACH_ENTRY_SAFE(header
, header2
, &This
->reqheaders
, struct httpheader
, entry
)
1219 list_remove(&header
->entry
);
1220 SysFreeString(header
->header
);
1221 SysFreeString(header
->value
);
1224 /* response headers */
1225 free_response_headers(This
);
1226 SysFreeString(This
->status_text
);
1228 /* detach callback object */
1229 BindStatusCallback_Detach(This
->bsc
);
1231 if (This
->sink
) IDispatch_Release(This
->sink
);
1234 static HRESULT WINAPI
XMLHTTPRequest_QueryInterface(IXMLHTTPRequest
*iface
, REFIID riid
, void **ppvObject
)
1236 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1237 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1239 if ( IsEqualGUID( riid
, &IID_IXMLHTTPRequest
) ||
1240 IsEqualGUID( riid
, &IID_IDispatch
) ||
1241 IsEqualGUID( riid
, &IID_IUnknown
) )
1245 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
1247 *ppvObject
= &This
->IObjectWithSite_iface
;
1249 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
1251 *ppvObject
= &This
->IObjectSafety_iface
;
1255 TRACE("Unsupported interface %s\n", debugstr_guid(riid
));
1257 return E_NOINTERFACE
;
1260 IXMLHTTPRequest_AddRef( iface
);
1265 static ULONG WINAPI
XMLHTTPRequest_AddRef(IXMLHTTPRequest
*iface
)
1267 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1268 ULONG ref
= InterlockedIncrement( &This
->ref
);
1269 TRACE("(%p)->(%u)\n", This
, ref
);
1273 static ULONG WINAPI
XMLHTTPRequest_Release(IXMLHTTPRequest
*iface
)
1275 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1276 ULONG ref
= InterlockedDecrement( &This
->ref
);
1278 TRACE("(%p)->(%u)\n", This
, ref
);
1282 httprequest_release( This
);
1289 static HRESULT WINAPI
XMLHTTPRequest_GetTypeInfoCount(IXMLHTTPRequest
*iface
, UINT
*pctinfo
)
1291 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1293 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1300 static HRESULT WINAPI
XMLHTTPRequest_GetTypeInfo(IXMLHTTPRequest
*iface
, UINT iTInfo
,
1301 LCID lcid
, ITypeInfo
**ppTInfo
)
1303 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1305 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1307 return get_typeinfo(IXMLHTTPRequest_tid
, ppTInfo
);
1310 static HRESULT WINAPI
XMLHTTPRequest_GetIDsOfNames(IXMLHTTPRequest
*iface
, REFIID riid
,
1311 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1313 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1314 ITypeInfo
*typeinfo
;
1317 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1320 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
1321 return E_INVALIDARG
;
1323 hr
= get_typeinfo(IXMLHTTPRequest_tid
, &typeinfo
);
1326 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1327 ITypeInfo_Release(typeinfo
);
1333 static HRESULT WINAPI
XMLHTTPRequest_Invoke(IXMLHTTPRequest
*iface
, DISPID dispIdMember
, REFIID riid
,
1334 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1335 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1337 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1338 ITypeInfo
*typeinfo
;
1341 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1342 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1344 hr
= get_typeinfo(IXMLHTTPRequest_tid
, &typeinfo
);
1347 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXMLHTTPRequest_iface
, dispIdMember
, wFlags
,
1348 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1349 ITypeInfo_Release(typeinfo
);
1355 static HRESULT WINAPI
XMLHTTPRequest_open(IXMLHTTPRequest
*iface
, BSTR method
, BSTR url
,
1356 VARIANT async
, VARIANT user
, VARIANT password
)
1358 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1359 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_w(method
), debugstr_w(url
),
1360 debugstr_variant(&async
));
1361 return httprequest_open(This
, method
, url
, async
, user
, password
);
1364 static HRESULT WINAPI
XMLHTTPRequest_setRequestHeader(IXMLHTTPRequest
*iface
, BSTR header
, BSTR value
)
1366 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1367 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(header
), debugstr_w(value
));
1368 return httprequest_setRequestHeader(This
, header
, value
);
1371 static HRESULT WINAPI
XMLHTTPRequest_getResponseHeader(IXMLHTTPRequest
*iface
, BSTR header
, BSTR
*value
)
1373 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1374 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(header
), value
);
1375 return httprequest_getResponseHeader(This
, header
, value
);
1378 static HRESULT WINAPI
XMLHTTPRequest_getAllResponseHeaders(IXMLHTTPRequest
*iface
, BSTR
*respheaders
)
1380 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1381 TRACE("(%p)->(%p)\n", This
, respheaders
);
1382 return httprequest_getAllResponseHeaders(This
, respheaders
);
1385 static HRESULT WINAPI
XMLHTTPRequest_send(IXMLHTTPRequest
*iface
, VARIANT body
)
1387 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1388 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&body
));
1389 return httprequest_send(This
, body
);
1392 static HRESULT WINAPI
XMLHTTPRequest_abort(IXMLHTTPRequest
*iface
)
1394 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1395 TRACE("(%p)\n", This
);
1396 return httprequest_abort(This
);
1399 static HRESULT WINAPI
XMLHTTPRequest_get_status(IXMLHTTPRequest
*iface
, LONG
*status
)
1401 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1402 TRACE("(%p)->(%p)\n", This
, status
);
1403 return httprequest_get_status(This
, status
);
1406 static HRESULT WINAPI
XMLHTTPRequest_get_statusText(IXMLHTTPRequest
*iface
, BSTR
*status
)
1408 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1409 TRACE("(%p)->(%p)\n", This
, status
);
1410 return httprequest_get_statusText(This
, status
);
1413 static HRESULT WINAPI
XMLHTTPRequest_get_responseXML(IXMLHTTPRequest
*iface
, IDispatch
**body
)
1415 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1416 TRACE("(%p)->(%p)\n", This
, body
);
1417 return httprequest_get_responseXML(This
, body
);
1420 static HRESULT WINAPI
XMLHTTPRequest_get_responseText(IXMLHTTPRequest
*iface
, BSTR
*body
)
1422 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1423 TRACE("(%p)->(%p)\n", This
, body
);
1424 return httprequest_get_responseText(This
, body
);
1427 static HRESULT WINAPI
XMLHTTPRequest_get_responseBody(IXMLHTTPRequest
*iface
, VARIANT
*body
)
1429 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1430 TRACE("(%p)->(%p)\n", This
, body
);
1431 return httprequest_get_responseBody(This
, body
);
1434 static HRESULT WINAPI
XMLHTTPRequest_get_responseStream(IXMLHTTPRequest
*iface
, VARIANT
*body
)
1436 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1437 TRACE("(%p)->(%p)\n", This
, body
);
1438 return httprequest_get_responseStream(This
, body
);
1441 static HRESULT WINAPI
XMLHTTPRequest_get_readyState(IXMLHTTPRequest
*iface
, LONG
*state
)
1443 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1444 TRACE("(%p)->(%p)\n", This
, state
);
1445 return httprequest_get_readyState(This
, state
);
1448 static HRESULT WINAPI
XMLHTTPRequest_put_onreadystatechange(IXMLHTTPRequest
*iface
, IDispatch
*sink
)
1450 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1451 TRACE("(%p)->(%p)\n", This
, sink
);
1452 return httprequest_put_onreadystatechange(This
, sink
);
1455 static const struct IXMLHTTPRequestVtbl XMLHTTPRequestVtbl
=
1457 XMLHTTPRequest_QueryInterface
,
1458 XMLHTTPRequest_AddRef
,
1459 XMLHTTPRequest_Release
,
1460 XMLHTTPRequest_GetTypeInfoCount
,
1461 XMLHTTPRequest_GetTypeInfo
,
1462 XMLHTTPRequest_GetIDsOfNames
,
1463 XMLHTTPRequest_Invoke
,
1464 XMLHTTPRequest_open
,
1465 XMLHTTPRequest_setRequestHeader
,
1466 XMLHTTPRequest_getResponseHeader
,
1467 XMLHTTPRequest_getAllResponseHeaders
,
1468 XMLHTTPRequest_send
,
1469 XMLHTTPRequest_abort
,
1470 XMLHTTPRequest_get_status
,
1471 XMLHTTPRequest_get_statusText
,
1472 XMLHTTPRequest_get_responseXML
,
1473 XMLHTTPRequest_get_responseText
,
1474 XMLHTTPRequest_get_responseBody
,
1475 XMLHTTPRequest_get_responseStream
,
1476 XMLHTTPRequest_get_readyState
,
1477 XMLHTTPRequest_put_onreadystatechange
1480 /* IObjectWithSite */
1481 static HRESULT WINAPI
1482 httprequest_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
1484 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1485 return IXMLHTTPRequest_QueryInterface( (IXMLHTTPRequest
*)This
, riid
, ppvObject
);
1488 static ULONG WINAPI
httprequest_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
1490 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1491 return IXMLHTTPRequest_AddRef((IXMLHTTPRequest
*)This
);
1494 static ULONG WINAPI
httprequest_ObjectWithSite_Release( IObjectWithSite
* iface
)
1496 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1497 return IXMLHTTPRequest_Release((IXMLHTTPRequest
*)This
);
1500 static HRESULT WINAPI
httprequest_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
1502 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1504 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
1509 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
1512 static void get_base_uri(httprequest
*This
)
1514 IServiceProvider
*provider
;
1515 IHTMLDocument2
*doc
;
1520 hr
= IUnknown_QueryInterface(This
->site
, &IID_IServiceProvider
, (void**)&provider
);
1524 hr
= IServiceProvider_QueryService(provider
, &SID_SContainerDispatch
, &IID_IHTMLDocument2
, (void**)&doc
);
1525 IServiceProvider_Release(provider
);
1529 hr
= IHTMLDocument2_get_URL(doc
, &url
);
1530 IHTMLDocument2_Release(doc
);
1531 if(FAILED(hr
) || !url
|| !*url
)
1534 TRACE("host url %s\n", debugstr_w(url
));
1536 hr
= CreateUri(url
, 0, 0, &uri
);
1541 This
->base_uri
= uri
;
1544 static HRESULT WINAPI
httprequest_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
1546 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1548 TRACE("(%p)->(%p)\n", This
, punk
);
1551 IUnknown_Release( This
->site
);
1553 IUri_Release(This
->base_uri
);
1559 IUnknown_AddRef( punk
);
1566 static const IObjectWithSiteVtbl ObjectWithSiteVtbl
=
1568 httprequest_ObjectWithSite_QueryInterface
,
1569 httprequest_ObjectWithSite_AddRef
,
1570 httprequest_ObjectWithSite_Release
,
1571 httprequest_ObjectWithSite_SetSite
,
1572 httprequest_ObjectWithSite_GetSite
1576 static HRESULT WINAPI
httprequest_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
1578 httprequest
*This
= impl_from_IObjectSafety(iface
);
1579 return IXMLHTTPRequest_QueryInterface( (IXMLHTTPRequest
*)This
, riid
, ppv
);
1582 static ULONG WINAPI
httprequest_Safety_AddRef(IObjectSafety
*iface
)
1584 httprequest
*This
= impl_from_IObjectSafety(iface
);
1585 return IXMLHTTPRequest_AddRef((IXMLHTTPRequest
*)This
);
1588 static ULONG WINAPI
httprequest_Safety_Release(IObjectSafety
*iface
)
1590 httprequest
*This
= impl_from_IObjectSafety(iface
);
1591 return IXMLHTTPRequest_Release((IXMLHTTPRequest
*)This
);
1594 static HRESULT WINAPI
httprequest_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1595 DWORD
*supported
, DWORD
*enabled
)
1597 httprequest
*This
= impl_from_IObjectSafety(iface
);
1599 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
1601 if(!supported
|| !enabled
) return E_POINTER
;
1603 *supported
= safety_supported_options
;
1604 *enabled
= This
->safeopt
;
1609 static HRESULT WINAPI
httprequest_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1610 DWORD mask
, DWORD enabled
)
1612 httprequest
*This
= impl_from_IObjectSafety(iface
);
1613 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
1615 if ((mask
& ~safety_supported_options
))
1618 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
1623 static const IObjectSafetyVtbl ObjectSafetyVtbl
= {
1624 httprequest_Safety_QueryInterface
,
1625 httprequest_Safety_AddRef
,
1626 httprequest_Safety_Release
,
1627 httprequest_Safety_GetInterfaceSafetyOptions
,
1628 httprequest_Safety_SetInterfaceSafetyOptions
1631 /* IServerXMLHTTPRequest */
1632 static HRESULT WINAPI
ServerXMLHTTPRequest_QueryInterface(IServerXMLHTTPRequest
*iface
, REFIID riid
, void **obj
)
1634 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1636 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1638 if ( IsEqualGUID( riid
, &IID_IServerXMLHTTPRequest
) ||
1639 IsEqualGUID( riid
, &IID_IXMLHTTPRequest
) ||
1640 IsEqualGUID( riid
, &IID_IDispatch
) ||
1641 IsEqualGUID( riid
, &IID_IUnknown
) )
1647 TRACE("Unsupported interface %s\n", debugstr_guid(riid
));
1649 return E_NOINTERFACE
;
1652 IServerXMLHTTPRequest_AddRef( iface
);
1657 static ULONG WINAPI
ServerXMLHTTPRequest_AddRef(IServerXMLHTTPRequest
*iface
)
1659 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1660 ULONG ref
= InterlockedIncrement( &This
->ref
);
1661 TRACE("(%p)->(%u)\n", This
, ref
);
1665 static ULONG WINAPI
ServerXMLHTTPRequest_Release(IServerXMLHTTPRequest
*iface
)
1667 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1668 ULONG ref
= InterlockedDecrement( &This
->ref
);
1670 TRACE("(%p)->(%u)\n", This
, ref
);
1674 httprequest_release( &This
->req
);
1681 static HRESULT WINAPI
ServerXMLHTTPRequest_GetTypeInfoCount(IServerXMLHTTPRequest
*iface
, UINT
*pctinfo
)
1683 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1685 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1691 static HRESULT WINAPI
ServerXMLHTTPRequest_GetTypeInfo(IServerXMLHTTPRequest
*iface
, UINT iTInfo
,
1692 LCID lcid
, ITypeInfo
**ppTInfo
)
1694 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1696 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1698 return get_typeinfo(IServerXMLHTTPRequest_tid
, ppTInfo
);
1701 static HRESULT WINAPI
ServerXMLHTTPRequest_GetIDsOfNames(IServerXMLHTTPRequest
*iface
, REFIID riid
,
1702 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1704 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1705 ITypeInfo
*typeinfo
;
1708 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1711 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
1712 return E_INVALIDARG
;
1714 hr
= get_typeinfo(IServerXMLHTTPRequest_tid
, &typeinfo
);
1717 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1718 ITypeInfo_Release(typeinfo
);
1724 static HRESULT WINAPI
ServerXMLHTTPRequest_Invoke(IServerXMLHTTPRequest
*iface
, DISPID dispIdMember
, REFIID riid
,
1725 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1726 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1728 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1729 ITypeInfo
*typeinfo
;
1732 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1733 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1735 hr
= get_typeinfo(IServerXMLHTTPRequest_tid
, &typeinfo
);
1738 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IServerXMLHTTPRequest_iface
, dispIdMember
, wFlags
,
1739 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1740 ITypeInfo_Release(typeinfo
);
1746 static HRESULT WINAPI
ServerXMLHTTPRequest_open(IServerXMLHTTPRequest
*iface
, BSTR method
, BSTR url
,
1747 VARIANT async
, VARIANT user
, VARIANT password
)
1749 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1750 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_w(method
), debugstr_w(url
),
1751 debugstr_variant(&async
));
1752 return httprequest_open(&This
->req
, method
, url
, async
, user
, password
);
1755 static HRESULT WINAPI
ServerXMLHTTPRequest_setRequestHeader(IServerXMLHTTPRequest
*iface
, BSTR header
, BSTR value
)
1757 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1758 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(header
), debugstr_w(value
));
1759 return httprequest_setRequestHeader(&This
->req
, header
, value
);
1762 static HRESULT WINAPI
ServerXMLHTTPRequest_getResponseHeader(IServerXMLHTTPRequest
*iface
, BSTR header
, BSTR
*value
)
1764 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1765 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(header
), value
);
1766 return httprequest_getResponseHeader(&This
->req
, header
, value
);
1769 static HRESULT WINAPI
ServerXMLHTTPRequest_getAllResponseHeaders(IServerXMLHTTPRequest
*iface
, BSTR
*respheaders
)
1771 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1772 TRACE("(%p)->(%p)\n", This
, respheaders
);
1773 return httprequest_getAllResponseHeaders(&This
->req
, respheaders
);
1776 static HRESULT WINAPI
ServerXMLHTTPRequest_send(IServerXMLHTTPRequest
*iface
, VARIANT body
)
1778 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1779 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&body
));
1780 return httprequest_send(&This
->req
, body
);
1783 static HRESULT WINAPI
ServerXMLHTTPRequest_abort(IServerXMLHTTPRequest
*iface
)
1785 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1786 TRACE("(%p)\n", This
);
1787 return httprequest_abort(&This
->req
);
1790 static HRESULT WINAPI
ServerXMLHTTPRequest_get_status(IServerXMLHTTPRequest
*iface
, LONG
*status
)
1792 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1793 TRACE("(%p)->(%p)\n", This
, status
);
1794 return httprequest_get_status(&This
->req
, status
);
1797 static HRESULT WINAPI
ServerXMLHTTPRequest_get_statusText(IServerXMLHTTPRequest
*iface
, BSTR
*status
)
1799 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1800 TRACE("(%p)->(%p)\n", This
, status
);
1801 return httprequest_get_statusText(&This
->req
, status
);
1804 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseXML(IServerXMLHTTPRequest
*iface
, IDispatch
**body
)
1806 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1807 TRACE("(%p)->(%p)\n", This
, body
);
1808 return httprequest_get_responseXML(&This
->req
, body
);
1811 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseText(IServerXMLHTTPRequest
*iface
, BSTR
*body
)
1813 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1814 TRACE("(%p)->(%p)\n", This
, body
);
1815 return httprequest_get_responseText(&This
->req
, body
);
1818 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseBody(IServerXMLHTTPRequest
*iface
, VARIANT
*body
)
1820 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1821 TRACE("(%p)->(%p)\n", This
, body
);
1822 return httprequest_get_responseBody(&This
->req
, body
);
1825 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseStream(IServerXMLHTTPRequest
*iface
, VARIANT
*body
)
1827 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1828 TRACE("(%p)->(%p)\n", This
, body
);
1829 return httprequest_get_responseStream(&This
->req
, body
);
1832 static HRESULT WINAPI
ServerXMLHTTPRequest_get_readyState(IServerXMLHTTPRequest
*iface
, LONG
*state
)
1834 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1835 TRACE("(%p)->(%p)\n", This
, state
);
1836 return httprequest_get_readyState(&This
->req
, state
);
1839 static HRESULT WINAPI
ServerXMLHTTPRequest_put_onreadystatechange(IServerXMLHTTPRequest
*iface
, IDispatch
*sink
)
1841 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1842 TRACE("(%p)->(%p)\n", This
, sink
);
1843 return httprequest_put_onreadystatechange(&This
->req
, sink
);
1846 static HRESULT WINAPI
ServerXMLHTTPRequest_setTimeouts(IServerXMLHTTPRequest
*iface
, LONG resolveTimeout
, LONG connectTimeout
,
1847 LONG sendTimeout
, LONG receiveTimeout
)
1849 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1850 FIXME("(%p)->(%d %d %d %d): stub\n", This
, resolveTimeout
, connectTimeout
, sendTimeout
, receiveTimeout
);
1854 static HRESULT WINAPI
ServerXMLHTTPRequest_waitForResponse(IServerXMLHTTPRequest
*iface
, VARIANT timeout
, VARIANT_BOOL
*isSuccessful
)
1856 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1857 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_variant(&timeout
), isSuccessful
);
1861 static HRESULT WINAPI
ServerXMLHTTPRequest_getOption(IServerXMLHTTPRequest
*iface
, SERVERXMLHTTP_OPTION option
, VARIANT
*value
)
1863 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1864 FIXME("(%p)->(%d %p): stub\n", This
, option
, value
);
1868 static HRESULT WINAPI
ServerXMLHTTPRequest_setOption(IServerXMLHTTPRequest
*iface
, SERVERXMLHTTP_OPTION option
, VARIANT value
)
1870 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1871 FIXME("(%p)->(%d %s): stub\n", This
, option
, debugstr_variant(&value
));
1875 static const struct IServerXMLHTTPRequestVtbl ServerXMLHTTPRequestVtbl
=
1877 ServerXMLHTTPRequest_QueryInterface
,
1878 ServerXMLHTTPRequest_AddRef
,
1879 ServerXMLHTTPRequest_Release
,
1880 ServerXMLHTTPRequest_GetTypeInfoCount
,
1881 ServerXMLHTTPRequest_GetTypeInfo
,
1882 ServerXMLHTTPRequest_GetIDsOfNames
,
1883 ServerXMLHTTPRequest_Invoke
,
1884 ServerXMLHTTPRequest_open
,
1885 ServerXMLHTTPRequest_setRequestHeader
,
1886 ServerXMLHTTPRequest_getResponseHeader
,
1887 ServerXMLHTTPRequest_getAllResponseHeaders
,
1888 ServerXMLHTTPRequest_send
,
1889 ServerXMLHTTPRequest_abort
,
1890 ServerXMLHTTPRequest_get_status
,
1891 ServerXMLHTTPRequest_get_statusText
,
1892 ServerXMLHTTPRequest_get_responseXML
,
1893 ServerXMLHTTPRequest_get_responseText
,
1894 ServerXMLHTTPRequest_get_responseBody
,
1895 ServerXMLHTTPRequest_get_responseStream
,
1896 ServerXMLHTTPRequest_get_readyState
,
1897 ServerXMLHTTPRequest_put_onreadystatechange
,
1898 ServerXMLHTTPRequest_setTimeouts
,
1899 ServerXMLHTTPRequest_waitForResponse
,
1900 ServerXMLHTTPRequest_getOption
,
1901 ServerXMLHTTPRequest_setOption
1904 static void init_httprequest(httprequest
*req
)
1906 req
->IXMLHTTPRequest_iface
.lpVtbl
= &XMLHTTPRequestVtbl
;
1907 req
->IObjectWithSite_iface
.lpVtbl
= &ObjectWithSiteVtbl
;
1908 req
->IObjectSafety_iface
.lpVtbl
= &ObjectSafetyVtbl
;
1914 req
->uri
= req
->base_uri
= NULL
;
1915 req
->user
= req
->password
= NULL
;
1917 req
->state
= READYSTATE_UNINITIALIZED
;
1922 req
->status_text
= NULL
;
1923 req
->reqheader_size
= 0;
1924 req
->raw_respheaders
= NULL
;
1925 req
->use_utf8_content
= FALSE
;
1927 list_init(&req
->reqheaders
);
1928 list_init(&req
->respheaders
);
1934 HRESULT
XMLHTTPRequest_create(IUnknown
*outer
, void **obj
)
1938 TRACE("(%p, %p)\n", outer
, obj
);
1940 req
= heap_alloc( sizeof (*req
) );
1942 return E_OUTOFMEMORY
;
1944 init_httprequest(req
);
1945 *obj
= &req
->IXMLHTTPRequest_iface
;
1947 TRACE("returning iface %p\n", *obj
);
1952 HRESULT
ServerXMLHTTP_create(IUnknown
*outer
, void **obj
)
1956 TRACE("(%p, %p)\n", outer
, obj
);
1958 req
= heap_alloc( sizeof (*req
) );
1960 return E_OUTOFMEMORY
;
1962 init_httprequest(&req
->req
);
1963 req
->IServerXMLHTTPRequest_iface
.lpVtbl
= &ServerXMLHTTPRequestVtbl
;
1966 *obj
= &req
->IServerXMLHTTPRequest_iface
;
1968 TRACE("returning iface %p\n", *obj
);
1975 HRESULT
XMLHTTPRequest_create(IUnknown
*pUnkOuter
, void **ppObj
)
1977 MESSAGE("This program tried to use a XMLHTTPRequest object, but\n"
1978 "libxml2 support was not present at compile time.\n");
1982 HRESULT
ServerXMLHTTP_create(IUnknown
*outer
, void **obj
)
1984 MESSAGE("This program tried to use a ServerXMLHTTP object, but\n"
1985 "libxml2 support was not present at compile time.\n");