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
;
147 if (This
->sink
&& last
!= state
)
151 memset(¶ms
, 0, sizeof(params
));
152 IDispatch_Invoke(This
->sink
, 0, &IID_NULL
, LOCALE_SYSTEM_DEFAULT
, DISPATCH_METHOD
, ¶ms
, 0, 0, 0);
156 static void free_response_headers(httprequest
*This
)
158 struct httpheader
*header
, *header2
;
160 LIST_FOR_EACH_ENTRY_SAFE(header
, header2
, &This
->respheaders
, struct httpheader
, entry
)
162 list_remove(&header
->entry
);
163 SysFreeString(header
->header
);
164 SysFreeString(header
->value
);
168 SysFreeString(This
->raw_respheaders
);
169 This
->raw_respheaders
= NULL
;
172 struct BindStatusCallback
174 IBindStatusCallback IBindStatusCallback_iface
;
175 IHttpNegotiate IHttpNegotiate_iface
;
176 IAuthenticate IAuthenticate_iface
;
180 httprequest
*request
;
185 /* request body data */
189 static inline BindStatusCallback
*impl_from_IBindStatusCallback( IBindStatusCallback
*iface
)
191 return CONTAINING_RECORD(iface
, BindStatusCallback
, IBindStatusCallback_iface
);
194 static inline BindStatusCallback
*impl_from_IHttpNegotiate( IHttpNegotiate
*iface
)
196 return CONTAINING_RECORD(iface
, BindStatusCallback
, IHttpNegotiate_iface
);
199 static inline BindStatusCallback
*impl_from_IAuthenticate( IAuthenticate
*iface
)
201 return CONTAINING_RECORD(iface
, BindStatusCallback
, IAuthenticate_iface
);
204 static void BindStatusCallback_Detach(BindStatusCallback
*bsc
)
208 if (bsc
->binding
) IBinding_Abort(bsc
->binding
);
210 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
214 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
215 REFIID riid
, void **ppv
)
217 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
221 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
223 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
224 IsEqualGUID(&IID_IBindStatusCallback
, riid
))
226 *ppv
= &This
->IBindStatusCallback_iface
;
228 else if (IsEqualGUID(&IID_IHttpNegotiate
, riid
))
230 *ppv
= &This
->IHttpNegotiate_iface
;
232 else if (IsEqualGUID(&IID_IAuthenticate
, riid
))
234 *ppv
= &This
->IAuthenticate_iface
;
236 else if (IsEqualGUID(&IID_IServiceProvider
, riid
) ||
237 IsEqualGUID(&IID_IBindStatusCallbackEx
, riid
) ||
238 IsEqualGUID(&IID_IInternetProtocol
, riid
) ||
239 IsEqualGUID(&IID_IHttpNegotiate2
, riid
))
241 return E_NOINTERFACE
;
246 IBindStatusCallback_AddRef(iface
);
250 FIXME("Unsupported riid = %s\n", debugstr_guid(riid
));
252 return E_NOINTERFACE
;
255 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
257 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
258 LONG ref
= InterlockedIncrement(&This
->ref
);
260 TRACE("(%p) ref = %d\n", This
, ref
);
265 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
267 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
268 LONG ref
= InterlockedDecrement(&This
->ref
);
270 TRACE("(%p) ref = %d\n", This
, ref
);
274 if (This
->binding
) IBinding_Release(This
->binding
);
275 if (This
->stream
) IStream_Release(This
->stream
);
276 if (This
->body
) GlobalFree(This
->body
);
283 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
284 DWORD reserved
, IBinding
*pbind
)
286 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
288 TRACE("(%p)->(%d %p)\n", This
, reserved
, pbind
);
290 if (!pbind
) return E_INVALIDARG
;
292 This
->binding
= pbind
;
293 IBinding_AddRef(pbind
);
295 httprequest_setreadystate(This
->request
, READYSTATE_LOADED
);
297 return CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
300 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pPriority
)
302 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
304 TRACE("(%p)->(%p)\n", This
, pPriority
);
309 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
311 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
313 TRACE("(%p)->(%d)\n", This
, reserved
);
318 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
319 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
321 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
323 TRACE("(%p)->(%u %u %u %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
324 debugstr_w(szStatusText
));
329 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
330 HRESULT hr
, LPCWSTR error
)
332 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
334 TRACE("(%p)->(0x%08x %s)\n", This
, hr
, debugstr_w(error
));
338 IBinding_Release(This
->binding
);
339 This
->binding
= NULL
;
343 httprequest_setreadystate(This
->request
, READYSTATE_COMPLETE
);
348 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
349 DWORD
*bind_flags
, BINDINFO
*pbindinfo
)
351 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
353 TRACE("(%p)->(%p %p)\n", This
, bind_flags
, pbindinfo
);
356 if (This
->request
->async
) *bind_flags
|= BINDF_ASYNCHRONOUS
;
358 if (This
->request
->verb
!= BINDVERB_GET
&& This
->body
)
360 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
361 pbindinfo
->stgmedData
.u
.hGlobal
= This
->body
;
362 pbindinfo
->cbstgmedData
= GlobalSize(This
->body
);
363 /* callback owns passed body pointer */
364 IBindStatusCallback_QueryInterface(iface
, &IID_IUnknown
, (void**)&pbindinfo
->stgmedData
.pUnkForRelease
);
367 pbindinfo
->dwBindVerb
= This
->request
->verb
;
368 if (This
->request
->verb
== BINDVERB_CUSTOM
)
370 pbindinfo
->szCustomVerb
= CoTaskMemAlloc(SysStringByteLen(This
->request
->custom
));
371 strcpyW(pbindinfo
->szCustomVerb
, This
->request
->custom
);
377 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
378 DWORD flags
, DWORD size
, FORMATETC
*format
, STGMEDIUM
*stgmed
)
380 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
385 TRACE("(%p)->(%08x %d %p %p)\n", This
, flags
, size
, format
, stgmed
);
389 hr
= IStream_Read(stgmed
->u
.pstm
, buf
, sizeof(buf
), &read
);
390 if (hr
!= S_OK
) break;
392 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
393 } while((hr
== S_OK
) && written
!= 0 && read
!= 0);
395 httprequest_setreadystate(This
->request
, READYSTATE_INTERACTIVE
);
400 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
401 REFIID riid
, IUnknown
*punk
)
403 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
405 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_guid(riid
), punk
);
410 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
411 BindStatusCallback_QueryInterface
,
412 BindStatusCallback_AddRef
,
413 BindStatusCallback_Release
,
414 BindStatusCallback_OnStartBinding
,
415 BindStatusCallback_GetPriority
,
416 BindStatusCallback_OnLowResource
,
417 BindStatusCallback_OnProgress
,
418 BindStatusCallback_OnStopBinding
,
419 BindStatusCallback_GetBindInfo
,
420 BindStatusCallback_OnDataAvailable
,
421 BindStatusCallback_OnObjectAvailable
424 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate
*iface
,
425 REFIID riid
, void **ppv
)
427 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
428 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallback_iface
, riid
, ppv
);
431 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate
*iface
)
433 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
434 return IBindStatusCallback_AddRef(&This
->IBindStatusCallback_iface
);
437 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate
*iface
)
439 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
440 return IBindStatusCallback_Release(&This
->IBindStatusCallback_iface
);
443 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
444 LPCWSTR url
, LPCWSTR headers
, DWORD reserved
, LPWSTR
*add_headers
)
446 static const WCHAR content_type_utf8W
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
447 't','e','x','t','/','p','l','a','i','n',';','c','h','a','r','s','e','t','=','u','t','f','-','8','\r','\n',0};
449 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
450 const struct httpheader
*entry
;
454 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(url
), debugstr_w(headers
), reserved
, add_headers
);
458 if (This
->request
->use_utf8_content
)
459 size
= sizeof(content_type_utf8W
);
461 if (!list_empty(&This
->request
->reqheaders
))
462 size
+= This
->request
->reqheader_size
*sizeof(WCHAR
);
464 if (!size
) return S_OK
;
466 buff
= CoTaskMemAlloc(size
);
467 if (!buff
) return E_OUTOFMEMORY
;
470 if (This
->request
->use_utf8_content
)
472 lstrcpyW(ptr
, content_type_utf8W
);
473 ptr
+= sizeof(content_type_utf8W
)/sizeof(WCHAR
)-1;
477 LIST_FOR_EACH_ENTRY(entry
, &This
->request
->reqheaders
, struct httpheader
, entry
)
479 lstrcpyW(ptr
, entry
->header
);
480 ptr
+= SysStringLen(entry
->header
);
482 lstrcpyW(ptr
, colspaceW
);
483 ptr
+= sizeof(colspaceW
)/sizeof(WCHAR
)-1;
485 lstrcpyW(ptr
, entry
->value
);
486 ptr
+= SysStringLen(entry
->value
);
488 lstrcpyW(ptr
, crlfW
);
489 ptr
+= sizeof(crlfW
)/sizeof(WCHAR
)-1;
497 static void add_response_header(httprequest
*This
, const WCHAR
*data
, int len
)
499 struct httpheader
*entry
;
500 const WCHAR
*ptr
= data
;
507 header
= SysAllocStringLen(data
, ptr
-data
);
508 /* skip leading spaces for a value */
509 while (*++ptr
== ' ')
511 value
= SysAllocStringLen(ptr
, len
-(ptr
-data
));
520 TRACE("got header %s:%s\n", debugstr_w(header
), debugstr_w(value
));
522 entry
= heap_alloc(sizeof(*entry
));
523 entry
->header
= header
;
524 entry
->value
= value
;
525 list_add_head(&This
->respheaders
, &entry
->entry
);
528 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate
*iface
, DWORD code
,
529 LPCWSTR resp_headers
, LPCWSTR req_headers
, LPWSTR
*add_reqheaders
)
531 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
533 TRACE("(%p)->(%d %s %s %p)\n", This
, code
, debugstr_w(resp_headers
),
534 debugstr_w(req_headers
), add_reqheaders
);
536 This
->request
->status
= code
;
537 /* store headers and status text */
538 free_response_headers(This
->request
);
539 SysFreeString(This
->request
->status_text
);
540 This
->request
->status_text
= NULL
;
543 const WCHAR
*ptr
, *line
, *status_text
;
545 ptr
= line
= resp_headers
;
547 /* skip HTTP-Version */
548 ptr
= strchrW(ptr
, ' ');
551 /* skip Status-Code */
552 ptr
= strchrW(++ptr
, ' ');
556 /* now it supposed to end with CRLF */
559 if (*ptr
== '\r' && *(ptr
+1) == '\n')
562 This
->request
->status_text
= SysAllocStringLen(status_text
, ptr
-status_text
);
563 TRACE("status text %s\n", debugstr_w(This
->request
->status_text
));
571 /* store as unparsed string for now */
572 This
->request
->raw_respheaders
= SysAllocString(line
);
578 static const IHttpNegotiateVtbl BSCHttpNegotiateVtbl
= {
579 BSCHttpNegotiate_QueryInterface
,
580 BSCHttpNegotiate_AddRef
,
581 BSCHttpNegotiate_Release
,
582 BSCHttpNegotiate_BeginningTransaction
,
583 BSCHttpNegotiate_OnResponse
586 static HRESULT WINAPI
Authenticate_QueryInterface(IAuthenticate
*iface
,
587 REFIID riid
, void **ppv
)
589 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
590 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallback_iface
, riid
, ppv
);
593 static ULONG WINAPI
Authenticate_AddRef(IAuthenticate
*iface
)
595 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
596 return IBindStatusCallback_AddRef(&This
->IBindStatusCallback_iface
);
599 static ULONG WINAPI
Authenticate_Release(IAuthenticate
*iface
)
601 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
602 return IBindStatusCallback_Release(&This
->IBindStatusCallback_iface
);
605 static HRESULT WINAPI
Authenticate_Authenticate(IAuthenticate
*iface
,
606 HWND
*hwnd
, LPWSTR
*username
, LPWSTR
*password
)
608 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
609 FIXME("(%p)->(%p %p %p)\n", This
, hwnd
, username
, password
);
613 static const IAuthenticateVtbl AuthenticateVtbl
= {
614 Authenticate_QueryInterface
,
616 Authenticate_Release
,
617 Authenticate_Authenticate
620 static HRESULT
BindStatusCallback_create(httprequest
* This
, BindStatusCallback
**obj
, const VARIANT
*body
)
622 BindStatusCallback
*bsc
;
627 hr
= CreateBindCtx(0, &pbc
);
628 if (hr
!= S_OK
) return hr
;
630 bsc
= heap_alloc(sizeof(*bsc
));
633 IBindCtx_Release(pbc
);
634 return E_OUTOFMEMORY
;
637 bsc
->IBindStatusCallback_iface
.lpVtbl
= &BindStatusCallbackVtbl
;
638 bsc
->IHttpNegotiate_iface
.lpVtbl
= &BSCHttpNegotiateVtbl
;
639 bsc
->IAuthenticate_iface
.lpVtbl
= &AuthenticateVtbl
;
646 TRACE("(%p)->(%p)\n", This
, bsc
);
648 This
->use_utf8_content
= FALSE
;
650 if (This
->verb
!= BINDVERB_GET
)
652 void *send_data
, *ptr
;
653 SAFEARRAY
*sa
= NULL
;
655 if (V_VT(body
) == (VT_VARIANT
|VT_BYREF
))
656 body
= V_VARIANTREF(body
);
662 int len
= SysStringLen(V_BSTR(body
));
663 const WCHAR
*str
= V_BSTR(body
);
666 for (i
= 0; i
< len
; i
++)
675 size
= WideCharToMultiByte(cp
, 0, str
, len
, NULL
, 0, NULL
, NULL
);
676 if (!(ptr
= heap_alloc(size
)))
679 return E_OUTOFMEMORY
;
681 WideCharToMultiByte(cp
, 0, str
, len
, ptr
, size
, NULL
, NULL
);
682 if (cp
== CP_UTF8
) This
->use_utf8_content
= TRUE
;
685 case VT_ARRAY
|VT_UI1
:
688 if ((hr
= SafeArrayAccessData(sa
, (void **)&ptr
)) != S_OK
) return hr
;
689 if ((hr
= SafeArrayGetUBound(sa
, 1, &size
) != S_OK
))
691 SafeArrayUnaccessData(sa
);
702 FIXME("unsupported body data type %d\n", V_VT(body
));
706 bsc
->body
= GlobalAlloc(GMEM_FIXED
, size
);
709 if (V_VT(body
) == VT_BSTR
)
711 else if (V_VT(body
) == (VT_ARRAY
|VT_UI1
))
712 SafeArrayUnaccessData(sa
);
715 return E_OUTOFMEMORY
;
718 send_data
= GlobalLock(bsc
->body
);
719 memcpy(send_data
, ptr
, size
);
720 GlobalUnlock(bsc
->body
);
722 if (V_VT(body
) == VT_BSTR
)
724 else if (V_VT(body
) == (VT_ARRAY
|VT_UI1
))
725 SafeArrayUnaccessData(sa
);
728 hr
= RegisterBindStatusCallback(pbc
, &bsc
->IBindStatusCallback_iface
, NULL
, 0);
733 hr
= CreateURLMoniker(NULL
, This
->url
, &moniker
);
738 hr
= IMoniker_BindToStorage(moniker
, pbc
, NULL
, &IID_IStream
, (void**)&stream
);
739 IMoniker_Release(moniker
);
740 if (stream
) IStream_Release(stream
);
742 IBindCtx_Release(pbc
);
747 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
755 static HRESULT
httprequest_open(httprequest
*This
, BSTR method
, BSTR url
,
756 VARIANT async
, VARIANT user
, VARIANT password
)
758 static const WCHAR MethodGetW
[] = {'G','E','T',0};
759 static const WCHAR MethodPutW
[] = {'P','U','T',0};
760 static const WCHAR MethodPostW
[] = {'P','O','S','T',0};
761 static const WCHAR MethodDeleteW
[] = {'D','E','L','E','T','E',0};
762 VARIANT str
, is_async
;
765 if (!method
|| !url
) return E_INVALIDARG
;
767 /* free previously set data */
768 SysFreeString(This
->url
);
769 SysFreeString(This
->user
);
770 SysFreeString(This
->password
);
771 This
->url
= This
->user
= This
->password
= NULL
;
773 if (!strcmpiW(method
, MethodGetW
))
775 This
->verb
= BINDVERB_GET
;
777 else if (!strcmpiW(method
, MethodPutW
))
779 This
->verb
= BINDVERB_PUT
;
781 else if (!strcmpiW(method
, MethodPostW
))
783 This
->verb
= BINDVERB_POST
;
785 else if (!strcmpiW(method
, MethodDeleteW
))
787 This
->verb
= BINDVERB_CUSTOM
;
788 SysReAllocString(&This
->custom
, method
);
792 FIXME("unsupported request type %s\n", debugstr_w(method
));
797 /* try to combine with site url */
798 if (This
->siteurl
&& PathIsRelativeW(url
))
800 DWORD len
= INTERNET_MAX_URL_LENGTH
;
801 WCHAR
*fullW
= heap_alloc(len
*sizeof(WCHAR
));
803 hr
= UrlCombineW(This
->siteurl
, url
, fullW
, &len
, 0);
806 TRACE("combined url %s\n", debugstr_w(fullW
));
807 This
->url
= SysAllocString(fullW
);
812 This
->url
= SysAllocString(url
);
814 VariantInit(&is_async
);
815 hr
= VariantChangeType(&is_async
, &async
, 0, VT_BOOL
);
816 This
->async
= hr
== S_OK
&& V_BOOL(&is_async
) == VARIANT_TRUE
;
819 hr
= VariantChangeType(&str
, &user
, 0, VT_BSTR
);
821 This
->user
= V_BSTR(&str
);
824 hr
= VariantChangeType(&str
, &password
, 0, VT_BSTR
);
826 This
->password
= V_BSTR(&str
);
828 httprequest_setreadystate(This
, READYSTATE_LOADING
);
833 static HRESULT
httprequest_setRequestHeader(httprequest
*This
, BSTR header
, BSTR value
)
835 struct httpheader
*entry
;
837 if (!header
|| !*header
) return E_INVALIDARG
;
838 if (This
->state
!= READYSTATE_LOADING
) return E_FAIL
;
839 if (!value
) return E_INVALIDARG
;
841 /* replace existing header value if already added */
842 LIST_FOR_EACH_ENTRY(entry
, &This
->reqheaders
, struct httpheader
, entry
)
844 if (lstrcmpW(entry
->header
, header
) == 0)
846 LONG length
= SysStringLen(entry
->value
);
849 hr
= SysReAllocString(&entry
->value
, value
) ? S_OK
: E_OUTOFMEMORY
;
852 This
->reqheader_size
+= (SysStringLen(entry
->value
) - length
);
858 entry
= heap_alloc(sizeof(*entry
));
859 if (!entry
) return E_OUTOFMEMORY
;
862 entry
->header
= SysAllocString(header
);
863 entry
->value
= SysAllocString(value
);
865 /* header length including null terminator */
866 This
->reqheader_size
+= SysStringLen(entry
->header
) + sizeof(colspaceW
)/sizeof(WCHAR
) +
867 SysStringLen(entry
->value
) + sizeof(crlfW
)/sizeof(WCHAR
) - 1;
869 list_add_head(&This
->reqheaders
, &entry
->entry
);
874 static HRESULT
httprequest_getResponseHeader(httprequest
*This
, BSTR header
, BSTR
*value
)
876 struct httpheader
*entry
;
878 if (!header
|| !value
) return E_INVALIDARG
;
880 if (This
->raw_respheaders
&& list_empty(&This
->respheaders
))
884 ptr
= line
= This
->raw_respheaders
;
887 if (*ptr
== '\r' && *(ptr
+1) == '\n')
889 add_response_header(This
, line
, ptr
-line
);
897 LIST_FOR_EACH_ENTRY(entry
, &This
->respheaders
, struct httpheader
, entry
)
899 if (!strcmpiW(entry
->header
, header
))
901 *value
= SysAllocString(entry
->value
);
902 TRACE("header value %s\n", debugstr_w(*value
));
910 static HRESULT
httprequest_getAllResponseHeaders(httprequest
*This
, BSTR
*respheaders
)
912 if (!respheaders
) return E_INVALIDARG
;
914 *respheaders
= SysAllocString(This
->raw_respheaders
);
919 static HRESULT
httprequest_send(httprequest
*This
, VARIANT body
)
921 BindStatusCallback
*bsc
= NULL
;
924 if (This
->state
!= READYSTATE_LOADING
) return E_FAIL
;
926 hr
= BindStatusCallback_create(This
, &bsc
, &body
);
927 if (FAILED(hr
)) return hr
;
929 BindStatusCallback_Detach(This
->bsc
);
935 static HRESULT
httprequest_abort(httprequest
*This
)
937 BindStatusCallback_Detach(This
->bsc
);
940 httprequest_setreadystate(This
, READYSTATE_UNINITIALIZED
);
945 static HRESULT
httprequest_get_status(httprequest
*This
, LONG
*status
)
947 if (!status
) return E_INVALIDARG
;
948 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
950 *status
= This
->status
;
955 static HRESULT
httprequest_get_statusText(httprequest
*This
, BSTR
*status
)
957 if (!status
) return E_INVALIDARG
;
958 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
960 *status
= SysAllocString(This
->status_text
);
965 static HRESULT
httprequest_get_responseText(httprequest
*This
, BSTR
*body
)
970 if (!body
) return E_INVALIDARG
;
971 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
973 hr
= GetHGlobalFromStream(This
->bsc
->stream
, &hglobal
);
976 xmlChar
*ptr
= GlobalLock(hglobal
);
977 DWORD size
= GlobalSize(hglobal
);
978 xmlCharEncoding encoding
= XML_CHAR_ENCODING_UTF8
;
980 /* try to determine data encoding */
983 encoding
= xmlDetectCharEncoding(ptr
, 4);
984 TRACE("detected encoding: %s\n", debugstr_a(xmlGetCharEncodingName(encoding
)));
985 if ( encoding
!= XML_CHAR_ENCODING_UTF8
&&
986 encoding
!= XML_CHAR_ENCODING_UTF16LE
&&
987 encoding
!= XML_CHAR_ENCODING_NONE
)
989 FIXME("unsupported encoding: %s\n", debugstr_a(xmlGetCharEncodingName(encoding
)));
990 GlobalUnlock(hglobal
);
995 /* without BOM assume UTF-8 */
996 if (encoding
== XML_CHAR_ENCODING_UTF8
||
997 encoding
== XML_CHAR_ENCODING_NONE
)
999 DWORD length
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)ptr
, size
, NULL
, 0);
1001 *body
= SysAllocStringLen(NULL
, length
);
1003 MultiByteToWideChar( CP_UTF8
, 0, (LPCSTR
)ptr
, size
, *body
, length
);
1006 *body
= SysAllocStringByteLen((LPCSTR
)ptr
, size
);
1008 if (!*body
) hr
= E_OUTOFMEMORY
;
1009 GlobalUnlock(hglobal
);
1015 static HRESULT
httprequest_get_responseXML(httprequest
*This
, IDispatch
**body
)
1017 IXMLDOMDocument3
*doc
;
1021 if (!body
) return E_INVALIDARG
;
1022 if (This
->state
!= READYSTATE_COMPLETE
) return E_FAIL
;
1024 hr
= DOMDocument_create(MSXML_DEFAULT
, NULL
, (void**)&doc
);
1025 if (hr
!= S_OK
) return hr
;
1027 hr
= httprequest_get_responseText(This
, &str
);
1032 hr
= IXMLDOMDocument3_loadXML(doc
, str
, &ok
);
1036 IXMLDOMDocument3_QueryInterface(doc
, &IID_IDispatch
, (void**)body
);
1037 IXMLDOMDocument3_Release(doc
);
1042 static HRESULT
httprequest_get_responseBody(httprequest
*This
, VARIANT
*body
)
1047 if (!body
) return E_INVALIDARG
;
1048 V_VT(body
) = VT_EMPTY
;
1050 if (This
->state
!= READYSTATE_COMPLETE
) return E_PENDING
;
1052 hr
= GetHGlobalFromStream(This
->bsc
->stream
, &hglobal
);
1055 void *ptr
= GlobalLock(hglobal
);
1056 DWORD size
= GlobalSize(hglobal
);
1058 SAFEARRAYBOUND bound
;
1062 bound
.cElements
= size
;
1063 array
= SafeArrayCreate(VT_UI1
, 1, &bound
);
1069 V_VT(body
) = VT_ARRAY
| VT_UI1
;
1070 V_ARRAY(body
) = array
;
1072 hr
= SafeArrayAccessData(array
, &dest
);
1075 memcpy(dest
, ptr
, size
);
1076 SafeArrayUnaccessData(array
);
1086 GlobalUnlock(hglobal
);
1092 static HRESULT
httprequest_get_responseStream(httprequest
*This
, VARIANT
*body
)
1098 if (!body
) return E_INVALIDARG
;
1099 V_VT(body
) = VT_EMPTY
;
1101 if (This
->state
!= READYSTATE_COMPLETE
) return E_PENDING
;
1103 hr
= IStream_Clone(This
->bsc
->stream
, &stream
);
1106 IStream_Seek(stream
, move
, STREAM_SEEK_SET
, NULL
);
1108 V_VT(body
) = VT_UNKNOWN
;
1109 V_UNKNOWN(body
) = (IUnknown
*)stream
;
1114 static HRESULT
httprequest_get_readyState(httprequest
*This
, LONG
*state
)
1116 if (!state
) return E_INVALIDARG
;
1118 *state
= This
->state
;
1122 static HRESULT
httprequest_put_onreadystatechange(httprequest
*This
, IDispatch
*sink
)
1124 if (This
->sink
) IDispatch_Release(This
->sink
);
1125 if ((This
->sink
= sink
)) IDispatch_AddRef(This
->sink
);
1130 static void httprequest_release(httprequest
*This
)
1132 struct httpheader
*header
, *header2
;
1135 IUnknown_Release( This
->site
);
1137 SysFreeString(This
->custom
);
1138 SysFreeString(This
->siteurl
);
1139 SysFreeString(This
->url
);
1140 SysFreeString(This
->user
);
1141 SysFreeString(This
->password
);
1143 /* request headers */
1144 LIST_FOR_EACH_ENTRY_SAFE(header
, header2
, &This
->reqheaders
, struct httpheader
, entry
)
1146 list_remove(&header
->entry
);
1147 SysFreeString(header
->header
);
1148 SysFreeString(header
->value
);
1151 /* response headers */
1152 free_response_headers(This
);
1153 SysFreeString(This
->status_text
);
1155 /* detach callback object */
1156 BindStatusCallback_Detach(This
->bsc
);
1158 if (This
->sink
) IDispatch_Release(This
->sink
);
1161 static HRESULT WINAPI
XMLHTTPRequest_QueryInterface(IXMLHTTPRequest
*iface
, REFIID riid
, void **ppvObject
)
1163 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1164 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1166 if ( IsEqualGUID( riid
, &IID_IXMLHTTPRequest
) ||
1167 IsEqualGUID( riid
, &IID_IDispatch
) ||
1168 IsEqualGUID( riid
, &IID_IUnknown
) )
1172 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
1174 *ppvObject
= &This
->IObjectWithSite_iface
;
1176 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
1178 *ppvObject
= &This
->IObjectSafety_iface
;
1182 TRACE("Unsupported interface %s\n", debugstr_guid(riid
));
1184 return E_NOINTERFACE
;
1187 IXMLHTTPRequest_AddRef( iface
);
1192 static ULONG WINAPI
XMLHTTPRequest_AddRef(IXMLHTTPRequest
*iface
)
1194 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1195 ULONG ref
= InterlockedIncrement( &This
->ref
);
1196 TRACE("(%p)->(%u)\n", This
, ref
);
1200 static ULONG WINAPI
XMLHTTPRequest_Release(IXMLHTTPRequest
*iface
)
1202 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1203 ULONG ref
= InterlockedDecrement( &This
->ref
);
1205 TRACE("(%p)->(%u)\n", This
, ref
);
1209 httprequest_release( This
);
1216 static HRESULT WINAPI
XMLHTTPRequest_GetTypeInfoCount(IXMLHTTPRequest
*iface
, UINT
*pctinfo
)
1218 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1220 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1227 static HRESULT WINAPI
XMLHTTPRequest_GetTypeInfo(IXMLHTTPRequest
*iface
, UINT iTInfo
,
1228 LCID lcid
, ITypeInfo
**ppTInfo
)
1230 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1232 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1234 return get_typeinfo(IXMLHTTPRequest_tid
, ppTInfo
);
1237 static HRESULT WINAPI
XMLHTTPRequest_GetIDsOfNames(IXMLHTTPRequest
*iface
, REFIID riid
,
1238 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1240 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1241 ITypeInfo
*typeinfo
;
1244 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1247 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
1248 return E_INVALIDARG
;
1250 hr
= get_typeinfo(IXMLHTTPRequest_tid
, &typeinfo
);
1253 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1254 ITypeInfo_Release(typeinfo
);
1260 static HRESULT WINAPI
XMLHTTPRequest_Invoke(IXMLHTTPRequest
*iface
, DISPID dispIdMember
, REFIID riid
,
1261 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1262 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1264 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1265 ITypeInfo
*typeinfo
;
1268 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1269 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1271 hr
= get_typeinfo(IXMLHTTPRequest_tid
, &typeinfo
);
1274 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXMLHTTPRequest_iface
, dispIdMember
, wFlags
,
1275 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1276 ITypeInfo_Release(typeinfo
);
1282 static HRESULT WINAPI
XMLHTTPRequest_open(IXMLHTTPRequest
*iface
, BSTR method
, BSTR url
,
1283 VARIANT async
, VARIANT user
, VARIANT password
)
1285 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1286 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_w(method
), debugstr_w(url
),
1287 debugstr_variant(&async
));
1288 return httprequest_open(This
, method
, url
, async
, user
, password
);
1291 static HRESULT WINAPI
XMLHTTPRequest_setRequestHeader(IXMLHTTPRequest
*iface
, BSTR header
, BSTR value
)
1293 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1294 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(header
), debugstr_w(value
));
1295 return httprequest_setRequestHeader(This
, header
, value
);
1298 static HRESULT WINAPI
XMLHTTPRequest_getResponseHeader(IXMLHTTPRequest
*iface
, BSTR header
, BSTR
*value
)
1300 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1301 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(header
), value
);
1302 return httprequest_getResponseHeader(This
, header
, value
);
1305 static HRESULT WINAPI
XMLHTTPRequest_getAllResponseHeaders(IXMLHTTPRequest
*iface
, BSTR
*respheaders
)
1307 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1308 TRACE("(%p)->(%p)\n", This
, respheaders
);
1309 return httprequest_getAllResponseHeaders(This
, respheaders
);
1312 static HRESULT WINAPI
XMLHTTPRequest_send(IXMLHTTPRequest
*iface
, VARIANT body
)
1314 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1315 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&body
));
1316 return httprequest_send(This
, body
);
1319 static HRESULT WINAPI
XMLHTTPRequest_abort(IXMLHTTPRequest
*iface
)
1321 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1322 TRACE("(%p)\n", This
);
1323 return httprequest_abort(This
);
1326 static HRESULT WINAPI
XMLHTTPRequest_get_status(IXMLHTTPRequest
*iface
, LONG
*status
)
1328 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1329 TRACE("(%p)->(%p)\n", This
, status
);
1330 return httprequest_get_status(This
, status
);
1333 static HRESULT WINAPI
XMLHTTPRequest_get_statusText(IXMLHTTPRequest
*iface
, BSTR
*status
)
1335 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1336 TRACE("(%p)->(%p)\n", This
, status
);
1337 return httprequest_get_statusText(This
, status
);
1340 static HRESULT WINAPI
XMLHTTPRequest_get_responseXML(IXMLHTTPRequest
*iface
, IDispatch
**body
)
1342 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1343 TRACE("(%p)->(%p)\n", This
, body
);
1344 return httprequest_get_responseXML(This
, body
);
1347 static HRESULT WINAPI
XMLHTTPRequest_get_responseText(IXMLHTTPRequest
*iface
, BSTR
*body
)
1349 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1350 TRACE("(%p)->(%p)\n", This
, body
);
1351 return httprequest_get_responseText(This
, body
);
1354 static HRESULT WINAPI
XMLHTTPRequest_get_responseBody(IXMLHTTPRequest
*iface
, VARIANT
*body
)
1356 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1357 TRACE("(%p)->(%p)\n", This
, body
);
1358 return httprequest_get_responseBody(This
, body
);
1361 static HRESULT WINAPI
XMLHTTPRequest_get_responseStream(IXMLHTTPRequest
*iface
, VARIANT
*body
)
1363 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1364 TRACE("(%p)->(%p)\n", This
, body
);
1365 return httprequest_get_responseStream(This
, body
);
1368 static HRESULT WINAPI
XMLHTTPRequest_get_readyState(IXMLHTTPRequest
*iface
, LONG
*state
)
1370 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1371 TRACE("(%p)->(%p)\n", This
, state
);
1372 return httprequest_get_readyState(This
, state
);
1375 static HRESULT WINAPI
XMLHTTPRequest_put_onreadystatechange(IXMLHTTPRequest
*iface
, IDispatch
*sink
)
1377 httprequest
*This
= impl_from_IXMLHTTPRequest( iface
);
1378 TRACE("(%p)->(%p)\n", This
, sink
);
1379 return httprequest_put_onreadystatechange(This
, sink
);
1382 static const struct IXMLHTTPRequestVtbl XMLHTTPRequestVtbl
=
1384 XMLHTTPRequest_QueryInterface
,
1385 XMLHTTPRequest_AddRef
,
1386 XMLHTTPRequest_Release
,
1387 XMLHTTPRequest_GetTypeInfoCount
,
1388 XMLHTTPRequest_GetTypeInfo
,
1389 XMLHTTPRequest_GetIDsOfNames
,
1390 XMLHTTPRequest_Invoke
,
1391 XMLHTTPRequest_open
,
1392 XMLHTTPRequest_setRequestHeader
,
1393 XMLHTTPRequest_getResponseHeader
,
1394 XMLHTTPRequest_getAllResponseHeaders
,
1395 XMLHTTPRequest_send
,
1396 XMLHTTPRequest_abort
,
1397 XMLHTTPRequest_get_status
,
1398 XMLHTTPRequest_get_statusText
,
1399 XMLHTTPRequest_get_responseXML
,
1400 XMLHTTPRequest_get_responseText
,
1401 XMLHTTPRequest_get_responseBody
,
1402 XMLHTTPRequest_get_responseStream
,
1403 XMLHTTPRequest_get_readyState
,
1404 XMLHTTPRequest_put_onreadystatechange
1407 /* IObjectWithSite */
1408 static HRESULT WINAPI
1409 httprequest_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
1411 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1412 return IXMLHTTPRequest_QueryInterface( (IXMLHTTPRequest
*)This
, riid
, ppvObject
);
1415 static ULONG WINAPI
httprequest_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
1417 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1418 return IXMLHTTPRequest_AddRef((IXMLHTTPRequest
*)This
);
1421 static ULONG WINAPI
httprequest_ObjectWithSite_Release( IObjectWithSite
* iface
)
1423 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1424 return IXMLHTTPRequest_Release((IXMLHTTPRequest
*)This
);
1427 static HRESULT WINAPI
httprequest_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
1429 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1431 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
1436 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
1439 static HRESULT WINAPI
httprequest_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
1441 httprequest
*This
= impl_from_IObjectWithSite(iface
);
1442 IServiceProvider
*provider
;
1445 TRACE("(%p)->(%p)\n", iface
, punk
);
1448 IUnknown_AddRef( punk
);
1451 IUnknown_Release( This
->site
);
1455 hr
= IUnknown_QueryInterface(This
->site
, &IID_IServiceProvider
, (void**)&provider
);
1458 IHTMLDocument2
*doc
;
1460 hr
= IServiceProvider_QueryService(provider
, &SID_SContainerDispatch
, &IID_IHTMLDocument2
, (void**)&doc
);
1463 SysFreeString(This
->siteurl
);
1465 hr
= IHTMLDocument2_get_URL(doc
, &This
->siteurl
);
1466 IHTMLDocument2_Release(doc
);
1467 TRACE("host url %s, 0x%08x\n", debugstr_w(This
->siteurl
), hr
);
1469 IServiceProvider_Release(provider
);
1475 static const IObjectWithSiteVtbl ObjectWithSiteVtbl
=
1477 httprequest_ObjectWithSite_QueryInterface
,
1478 httprequest_ObjectWithSite_AddRef
,
1479 httprequest_ObjectWithSite_Release
,
1480 httprequest_ObjectWithSite_SetSite
,
1481 httprequest_ObjectWithSite_GetSite
1485 static HRESULT WINAPI
httprequest_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
1487 httprequest
*This
= impl_from_IObjectSafety(iface
);
1488 return IXMLHTTPRequest_QueryInterface( (IXMLHTTPRequest
*)This
, riid
, ppv
);
1491 static ULONG WINAPI
httprequest_Safety_AddRef(IObjectSafety
*iface
)
1493 httprequest
*This
= impl_from_IObjectSafety(iface
);
1494 return IXMLHTTPRequest_AddRef((IXMLHTTPRequest
*)This
);
1497 static ULONG WINAPI
httprequest_Safety_Release(IObjectSafety
*iface
)
1499 httprequest
*This
= impl_from_IObjectSafety(iface
);
1500 return IXMLHTTPRequest_Release((IXMLHTTPRequest
*)This
);
1503 static HRESULT WINAPI
httprequest_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1504 DWORD
*supported
, DWORD
*enabled
)
1506 httprequest
*This
= impl_from_IObjectSafety(iface
);
1508 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
1510 if(!supported
|| !enabled
) return E_POINTER
;
1512 *supported
= safety_supported_options
;
1513 *enabled
= This
->safeopt
;
1518 static HRESULT WINAPI
httprequest_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1519 DWORD mask
, DWORD enabled
)
1521 httprequest
*This
= impl_from_IObjectSafety(iface
);
1522 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
1524 if ((mask
& ~safety_supported_options
))
1527 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
1532 static const IObjectSafetyVtbl ObjectSafetyVtbl
= {
1533 httprequest_Safety_QueryInterface
,
1534 httprequest_Safety_AddRef
,
1535 httprequest_Safety_Release
,
1536 httprequest_Safety_GetInterfaceSafetyOptions
,
1537 httprequest_Safety_SetInterfaceSafetyOptions
1540 /* IServerXMLHTTPRequest */
1541 static HRESULT WINAPI
ServerXMLHTTPRequest_QueryInterface(IServerXMLHTTPRequest
*iface
, REFIID riid
, void **obj
)
1543 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1545 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1547 if ( IsEqualGUID( riid
, &IID_IServerXMLHTTPRequest
) ||
1548 IsEqualGUID( riid
, &IID_IXMLHTTPRequest
) ||
1549 IsEqualGUID( riid
, &IID_IDispatch
) ||
1550 IsEqualGUID( riid
, &IID_IUnknown
) )
1556 TRACE("Unsupported interface %s\n", debugstr_guid(riid
));
1558 return E_NOINTERFACE
;
1561 IServerXMLHTTPRequest_AddRef( iface
);
1566 static ULONG WINAPI
ServerXMLHTTPRequest_AddRef(IServerXMLHTTPRequest
*iface
)
1568 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1569 ULONG ref
= InterlockedIncrement( &This
->ref
);
1570 TRACE("(%p)->(%u)\n", This
, ref
);
1574 static ULONG WINAPI
ServerXMLHTTPRequest_Release(IServerXMLHTTPRequest
*iface
)
1576 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1577 ULONG ref
= InterlockedDecrement( &This
->ref
);
1579 TRACE("(%p)->(%u)\n", This
, ref
);
1583 httprequest_release( &This
->req
);
1590 static HRESULT WINAPI
ServerXMLHTTPRequest_GetTypeInfoCount(IServerXMLHTTPRequest
*iface
, UINT
*pctinfo
)
1592 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1594 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1600 static HRESULT WINAPI
ServerXMLHTTPRequest_GetTypeInfo(IServerXMLHTTPRequest
*iface
, UINT iTInfo
,
1601 LCID lcid
, ITypeInfo
**ppTInfo
)
1603 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1605 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1607 return get_typeinfo(IServerXMLHTTPRequest_tid
, ppTInfo
);
1610 static HRESULT WINAPI
ServerXMLHTTPRequest_GetIDsOfNames(IServerXMLHTTPRequest
*iface
, REFIID riid
,
1611 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1613 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1614 ITypeInfo
*typeinfo
;
1617 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1620 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
1621 return E_INVALIDARG
;
1623 hr
= get_typeinfo(IServerXMLHTTPRequest_tid
, &typeinfo
);
1626 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1627 ITypeInfo_Release(typeinfo
);
1633 static HRESULT WINAPI
ServerXMLHTTPRequest_Invoke(IServerXMLHTTPRequest
*iface
, DISPID dispIdMember
, REFIID riid
,
1634 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1635 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1637 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1638 ITypeInfo
*typeinfo
;
1641 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1642 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1644 hr
= get_typeinfo(IServerXMLHTTPRequest_tid
, &typeinfo
);
1647 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IServerXMLHTTPRequest_iface
, dispIdMember
, wFlags
,
1648 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1649 ITypeInfo_Release(typeinfo
);
1655 static HRESULT WINAPI
ServerXMLHTTPRequest_open(IServerXMLHTTPRequest
*iface
, BSTR method
, BSTR url
,
1656 VARIANT async
, VARIANT user
, VARIANT password
)
1658 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1659 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_w(method
), debugstr_w(url
),
1660 debugstr_variant(&async
));
1661 return httprequest_open(&This
->req
, method
, url
, async
, user
, password
);
1664 static HRESULT WINAPI
ServerXMLHTTPRequest_setRequestHeader(IServerXMLHTTPRequest
*iface
, BSTR header
, BSTR value
)
1666 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1667 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(header
), debugstr_w(value
));
1668 return httprequest_setRequestHeader(&This
->req
, header
, value
);
1671 static HRESULT WINAPI
ServerXMLHTTPRequest_getResponseHeader(IServerXMLHTTPRequest
*iface
, BSTR header
, BSTR
*value
)
1673 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1674 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(header
), value
);
1675 return httprequest_getResponseHeader(&This
->req
, header
, value
);
1678 static HRESULT WINAPI
ServerXMLHTTPRequest_getAllResponseHeaders(IServerXMLHTTPRequest
*iface
, BSTR
*respheaders
)
1680 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1681 TRACE("(%p)->(%p)\n", This
, respheaders
);
1682 return httprequest_getAllResponseHeaders(&This
->req
, respheaders
);
1685 static HRESULT WINAPI
ServerXMLHTTPRequest_send(IServerXMLHTTPRequest
*iface
, VARIANT body
)
1687 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1688 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&body
));
1689 return httprequest_send(&This
->req
, body
);
1692 static HRESULT WINAPI
ServerXMLHTTPRequest_abort(IServerXMLHTTPRequest
*iface
)
1694 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1695 TRACE("(%p)\n", This
);
1696 return httprequest_abort(&This
->req
);
1699 static HRESULT WINAPI
ServerXMLHTTPRequest_get_status(IServerXMLHTTPRequest
*iface
, LONG
*status
)
1701 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1702 TRACE("(%p)->(%p)\n", This
, status
);
1703 return httprequest_get_status(&This
->req
, status
);
1706 static HRESULT WINAPI
ServerXMLHTTPRequest_get_statusText(IServerXMLHTTPRequest
*iface
, BSTR
*status
)
1708 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1709 TRACE("(%p)->(%p)\n", This
, status
);
1710 return httprequest_get_statusText(&This
->req
, status
);
1713 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseXML(IServerXMLHTTPRequest
*iface
, IDispatch
**body
)
1715 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1716 TRACE("(%p)->(%p)\n", This
, body
);
1717 return httprequest_get_responseXML(&This
->req
, body
);
1720 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseText(IServerXMLHTTPRequest
*iface
, BSTR
*body
)
1722 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1723 TRACE("(%p)->(%p)\n", This
, body
);
1724 return httprequest_get_responseText(&This
->req
, body
);
1727 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseBody(IServerXMLHTTPRequest
*iface
, VARIANT
*body
)
1729 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1730 TRACE("(%p)->(%p)\n", This
, body
);
1731 return httprequest_get_responseBody(&This
->req
, body
);
1734 static HRESULT WINAPI
ServerXMLHTTPRequest_get_responseStream(IServerXMLHTTPRequest
*iface
, VARIANT
*body
)
1736 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1737 TRACE("(%p)->(%p)\n", This
, body
);
1738 return httprequest_get_responseStream(&This
->req
, body
);
1741 static HRESULT WINAPI
ServerXMLHTTPRequest_get_readyState(IServerXMLHTTPRequest
*iface
, LONG
*state
)
1743 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1744 TRACE("(%p)->(%p)\n", This
, state
);
1745 return httprequest_get_readyState(&This
->req
, state
);
1748 static HRESULT WINAPI
ServerXMLHTTPRequest_put_onreadystatechange(IServerXMLHTTPRequest
*iface
, IDispatch
*sink
)
1750 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1751 TRACE("(%p)->(%p)\n", This
, sink
);
1752 return httprequest_put_onreadystatechange(&This
->req
, sink
);
1755 static HRESULT WINAPI
ServerXMLHTTPRequest_setTimeouts(IServerXMLHTTPRequest
*iface
, LONG resolveTimeout
, LONG connectTimeout
,
1756 LONG sendTimeout
, LONG receiveTimeout
)
1758 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1759 FIXME("(%p)->(%d %d %d %d): stub\n", This
, resolveTimeout
, connectTimeout
, sendTimeout
, receiveTimeout
);
1763 static HRESULT WINAPI
ServerXMLHTTPRequest_waitForResponse(IServerXMLHTTPRequest
*iface
, VARIANT timeout
, VARIANT_BOOL
*isSuccessful
)
1765 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1766 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_variant(&timeout
), isSuccessful
);
1770 static HRESULT WINAPI
ServerXMLHTTPRequest_getOption(IServerXMLHTTPRequest
*iface
, SERVERXMLHTTP_OPTION option
, VARIANT
*value
)
1772 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1773 FIXME("(%p)->(%d %p): stub\n", This
, option
, value
);
1777 static HRESULT WINAPI
ServerXMLHTTPRequest_setOption(IServerXMLHTTPRequest
*iface
, SERVERXMLHTTP_OPTION option
, VARIANT value
)
1779 serverhttp
*This
= impl_from_IServerXMLHTTPRequest( iface
);
1780 FIXME("(%p)->(%d %s): stub\n", This
, option
, debugstr_variant(&value
));
1784 static const struct IServerXMLHTTPRequestVtbl ServerXMLHTTPRequestVtbl
=
1786 ServerXMLHTTPRequest_QueryInterface
,
1787 ServerXMLHTTPRequest_AddRef
,
1788 ServerXMLHTTPRequest_Release
,
1789 ServerXMLHTTPRequest_GetTypeInfoCount
,
1790 ServerXMLHTTPRequest_GetTypeInfo
,
1791 ServerXMLHTTPRequest_GetIDsOfNames
,
1792 ServerXMLHTTPRequest_Invoke
,
1793 ServerXMLHTTPRequest_open
,
1794 ServerXMLHTTPRequest_setRequestHeader
,
1795 ServerXMLHTTPRequest_getResponseHeader
,
1796 ServerXMLHTTPRequest_getAllResponseHeaders
,
1797 ServerXMLHTTPRequest_send
,
1798 ServerXMLHTTPRequest_abort
,
1799 ServerXMLHTTPRequest_get_status
,
1800 ServerXMLHTTPRequest_get_statusText
,
1801 ServerXMLHTTPRequest_get_responseXML
,
1802 ServerXMLHTTPRequest_get_responseText
,
1803 ServerXMLHTTPRequest_get_responseBody
,
1804 ServerXMLHTTPRequest_get_responseStream
,
1805 ServerXMLHTTPRequest_get_readyState
,
1806 ServerXMLHTTPRequest_put_onreadystatechange
,
1807 ServerXMLHTTPRequest_setTimeouts
,
1808 ServerXMLHTTPRequest_waitForResponse
,
1809 ServerXMLHTTPRequest_getOption
,
1810 ServerXMLHTTPRequest_setOption
1813 static void init_httprequest(httprequest
*req
)
1815 req
->IXMLHTTPRequest_iface
.lpVtbl
= &XMLHTTPRequestVtbl
;
1816 req
->IObjectWithSite_iface
.lpVtbl
= &ObjectWithSiteVtbl
;
1817 req
->IObjectSafety_iface
.lpVtbl
= &ObjectSafetyVtbl
;
1823 req
->url
= req
->siteurl
= req
->user
= req
->password
= NULL
;
1825 req
->state
= READYSTATE_UNINITIALIZED
;
1830 req
->status_text
= NULL
;
1831 req
->reqheader_size
= 0;
1832 req
->raw_respheaders
= NULL
;
1833 req
->use_utf8_content
= FALSE
;
1835 list_init(&req
->reqheaders
);
1836 list_init(&req
->respheaders
);
1842 HRESULT
XMLHTTPRequest_create(IUnknown
*outer
, void **obj
)
1846 TRACE("(%p, %p)\n", outer
, obj
);
1848 req
= heap_alloc( sizeof (*req
) );
1850 return E_OUTOFMEMORY
;
1852 init_httprequest(req
);
1853 *obj
= &req
->IXMLHTTPRequest_iface
;
1855 TRACE("returning iface %p\n", *obj
);
1860 HRESULT
ServerXMLHTTP_create(IUnknown
*outer
, void **obj
)
1864 TRACE("(%p, %p)\n", outer
, obj
);
1866 req
= heap_alloc( sizeof (*req
) );
1868 return E_OUTOFMEMORY
;
1870 init_httprequest(&req
->req
);
1871 req
->IServerXMLHTTPRequest_iface
.lpVtbl
= &ServerXMLHTTPRequestVtbl
;
1874 *obj
= &req
->IServerXMLHTTPRequest_iface
;
1876 TRACE("returning iface %p\n", *obj
);
1883 HRESULT
XMLHTTPRequest_create(IUnknown
*pUnkOuter
, void **ppObj
)
1885 MESSAGE("This program tried to use a XMLHTTPRequest object, but\n"
1886 "libxml2 support was not present at compile time.\n");
1890 HRESULT
ServerXMLHTTP_create(IUnknown
*outer
, void **obj
)
1892 MESSAGE("This program tried to use a ServerXMLHTTP object, but\n"
1893 "libxml2 support was not present at compile time.\n");