mshtml: Add IHTMLXMLHttpRequest:open() method implementation.
[wine.git] / dlls / mshtml / xmlhttprequest.c
blob3953237490b2fbd7b45199b7c7a006ac82145ef6
1 /*
2 * Copyright 2015 Zhenbo Li
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
20 #include <assert.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
29 #include "wine/debug.h"
31 #include "mshtml_private.h"
32 #include "htmlevent.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36 static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str)
38 char *cstr = heap_strdupWtoU(bstr);
39 if(!cstr)
40 return E_OUTOFMEMORY;
41 nsACString_Init(str, cstr);
42 heap_free(cstr);
43 return S_OK;
46 static HRESULT variant_to_nsastr(VARIANT var, nsAString *ret)
48 switch(V_VT(&var)) {
49 case VT_NULL:
50 case VT_ERROR:
51 case VT_EMPTY:
52 nsAString_Init(ret, NULL);
53 return S_OK;
54 case VT_BSTR:
55 nsAString_InitDepend(ret, V_BSTR(&var));
56 return S_OK;
57 default:
58 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var));
59 return E_INVALIDARG;
63 /* IHTMLXMLHttpRequest */
64 typedef struct {
65 EventTarget event_target;
66 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
67 LONG ref;
68 nsIXMLHttpRequest *nsxhr;
69 } HTMLXMLHttpRequest;
71 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
73 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
76 static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *iface, REFIID riid, void **ppv)
78 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
80 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
82 if(IsEqualGUID(&IID_IUnknown, riid)) {
83 *ppv = &This->IHTMLXMLHttpRequest_iface;
84 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
85 *ppv = &This->IHTMLXMLHttpRequest_iface;
86 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
87 *ppv = &This->IHTMLXMLHttpRequest_iface;
88 }else if(dispex_query_interface(&This->event_target.dispex, riid, ppv)) {
89 return *ppv ? S_OK : E_NOINTERFACE;
90 }else {
91 *ppv = NULL;
92 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
93 return E_NOINTERFACE;
96 IUnknown_AddRef((IUnknown*)*ppv);
97 return S_OK;
100 static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
102 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
103 LONG ref = InterlockedIncrement(&This->ref);
105 TRACE("(%p) ref=%d\n", This, ref);
107 return ref;
110 static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
112 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
113 LONG ref = InterlockedDecrement(&This->ref);
115 TRACE("(%p) ref=%d\n", This, ref);
117 if(!ref) {
118 release_dispex(&This->event_target.dispex);
119 nsIXMLHttpRequest_Release(This->nsxhr);
120 heap_free(This);
123 return ref;
126 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest *iface, UINT *pctinfo)
128 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
129 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
132 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest *iface, UINT iTInfo,
133 LCID lcid, ITypeInfo **ppTInfo)
135 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
137 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
140 static HRESULT WINAPI HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
141 LCID lcid, DISPID *rgDispId)
143 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
145 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
146 lcid, rgDispId);
149 static HRESULT WINAPI HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
150 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
152 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
154 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
155 pDispParams, pVarResult, pExcepInfo, puArgErr);
158 static HRESULT WINAPI HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest *iface, LONG *p)
160 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
161 FIXME("(%p)->(%p)\n", This, p);
162 return E_NOTIMPL;
165 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest *iface, VARIANT *p)
167 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
168 FIXME("(%p)->(%p)\n", This, p);
169 return E_NOTIMPL;
172 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *iface, BSTR *p)
174 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
175 FIXME("(%p)->(%p)\n", This, p);
176 return E_NOTIMPL;
179 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
181 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
182 FIXME("(%p)->(%p)\n", This, p);
183 return E_NOTIMPL;
186 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)
188 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
189 FIXME("(%p)->(%p)\n", This, p);
190 return E_NOTIMPL;
193 static HRESULT WINAPI HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest *iface, BSTR *p)
195 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
196 FIXME("(%p)->(%p)\n", This, p);
197 return E_NOTIMPL;
200 static HRESULT WINAPI HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT v)
202 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
204 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
206 return set_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, &v);
209 static HRESULT WINAPI HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT *p)
211 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
213 TRACE("(%p)->(%p)\n", This, p);
215 return get_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, p);
218 static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
220 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
221 FIXME("(%p)->()\n", This);
222 return E_NOTIMPL;
225 static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword)
227 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
228 nsACString method, url;
229 nsAString user, password;
230 nsresult nsres;
231 HRESULT hres;
233 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword));
235 if(V_VT(&varAsync) != VT_BOOL) {
236 FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync));
237 return E_FAIL;
240 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
241 * synchronous requests on the main thread have been deprecated due to the negative
242 * effects to the user experience.
244 if(!V_BOOL(&varAsync)) {
245 FIXME("Synchronous request is not supported yet\n");
246 return E_FAIL;
249 hres = variant_to_nsastr(varUser, &user);
250 if(FAILED(hres))
251 return hres;
252 hres = variant_to_nsastr(varPassword, &password);
253 if(FAILED(hres)) {
254 nsAString_Finish(&user);
255 return hres;
258 hres = bstr_to_nsacstr(bstrMethod, &method);
259 if(FAILED(hres)) {
260 nsAString_Finish(&user);
261 nsAString_Finish(&password);
262 return hres;
264 hres = bstr_to_nsacstr(bstrUrl, &url);
265 if(FAILED(hres)) {
266 nsAString_Finish(&user);
267 nsAString_Finish(&password);
268 nsACString_Finish(&method);
269 return hres;
272 nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE,
273 &user, &password, 0);
275 nsACString_Finish(&method);
276 nsACString_Finish(&url);
277 nsAString_Finish(&user);
278 nsAString_Finish(&password);
280 if(NS_FAILED(nsres)) {
281 ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres);
282 return E_FAIL;
285 return S_OK;
288 static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)
290 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
291 FIXME("(%p)->(%s)\n", This, debugstr_variant(&varBody));
292 return E_NOTIMPL;
295 static HRESULT WINAPI HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest *iface, BSTR *p)
297 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
298 FIXME("(%p)->(%p)\n", This, p);
299 return E_NOTIMPL;
302 static HRESULT WINAPI HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR *p)
304 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
305 FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrHeader), p);
306 return E_NOTIMPL;
309 static HRESULT WINAPI HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR bstrValue)
311 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
312 FIXME("(%p)->(%s %s)\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
313 return E_NOTIMPL;
316 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
317 HTMLXMLHttpRequest_QueryInterface,
318 HTMLXMLHttpRequest_AddRef,
319 HTMLXMLHttpRequest_Release,
320 HTMLXMLHttpRequest_GetTypeInfoCount,
321 HTMLXMLHttpRequest_GetTypeInfo,
322 HTMLXMLHttpRequest_GetIDsOfNames,
323 HTMLXMLHttpRequest_Invoke,
324 HTMLXMLHttpRequest_get_readyState,
325 HTMLXMLHttpRequest_get_responseBody,
326 HTMLXMLHttpRequest_get_responseText,
327 HTMLXMLHttpRequest_get_responseXML,
328 HTMLXMLHttpRequest_get_status,
329 HTMLXMLHttpRequest_get_statusText,
330 HTMLXMLHttpRequest_put_onreadystatechange,
331 HTMLXMLHttpRequest_get_onreadystatechange,
332 HTMLXMLHttpRequest_abort,
333 HTMLXMLHttpRequest_open,
334 HTMLXMLHttpRequest_send,
335 HTMLXMLHttpRequest_getAllResponseHeaders,
336 HTMLXMLHttpRequest_getResponseHeader,
337 HTMLXMLHttpRequest_setRequestHeader
340 static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
342 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
345 static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, int eid)
347 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
349 FIXME("(%p)\n", This);
351 assert(eid == EVENTID_READYSTATECHANGE);
354 static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl = {
355 NULL,
356 NULL,
357 NULL,
358 NULL,
359 NULL,
360 HTMLXMLHttpRequest_bind_event
363 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
364 IHTMLXMLHttpRequest_tid,
367 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
368 &HTMLXMLHttpRequest_dispex_vtbl,
369 DispHTMLXMLHttpRequest_tid,
370 NULL,
371 HTMLXMLHttpRequest_iface_tids
375 /* IHTMLXMLHttpRequestFactory */
376 static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface)
378 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface);
381 static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory *iface, REFIID riid, void **ppv)
383 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
385 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
387 if(IsEqualGUID(&IID_IUnknown, riid)) {
388 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
389 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
390 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
391 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) {
392 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
393 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
394 return *ppv ? S_OK : E_NOINTERFACE;
395 }else {
396 *ppv = NULL;
397 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
398 return E_NOINTERFACE;
401 IUnknown_AddRef((IUnknown*)*ppv);
402 return S_OK;
405 static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface)
407 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
408 LONG ref = InterlockedIncrement(&This->ref);
410 TRACE("(%p) ref=%d\n", This, ref);
412 return ref;
415 static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface)
417 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
418 LONG ref = InterlockedDecrement(&This->ref);
420 TRACE("(%p) ref=%d\n", This, ref);
422 if(!ref) {
423 release_dispex(&This->dispex);
424 heap_free(This);
427 return ref;
430 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory *iface, UINT *pctinfo)
432 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
433 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
436 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory *iface, UINT iTInfo,
437 LCID lcid, ITypeInfo **ppTInfo)
439 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
441 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
444 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
445 LCID lcid, DISPID *rgDispId)
447 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
449 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
450 lcid, rgDispId);
453 static HRESULT WINAPI HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
454 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
456 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
458 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
459 pDispParams, pVarResult, pExcepInfo, puArgErr);
462 static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p)
464 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
465 HTMLXMLHttpRequest *ret;
466 nsIXMLHttpRequest *nsxhr;
468 TRACE("(%p)->(%p)\n", This, p);
470 nsxhr = create_nsxhr(This->window->base.outer_window->nswindow);
471 if(!nsxhr)
472 return E_FAIL;
474 ret = heap_alloc_zero(sizeof(*ret));
475 if(!ret) {
476 nsIXMLHttpRequest_Release(nsxhr);
477 return E_OUTOFMEMORY;
479 ret->nsxhr = nsxhr;
481 ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
482 init_dispex(&ret->event_target.dispex, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
483 &HTMLXMLHttpRequest_dispex);
484 ret->ref = 1;
486 *p = &ret->IHTMLXMLHttpRequest_iface;
487 return S_OK;
490 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = {
491 HTMLXMLHttpRequestFactory_QueryInterface,
492 HTMLXMLHttpRequestFactory_AddRef,
493 HTMLXMLHttpRequestFactory_Release,
494 HTMLXMLHttpRequestFactory_GetTypeInfoCount,
495 HTMLXMLHttpRequestFactory_GetTypeInfo,
496 HTMLXMLHttpRequestFactory_GetIDsOfNames,
497 HTMLXMLHttpRequestFactory_Invoke,
498 HTMLXMLHttpRequestFactory_create
501 static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = {
502 IHTMLXMLHttpRequestFactory_tid,
505 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
506 NULL,
507 IHTMLXMLHttpRequestFactory_tid,
508 NULL,
509 HTMLXMLHttpRequestFactory_iface_tids
512 HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr)
514 HTMLXMLHttpRequestFactory *ret;
516 ret = heap_alloc(sizeof(*ret));
517 if(!ret)
518 return E_OUTOFMEMORY;
520 ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl;
521 ret->ref = 1;
522 ret->window = window;
524 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface,
525 &HTMLXMLHttpRequestFactory_dispex);
527 *ret_ptr = ret;
528 return S_OK;