2006-04-20 07:36:50 +04:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an " AS
* IS " basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied . See the License for the specific language governing
* rights and limitations under the License .
*
* The Original Code is mozilla . org code .
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation . Portions created by Netscape are
* Copyright ( C ) 1998 Netscape Communications Corporation . All
* Rights Reserved .
*
* Contributor ( s ) :
*/
# include "nsXMLHttpRequest.h"
# include "nsISimpleEnumerator.h"
# include "nsIXPConnect.h"
# include "nsIByteArrayInputStream.h"
# include "nsIUnicodeEncoder.h"
# include "nsIServiceManager.h"
# include "nsICharsetConverterManager.h"
# include "nsLayoutCID.h"
# include "nsIDOMDOMImplementation.h"
# include "nsIPrivateDOMImplementation.h"
# include "nsXPIDLString.h"
# include "nsIURI.h"
# include "nsILoadGroup.h"
# include "nsNetUtil.h"
# include "nsIDOMSerializer.h"
# include "nsISupportsPrimitives.h"
2006-04-20 07:36:54 +04:00
# include "nsIDOMEventReceiver.h"
2006-04-20 07:36:50 +04:00
# include "prprf.h"
# include "nsIDOMEventListener.h"
# include "nsIJSContextStack.h"
2006-04-20 07:36:51 +04:00
# include "nsIScriptSecurityManager.h"
# include "nsICodebasePrincipal.h"
2006-04-20 07:36:54 +04:00
# include "nsWeakPtr.h"
2006-04-20 07:37:08 +04:00
# include "nsICharsetAlias.h"
2006-04-20 07:36:54 +04:00
# ifdef IMPLEMENT_SYNC_LOAD
# include "nsIScriptContext.h"
# include "nsIScriptGlobalObject.h"
# include "nsIDocShell.h"
# include "nsIDocShellTreeItem.h"
2006-04-20 07:37:11 +04:00
# include "nsIDocShellTreeOwner.h"
2006-04-20 07:36:54 +04:00
# include "nsIEventQueueService.h"
2006-04-20 07:37:11 +04:00
# include "nsIInterfaceRequestor.h"
2006-04-20 07:36:54 +04:00
# endif
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
# include "nsIDOMClassInfo.h"
2006-04-20 07:36:50 +04:00
static const char * kLoadAsData = " loadAsData " ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
# define LOADSTR NS_LITERAL_STRING("load")
# define ERRORSTR NS_LITERAL_STRING("error")
2006-04-20 07:36:50 +04:00
2006-04-20 07:36:54 +04:00
// CIDs
2006-04-20 07:36:50 +04:00
static NS_DEFINE_CID ( kIDOMDOMImplementationCID , NS_DOM_IMPLEMENTATION_CID ) ;
static NS_DEFINE_CID ( kCharsetConverterManagerCID , NS_ICHARSETCONVERTERMANAGER_CID ) ;
2006-04-20 07:36:54 +04:00
# ifdef IMPLEMENT_SYNC_LOAD
static NS_DEFINE_IID ( kEventQueueServiceCID , NS_EVENTQUEUESERVICE_CID ) ;
# endif
2006-04-20 07:36:50 +04:00
static JSContext *
GetSafeContext ( )
{
// Get the "safe" JSContext: our JSContext of last resort
nsresult rv ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
nsCOMPtr < nsIThreadJSContextStack > stack =
do_GetService ( " @mozilla.org/js/xpc/ContextStack;1 " , & rv ) ;
2006-04-20 07:36:50 +04:00
if ( NS_FAILED ( rv ) )
return nsnull ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
2006-04-20 07:36:50 +04:00
JSContext * cx ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
if ( NS_FAILED ( stack - > GetSafeJSContext ( & cx ) ) ) {
2006-04-20 07:36:50 +04:00
return nsnull ;
}
return cx ;
}
static JSContext *
GetCurrentContext ( )
{
// Get JSContext from stack.
nsresult rv ;
2006-04-20 07:37:00 +04:00
NS_WITH_SERVICE ( nsIJSContextStack , stack , " @mozilla.org/js/xpc/ContextStack;1 " ,
2006-04-20 07:36:50 +04:00
& rv ) ;
if ( NS_FAILED ( rv ) )
return nsnull ;
JSContext * cx ;
if ( NS_FAILED ( stack - > Peek ( & cx ) ) )
return nsnull ;
return cx ;
}
nsXMLHttpRequestScriptListener : : nsXMLHttpRequestScriptListener ( JSObject * aScopeObj , JSObject * aFunctionObj )
{
NS_INIT_ISUPPORTS ( ) ;
// We don't have to add a GC root for the scope object
// since we'll go away if it goes away
mScopeObj = aScopeObj ;
mFunctionObj = aFunctionObj ;
JSContext * cx ;
cx = GetSafeContext ( ) ;
if ( cx ) {
JS_AddNamedRoot ( cx , & mFunctionObj , " nsXMLHttpRequest " ) ;
}
}
nsXMLHttpRequestScriptListener : : ~ nsXMLHttpRequestScriptListener ( )
{
JSContext * cx ;
cx = GetSafeContext ( ) ;
if ( cx ) {
JS_RemoveRoot ( cx , & mFunctionObj ) ;
}
}
NS_IMPL_ISUPPORTS2 ( nsXMLHttpRequestScriptListener , nsIDOMEventListener , nsIPrivateJSEventListener )
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHODIMP
2006-04-20 07:36:50 +04:00
nsXMLHttpRequestScriptListener : : HandleEvent ( nsIDOMEvent * aEvent )
{
JSContext * cx ;
cx = GetCurrentContext ( ) ;
if ( ! cx ) {
cx = GetSafeContext ( ) ;
}
if ( cx ) {
jsval val ;
// Hmmm...we can't pass along the nsIDOMEvent because
// we may not have the right type of context (required
// to get a JSObject from a nsIScriptObjectOwner)
JS_CallFunctionValue ( cx , mScopeObj ,
OBJECT_TO_JSVAL ( mFunctionObj ) ,
0 , nsnull , & val ) ;
}
return NS_OK ;
}
NS_IMETHODIMP
nsXMLHttpRequestScriptListener : : GetFunctionObj ( JSObject * * aObj )
{
NS_ENSURE_ARG_POINTER ( aObj ) ;
* aObj = mFunctionObj ;
return NS_OK ;
}
2006-04-20 07:36:54 +04:00
/////////////////////////////////////////////
//
// This class exists to prevent a circular reference between
// the loaded document and the nsXMLHttpRequest instance. The
// request owns the document. While the document is loading,
// the request is a load listener, held onto by the document.
// The proxy class breaks the circularity by filling in as the
// load listener and holding a weak reference to the request
// object.
//
/////////////////////////////////////////////
class nsLoadListenerProxy : public nsIDOMLoadListener {
public :
nsLoadListenerProxy ( nsWeakPtr aParent ) ;
virtual ~ nsLoadListenerProxy ( ) ;
NS_DECL_ISUPPORTS
// nsIDOMEventListener
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHOD HandleEvent ( nsIDOMEvent * aEvent ) ;
2006-04-20 07:36:54 +04:00
// nsIDOMLoadListener
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHOD Load ( nsIDOMEvent * aEvent ) ;
NS_IMETHOD Unload ( nsIDOMEvent * aEvent ) ;
NS_IMETHOD Abort ( nsIDOMEvent * aEvent ) ;
NS_IMETHOD Error ( nsIDOMEvent * aEvent ) ;
2006-04-20 07:36:54 +04:00
protected :
nsWeakPtr mParent ;
} ;
nsLoadListenerProxy : : nsLoadListenerProxy ( nsWeakPtr aParent )
{
NS_INIT_ISUPPORTS ( ) ;
mParent = aParent ;
}
nsLoadListenerProxy : : ~ nsLoadListenerProxy ( )
{
}
NS_IMPL_ISUPPORTS1 ( nsLoadListenerProxy , nsIDOMLoadListener )
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHODIMP
2006-04-20 07:36:54 +04:00
nsLoadListenerProxy : : HandleEvent ( nsIDOMEvent * aEvent )
{
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMLoadListener > listener ( do_QueryReferent ( mParent ) ) ;
2006-04-20 07:36:54 +04:00
if ( listener ) {
return listener - > HandleEvent ( aEvent ) ;
}
return NS_OK ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHODIMP
2006-04-20 07:36:54 +04:00
nsLoadListenerProxy : : Load ( nsIDOMEvent * aEvent )
{
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMLoadListener > listener ( do_QueryReferent ( mParent ) ) ;
2006-04-20 07:36:54 +04:00
if ( listener ) {
return listener - > Load ( aEvent ) ;
}
return NS_OK ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHODIMP
2006-04-20 07:36:54 +04:00
nsLoadListenerProxy : : Unload ( nsIDOMEvent * aEvent )
{
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMLoadListener > listener ( do_QueryReferent ( mParent ) ) ;
2006-04-20 07:36:54 +04:00
if ( listener ) {
return listener - > Unload ( aEvent ) ;
}
return NS_OK ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHODIMP
2006-04-20 07:36:54 +04:00
nsLoadListenerProxy : : Abort ( nsIDOMEvent * aEvent )
{
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMLoadListener > listener ( do_QueryReferent ( mParent ) ) ;
2006-04-20 07:36:54 +04:00
if ( listener ) {
return listener - > Abort ( aEvent ) ;
}
return NS_OK ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMETHODIMP
2006-04-20 07:36:54 +04:00
nsLoadListenerProxy : : Error ( nsIDOMEvent * aEvent )
{
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMLoadListener > listener ( do_QueryReferent ( mParent ) ) ;
2006-04-20 07:36:54 +04:00
if ( listener ) {
return listener - > Error ( aEvent ) ;
}
return NS_OK ;
}
2006-04-20 07:36:50 +04:00
/////////////////////////////////////////////
//
//
/////////////////////////////////////////////
nsXMLHttpRequest : : nsXMLHttpRequest ( )
{
NS_INIT_ISUPPORTS ( ) ;
2006-04-20 07:36:54 +04:00
mStatus = XML_HTTP_REQUEST_INITIALIZED ;
2006-04-20 07:36:51 +04:00
mAsync = PR_TRUE ;
2006-04-20 07:36:50 +04:00
}
nsXMLHttpRequest : : ~ nsXMLHttpRequest ( )
{
2006-04-20 07:36:54 +04:00
if ( XML_HTTP_REQUEST_SENT = = mStatus ) {
Abort ( ) ;
}
# ifdef IMPLEMENT_SYNC_LOAD
2006-04-20 07:37:11 +04:00
if ( mChromeWindow ) {
mChromeWindow - > ExitModalEventLoop ( NS_OK ) ;
2006-04-20 07:36:54 +04:00
}
# endif
2006-04-20 07:36:50 +04:00
}
2006-04-20 07:36:54 +04:00
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
// XPConnect interface list for nsXMLHttpRequest
NS_CLASSINFO_MAP_BEGIN ( XMLHttpRequest )
NS_CLASSINFO_MAP_ENTRY ( nsIXMLHttpRequest )
NS_CLASSINFO_MAP_ENTRY ( nsIDOMEventTarget )
NS_CLASSINFO_MAP_END
// QueryInterface implementation for nsXMLHttpRequest
2006-04-20 07:36:54 +04:00
NS_INTERFACE_MAP_BEGIN ( nsXMLHttpRequest )
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS ( nsISupports , nsIXMLHttpRequest )
NS_INTERFACE_MAP_ENTRY ( nsIXMLHttpRequest )
NS_INTERFACE_MAP_ENTRY ( nsIDOMLoadListener )
NS_INTERFACE_MAP_ENTRY ( nsIDOMEventTarget )
NS_INTERFACE_MAP_ENTRY ( nsISecurityCheckedComponent )
NS_INTERFACE_MAP_ENTRY ( nsIRequestObserver )
NS_INTERFACE_MAP_ENTRY ( nsIStreamListener )
NS_INTERFACE_MAP_ENTRY ( nsISupportsWeakReference )
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO ( XMLHttpRequest )
2006-04-20 07:36:54 +04:00
NS_INTERFACE_MAP_END
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
NS_IMPL_ADDREF ( nsXMLHttpRequest )
NS_IMPL_RELEASE ( nsXMLHttpRequest )
/* void addEventListener (in string type, in nsIDOMEventListener listener); */
NS_IMETHODIMP
nsXMLHttpRequest : : AddEventListener ( const nsAReadableString & type ,
nsIDOMEventListener * listener ,
PRBool useCapture )
2006-04-20 07:36:50 +04:00
{
NS_ENSURE_ARG ( listener ) ;
nsresult rv ;
// I know, I know - strcmp's. But it's only for a couple of
// cases...and they are short strings. :-)
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
if ( type . Equals ( LOADSTR ) ) {
2006-04-20 07:36:50 +04:00
if ( ! mLoadEventListeners ) {
rv = NS_NewISupportsArray ( getter_AddRefs ( mLoadEventListeners ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
}
mLoadEventListeners - > AppendElement ( listener ) ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
else if ( type . Equals ( ERRORSTR ) ) {
2006-04-20 07:36:50 +04:00
if ( ! mErrorEventListeners ) {
rv = NS_NewISupportsArray ( getter_AddRefs ( mErrorEventListeners ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
}
mErrorEventListeners - > AppendElement ( listener ) ;
}
else {
return NS_ERROR_INVALID_ARG ;
}
return NS_OK ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
/* void removeEventListener (in string type, in nsIDOMEventListener listener); */
2006-04-20 07:36:50 +04:00
NS_IMETHODIMP
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
nsXMLHttpRequest : : RemoveEventListener ( const nsAReadableString & type ,
nsIDOMEventListener * listener ,
PRBool useCapture )
2006-04-20 07:36:50 +04:00
{
NS_ENSURE_ARG ( listener ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
if ( type . Equals ( LOADSTR ) ) {
2006-04-20 07:36:50 +04:00
if ( mLoadEventListeners ) {
mLoadEventListeners - > RemoveElement ( listener ) ;
}
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
else if ( type . Equals ( ERRORSTR ) ) {
2006-04-20 07:36:50 +04:00
if ( mErrorEventListeners ) {
mErrorEventListeners - > RemoveElement ( listener ) ;
}
}
else {
return NS_ERROR_INVALID_ARG ;
}
return NS_OK ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
/* void dispatchEvent (in nsIDOMEvent evt); */
NS_IMETHODIMP
nsXMLHttpRequest : : DispatchEvent ( nsIDOMEvent * evt )
{
// Ignored
return NS_OK ;
}
2006-04-20 07:36:50 +04:00
nsresult
nsXMLHttpRequest : : MakeScriptEventListener ( nsISupports * aObject ,
nsIDOMEventListener * * aListener )
{
nsresult rv ;
* aListener = nsnull ;
nsCOMPtr < nsIXPCNativeCallContext > cc ;
NS_WITH_SERVICE ( nsIXPConnect , xpc , nsIXPConnect : : GetCID ( ) , & rv ) ;
if ( NS_SUCCEEDED ( rv ) ) {
rv = xpc - > GetCurrentNativeCallContext ( getter_AddRefs ( cc ) ) ;
}
if ( NS_SUCCEEDED ( rv ) & & cc ) {
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIXPConnectJSObjectHolder > jsobjholder ( do_QueryInterface ( aObject ) ) ;
2006-04-20 07:36:50 +04:00
if ( jsobjholder ) {
JSObject * funobj ;
rv = jsobjholder - > GetJSObject ( & funobj ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
JSContext * cx ;
rv = cc - > GetJSContext ( & cx ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
JSFunction * fun = JS_ValueToFunction ( cx , OBJECT_TO_JSVAL ( funobj ) ) ;
if ( ! fun ) {
return NS_ERROR_INVALID_ARG ;
}
nsCOMPtr < nsIXPConnectWrappedNative > wrapper ;
rv = cc - > GetCalleeWrapper ( getter_AddRefs ( wrapper ) ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
JSObject * scopeobj ;
rv = wrapper - > GetJSObject ( & scopeobj ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
nsXMLHttpRequestScriptListener * listener = new nsXMLHttpRequestScriptListener ( scopeobj , funobj ) ;
if ( ! listener ) {
return NS_ERROR_OUT_OF_MEMORY ;
}
* aListener = listener ;
NS_ADDREF ( * aListener ) ;
}
}
return NS_OK ;
}
static PRBool
CheckForScriptListener ( nsISupports * aElement , void * aData )
{
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIPrivateJSEventListener > jsel ( do_QueryInterface ( aElement ) ) ;
2006-04-20 07:36:50 +04:00
if ( jsel ) {
nsIDOMEventListener * * retval = ( nsIDOMEventListener * * ) aData ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
2006-04-20 07:36:50 +04:00
aElement - > QueryInterface ( NS_GET_IID ( nsIDOMEventListener ) , ( void * * ) retval ) ;
return PR_FALSE ;
}
return PR_TRUE ;
}
void
nsXMLHttpRequest : : GetScriptEventListener ( nsISupportsArray * aList ,
nsIDOMEventListener * * aListener )
{
aList - > EnumerateForwards ( CheckForScriptListener , ( void * ) aListener ) ;
}
PRBool
nsXMLHttpRequest : : StuffReturnValue ( nsIDOMEventListener * aListener )
{
nsresult rv ;
nsCOMPtr < nsIXPCNativeCallContext > cc ;
NS_WITH_SERVICE ( nsIXPConnect , xpc , nsIXPConnect : : GetCID ( ) , & rv ) ;
if ( NS_SUCCEEDED ( rv ) ) {
rv = xpc - > GetCurrentNativeCallContext ( getter_AddRefs ( cc ) ) ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
2006-04-20 07:36:50 +04:00
// If we're being called through JS, stuff the return value
if ( NS_SUCCEEDED ( rv ) & & cc ) {
jsval * val ;
rv = cc - > GetRetValPtr ( & val ) ;
if ( NS_SUCCEEDED ( rv ) ) {
JSObject * obj ;
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIPrivateJSEventListener > jsel ( do_QueryInterface ( aListener ) ) ;
2006-04-20 07:36:50 +04:00
if ( jsel ) {
jsel - > GetFunctionObj ( & obj ) ;
* val = OBJECT_TO_JSVAL ( obj ) ;
2006-04-20 07:36:55 +04:00
cc - > SetReturnValueWasSet ( JS_TRUE ) ;
2006-04-20 07:36:50 +04:00
return PR_TRUE ;
}
}
}
return PR_FALSE ;
}
/* attribute nsIDOMEventListener onload; */
NS_IMETHODIMP
nsXMLHttpRequest : : GetOnload ( nsISupports * * aOnLoad )
{
NS_ENSURE_ARG_POINTER ( aOnLoad ) ;
* aOnLoad = nsnull ;
if ( mLoadEventListeners ) {
nsCOMPtr < nsIDOMEventListener > listener ;
GetScriptEventListener ( mLoadEventListeners , getter_AddRefs ( listener ) ) ;
if ( listener ) {
StuffReturnValue ( listener ) ;
}
}
return NS_OK ;
}
NS_IMETHODIMP
nsXMLHttpRequest : : SetOnload ( nsISupports * aOnLoad )
{
NS_ENSURE_ARG ( aOnLoad ) ;
nsresult rv ;
nsCOMPtr < nsIDOMEventListener > listener ;
rv = MakeScriptEventListener ( aOnLoad , getter_AddRefs ( listener ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
if ( listener ) {
nsCOMPtr < nsIDOMEventListener > oldListener ;
// Remove any old script event listener that exists since
// we can only have one
if ( mLoadEventListeners ) {
GetScriptEventListener ( mLoadEventListeners , getter_AddRefs ( oldListener ) ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
RemoveEventListener ( LOADSTR , oldListener , PR_TRUE ) ;
2006-04-20 07:36:50 +04:00
}
}
else {
// If it's not a script event listener, try to directly QI it to
// an actual event listener
listener = do_QueryInterface ( aOnLoad ) ;
if ( ! listener ) {
return NS_ERROR_INVALID_ARG ;
}
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
return AddEventListener ( LOADSTR , listener , PR_TRUE ) ;
2006-04-20 07:36:50 +04:00
}
/* attribute nsIDOMEventListener onerror; */
NS_IMETHODIMP
nsXMLHttpRequest : : GetOnerror ( nsISupports * * aOnerror )
{
NS_ENSURE_ARG_POINTER ( aOnerror ) ;
* aOnerror = nsnull ;
if ( mErrorEventListeners ) {
nsCOMPtr < nsIDOMEventListener > listener ;
GetScriptEventListener ( mErrorEventListeners , getter_AddRefs ( listener ) ) ;
if ( listener ) {
StuffReturnValue ( listener ) ;
}
}
return NS_OK ;
}
NS_IMETHODIMP
nsXMLHttpRequest : : SetOnerror ( nsISupports * aOnerror )
{
NS_ENSURE_ARG ( aOnerror ) ;
nsresult rv ;
nsCOMPtr < nsIDOMEventListener > listener ;
rv = MakeScriptEventListener ( aOnerror , getter_AddRefs ( listener ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
if ( listener ) {
nsCOMPtr < nsIDOMEventListener > oldListener ;
// Remove any old script event listener that exists since
// we can only have one
if ( mErrorEventListeners ) {
GetScriptEventListener ( mErrorEventListeners ,
getter_AddRefs ( oldListener ) ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
RemoveEventListener ( ERRORSTR , oldListener , PR_TRUE ) ;
2006-04-20 07:36:50 +04:00
}
}
else {
// If it's not a script event listener, try to directly QI it to
// an actual event listener
listener = do_QueryInterface ( aOnerror ) ;
if ( ! listener ) {
return NS_ERROR_INVALID_ARG ;
}
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
return AddEventListener ( ERRORSTR , listener , PR_TRUE ) ;
2006-04-20 07:36:50 +04:00
}
2006-04-20 07:37:18 +04:00
/* readonly attribute nsIHttpChannel channel; */
NS_IMETHODIMP nsXMLHttpRequest : : GetChannel ( nsIHttpChannel * * aChannel )
2006-04-20 07:37:01 +04:00
{
NS_ENSURE_ARG_POINTER ( aChannel ) ;
* aChannel = mChannel ;
NS_IF_ADDREF ( * aChannel ) ;
return NS_OK ;
}
2006-04-20 07:36:50 +04:00
/* readonly attribute nsIDOMDocument responseXML; */
NS_IMETHODIMP nsXMLHttpRequest : : GetResponseXML ( nsIDOMDocument * * aResponseXML )
{
NS_ENSURE_ARG_POINTER ( aResponseXML ) ;
* aResponseXML = nsnull ;
2006-04-20 07:36:54 +04:00
if ( ( XML_HTTP_REQUEST_COMPLETED = = mStatus ) & & mDocument ) {
2006-04-20 07:36:50 +04:00
* aResponseXML = mDocument ;
NS_ADDREF ( * aResponseXML ) ;
}
return NS_OK ;
}
2006-04-20 07:37:08 +04:00
/*
* This piece copied from nsXMLDocument , we try to get the charset
* from HTTP headers .
*/
nsresult
nsXMLHttpRequest : : DetectCharset ( nsAWritableString & aCharset )
{
aCharset . Truncate ( ) ;
nsresult rv ;
2006-04-20 07:37:18 +04:00
nsCOMPtr < nsIHttpChannel > httpChannel ( do_QueryInterface ( mChannel , & rv ) ) ;
2006-04-20 07:37:08 +04:00
if ( httpChannel ) {
nsXPIDLCString contenttypeheader ;
2006-04-20 07:37:18 +04:00
rv = httpChannel - > GetResponseHeader ( " content-type " , getter_Copies ( contenttypeheader ) ) ;
2006-04-20 07:37:08 +04:00
if ( NS_SUCCEEDED ( rv ) ) {
nsAutoString contentType ;
2006-04-20 07:37:22 +04:00
contentType . AssignWithConversion ( contenttypeheader . get ( ) ) ;
2006-04-20 07:37:08 +04:00
PRInt32 start = contentType . RFind ( " charset= " , PR_TRUE ) ;
if ( start < 0 ) {
start + = 8 ; // 8 = "charset=".length
PRInt32 end = 0 ;
if ( PRUnichar ( ' " ' ) = = contentType . CharAt ( start ) ) {
start + + ;
end = contentType . FindCharInSet ( " \" " , start ) ;
if ( end < 0 )
end = contentType . Length ( ) ;
} else {
end = contentType . FindCharInSet ( " ; \n \r " , start ) ;
if ( end < 0 )
end = contentType . Length ( ) ;
}
nsAutoString theCharset ;
contentType . Mid ( theCharset , start , end - start ) ;
nsCOMPtr < nsICharsetAlias > calias ( do_GetService ( kCharsetAliasCID , & rv ) ) ;
if ( NS_SUCCEEDED ( rv ) & & calias ) {
nsAutoString preferred ;
rv = calias - > GetPreferred ( theCharset , preferred ) ;
if ( NS_SUCCEEDED ( rv ) ) {
aCharset . Assign ( preferred ) ;
}
}
}
}
}
return rv ;
}
nsresult
nsXMLHttpRequest : : ConvertBodyToText ( PRUnichar * * aOutBuffer )
{
* aOutBuffer = nsnull ;
2006-04-20 07:37:22 +04:00
PRInt32 dataLen = mResponseBody . Length ( ) ;
2006-04-20 07:37:08 +04:00
if ( ! dataLen )
return NS_OK ;
nsresult rv = NS_OK ;
nsAutoString dataCharset ;
nsCOMPtr < nsIDocument > document ( do_QueryInterface ( mDocument ) ) ;
if ( document ) {
rv = document - > GetDocumentCharacterSet ( dataCharset ) ;
if ( NS_FAILED ( rv ) )
return rv ;
} else {
if ( NS_FAILED ( DetectCharset ( dataCharset ) ) | | dataCharset . IsEmpty ( ) ) {
dataCharset . Assign ( NS_LITERAL_STRING ( " ISO-8859-1 " ) ) ; // Parser assumes ISO-8859-1
}
}
if ( dataCharset . Equals ( NS_LITERAL_STRING ( " ASCII " ) ) ) {
// XXX There is no ASCII->Unicode decoder?
// XXX How to do this without double allocation/copy?
2006-04-20 07:37:22 +04:00
* aOutBuffer = NS_ConvertASCIItoUCS2 ( mResponseBody . get ( ) , dataLen ) . ToNewUnicode ( ) ;
2006-04-20 07:37:08 +04:00
if ( ! * aOutBuffer )
return NS_ERROR_OUT_OF_MEMORY ;
return NS_OK ;
}
nsCOMPtr < nsICharsetConverterManager > ccm ( do_GetService ( NS_CHARSETCONVERTERMANAGER_CONTRACTID , & rv ) ) ;
if ( NS_FAILED ( rv ) )
return rv ;
nsCOMPtr < nsIUnicodeDecoder > decoder ;
rv = ccm - > GetUnicodeDecoder ( & dataCharset , getter_AddRefs ( decoder ) ) ;
if ( NS_FAILED ( rv ) )
return rv ;
// This loop here is basically a copy of a similar thing in nsScanner.
// It will exit on first iteration in normal cases, but if we get illegal
// characters in the input we replace them and then continue.
2006-04-20 07:37:22 +04:00
const char * inBuffer = mResponseBody . get ( ) ;
2006-04-20 07:37:08 +04:00
PRUnichar * outBuffer = nsnull ;
PRInt32 outBufferIndex = 0 , inBufferLength = dataLen ;
PRInt32 outLen ;
for ( ; ; ) {
rv = decoder - > GetMaxLength ( inBuffer , inBufferLength , & outLen ) ;
if ( NS_FAILED ( rv ) )
return rv ;
PRUnichar * newOutBuffer = NS_STATIC_CAST ( PRUnichar * , nsMemory : : Realloc ( outBuffer , ( outLen + outBufferIndex + 1 ) * sizeof ( PRUnichar ) ) ) ;
if ( ! newOutBuffer ) {
nsMemory : : Free ( outBuffer ) ;
return NS_ERROR_OUT_OF_MEMORY ;
}
outBuffer = newOutBuffer ;
rv = decoder - > Convert ( inBuffer , & inBufferLength , & outBuffer [ outBufferIndex ] , & outLen ) ;
if ( rv = = NS_OK ) {
break ;
} else if ( rv = = NS_ERROR_ILLEGAL_INPUT ) {
// We consume one byte, replace it with U+FFFD
// and try the conversion again.
outBuffer [ outBufferIndex + outLen ] = ( PRUnichar ) 0xFFFD ;
outLen + + ;
outBufferIndex + = outLen ;
inBuffer = & inBuffer [ outLen ] ;
inBufferLength - = outLen ;
} else if ( NS_FAILED ( rv ) ) {
nsMemory : : Free ( outBuffer ) ;
return rv ; // We bail out on other critical errors
} else /*if (rv != NS_OK)*/ {
NS_ABORT_IF_FALSE ( 0 , " This should not happen, nsIUnicodeDecoder::Convert() succeeded partially " ) ;
nsMemory : : Free ( outBuffer ) ;
return NS_ERROR_FAILURE ;
}
}
outBuffer [ outBufferIndex + outLen ] = ' \0 ' ;
* aOutBuffer = outBuffer ;
return NS_OK ;
}
/* readonly attribute wstring responseText; */
NS_IMETHODIMP nsXMLHttpRequest : : GetResponseText ( PRUnichar * * aResponseText )
{
NS_ENSURE_ARG_POINTER ( aResponseText ) ;
* aResponseText = nsnull ;
if ( ( XML_HTTP_REQUEST_COMPLETED = = mStatus ) ) {
2006-04-20 07:37:22 +04:00
// First check if we can represent the data as a string - if it contains
// nulls we won't try.
if ( mResponseBody . FindChar ( ' \0 ' ) > = 0 )
2006-04-20 07:37:08 +04:00
return NS_ERROR_FAILURE ;
nsresult rv = ConvertBodyToText ( aResponseText ) ;
if ( NS_FAILED ( rv ) )
return rv ;
}
return NS_OK ;
}
2006-04-20 07:36:50 +04:00
/* readonly attribute unsigned long status; */
NS_IMETHODIMP
nsXMLHttpRequest : : GetStatus ( PRUint32 * aStatus )
{
if ( mChannel ) {
return mChannel - > GetResponseStatus ( aStatus ) ;
}
return NS_OK ;
}
/* readonly attribute string statusText; */
NS_IMETHODIMP
nsXMLHttpRequest : : GetStatusText ( char * * aStatusText )
{
2006-04-20 07:36:55 +04:00
NS_ENSURE_ARG_POINTER ( aStatusText ) ;
* aStatusText = nsnull ;
2006-04-20 07:36:50 +04:00
if ( mChannel ) {
2006-04-20 07:37:18 +04:00
return mChannel - > GetResponseStatusText ( aStatusText ) ;
2006-04-20 07:36:50 +04:00
}
return NS_OK ;
}
/* void abort (); */
NS_IMETHODIMP
nsXMLHttpRequest : : Abort ( )
{
2006-04-20 07:37:07 +04:00
if ( mReadRequest ) {
return mReadRequest - > Cancel ( NS_BINDING_ABORTED ) ;
2006-04-20 07:36:50 +04:00
}
return NS_OK ;
}
/* string getAllResponseHeaders (); */
NS_IMETHODIMP
nsXMLHttpRequest : : GetAllResponseHeaders ( char * * _retval )
{
NS_ENSURE_ARG_POINTER ( _retval ) ;
2006-04-20 07:36:55 +04:00
* _retval = nsnull ;
2006-04-20 07:36:50 +04:00
if ( mChannel ) {
2006-04-20 07:37:18 +04:00
nsHeaderVisitor * visitor = nsnull ;
NS_NEWXPCOM ( visitor , nsHeaderVisitor ) ;
if ( ! visitor )
return NS_ERROR_OUT_OF_MEMORY ;
NS_ADDREF ( visitor ) ;
2006-04-20 07:36:50 +04:00
2006-04-20 07:37:18 +04:00
nsresult rv = mChannel - > VisitResponseHeaders ( visitor ) ;
if ( NS_SUCCEEDED ( rv ) )
* _retval = ToNewCString ( visitor - > Headers ( ) ) ;
NS_RELEASE ( visitor ) ;
return rv ;
2006-04-20 07:36:50 +04:00
}
return NS_OK ;
}
/* string getResponseHeader (in string header); */
NS_IMETHODIMP
nsXMLHttpRequest : : GetResponseHeader ( const char * header , char * * _retval )
{
NS_ENSURE_ARG ( header ) ;
NS_ENSURE_ARG_POINTER ( _retval ) ;
2006-04-20 07:36:55 +04:00
* _retval = nsnull ;
2006-04-20 07:37:18 +04:00
if ( mChannel )
return mChannel - > GetResponseHeader ( header , _retval ) ;
2006-04-20 07:36:50 +04:00
return NS_OK ;
}
2006-04-20 07:36:55 +04:00
/* noscript void openRequest (in string method, in string url, in boolean async, in string user, in string password); */
2006-04-20 07:36:50 +04:00
NS_IMETHODIMP
nsXMLHttpRequest : : OpenRequest ( const char * method ,
2006-04-20 07:36:55 +04:00
const char * url ,
2006-04-20 07:36:50 +04:00
PRBool async ,
const char * user ,
const char * password )
{
NS_ENSURE_ARG ( method ) ;
NS_ENSURE_ARG ( url ) ;
nsresult rv ;
2006-04-20 07:36:51 +04:00
nsCOMPtr < nsIURI > uri ;
2006-04-20 07:36:50 +04:00
PRBool authp = PR_FALSE ;
2006-04-20 07:37:22 +04:00
// Return error if we're already processing a request
2006-04-20 07:36:54 +04:00
if ( XML_HTTP_REQUEST_SENT = = mStatus ) {
return NS_ERROR_FAILURE ;
}
2006-04-20 07:36:50 +04:00
mAsync = async ;
2006-04-20 07:36:55 +04:00
rv = NS_NewURI ( getter_AddRefs ( uri ) , url , mBaseURI ) ;
2006-04-20 07:36:50 +04:00
if ( NS_FAILED ( rv ) ) return rv ;
// Only http URLs are allowed
2006-04-20 07:37:09 +04:00
// The following check takes the place of nsScriptSecurityManager::CheckLoadURI
// since loads of http URLs are always allowed.
2006-04-20 07:37:02 +04:00
PRBool isHTTP = PR_FALSE ;
2006-04-20 07:37:12 +04:00
uri - > SchemeIs ( " http " , & isHTTP ) ;
2006-04-20 07:37:02 +04:00
if ( ! isHTTP )
return NS_ERROR_INVALID_ARG ;
2006-04-20 07:36:50 +04:00
if ( user ) {
nsCAutoString prehost ;
prehost . Assign ( user ) ;
if ( password ) {
prehost . Append ( " : " ) ;
prehost . Append ( password ) ;
}
2006-04-20 07:37:10 +04:00
uri - > SetPreHost ( prehost . get ( ) ) ;
2006-04-20 07:36:50 +04:00
authp = PR_TRUE ;
}
nsCOMPtr < nsIChannel > channel ;
2006-04-20 07:37:22 +04:00
rv = NS_OpenURI ( getter_AddRefs ( channel ) , uri , nsnull , nsnull ) ;
2006-04-20 07:36:50 +04:00
if ( NS_FAILED ( rv ) ) return rv ;
mChannel = do_QueryInterface ( channel ) ;
if ( ! mChannel ) {
return NS_ERROR_INVALID_ARG ;
}
2006-04-20 07:37:18 +04:00
//mChannel->SetAuthTriedWithPrehost(authp);
2006-04-20 07:36:51 +04:00
2006-04-20 07:37:18 +04:00
rv = mChannel - > SetRequestMethod ( method ) ;
2006-04-20 07:36:54 +04:00
mStatus = XML_HTTP_REQUEST_OPENED ;
2006-04-20 07:36:50 +04:00
return rv ;
}
2006-04-20 07:36:55 +04:00
/* void open (in string method, in string url); */
2006-04-20 07:36:50 +04:00
NS_IMETHODIMP
2006-04-20 07:36:55 +04:00
nsXMLHttpRequest : : Open ( const char * method , const char * url )
2006-04-20 07:36:50 +04:00
{
nsresult rv ;
PRBool async = PR_TRUE ;
char * user = nsnull ;
char * password = nsnull ;
nsCOMPtr < nsIXPCNativeCallContext > cc ;
NS_WITH_SERVICE ( nsIXPConnect , xpc , nsIXPConnect : : GetCID ( ) , & rv ) ;
if ( NS_SUCCEEDED ( rv ) ) {
rv = xpc - > GetCurrentNativeCallContext ( getter_AddRefs ( cc ) ) ;
}
if ( NS_SUCCEEDED ( rv ) & & cc ) {
PRUint32 argc ;
rv = cc - > GetArgc ( & argc ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
jsval * argv ;
rv = cc - > GetArgvPtr ( & argv ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
2006-04-20 07:36:50 +04:00
JSContext * cx ;
rv = cc - > GetJSContext ( & cx ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:36:51 +04:00
NS_WITH_SERVICE ( nsIScriptSecurityManager , secMan ,
2006-04-20 07:37:00 +04:00
NS_SCRIPTSECURITYMANAGER_CONTRACTID , & rv ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:37:21 +04:00
2006-04-20 07:37:22 +04:00
nsCOMPtr < nsIPrincipal > principal ;
rv = secMan - > GetSubjectPrincipal ( getter_AddRefs ( principal ) ) ;
if ( NS_SUCCEEDED ( rv ) ) {
nsCOMPtr < nsICodebasePrincipal > codebase = do_QueryInterface ( principal ) ;
if ( codebase ) {
codebase - > GetURI ( getter_AddRefs ( mBaseURI ) ) ;
}
}
2006-04-20 07:37:21 +04:00
nsCOMPtr < nsIURI > targetURI ;
2006-04-20 07:37:22 +04:00
rv = NS_NewURI ( getter_AddRefs ( targetURI ) , url , mBaseURI ) ;
2006-04-20 07:37:21 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
rv = secMan - > CheckConnect ( cx , targetURI , " XMLHttpRequest " , " open " ) ;
if ( NS_FAILED ( rv ) )
{
// Security check failed. The above call set a JS exception. The
// following lines ensure that the exception is propagated.
NS_WITH_SERVICE ( nsIXPConnect , xpc , nsIXPConnect : : GetCID ( ) , & rv ) ;
nsCOMPtr < nsIXPCNativeCallContext > cc ;
if ( NS_SUCCEEDED ( rv ) )
xpc - > GetCurrentNativeCallContext ( getter_AddRefs ( cc ) ) ;
if ( cc )
cc - > SetExceptionWasThrown ( PR_TRUE ) ;
return NS_OK ;
}
2006-04-20 07:36:50 +04:00
if ( argc > 2 ) {
2006-04-20 07:36:52 +04:00
JSBool asyncBool ;
JS_ValueToBoolean ( cx , argv [ 2 ] , & asyncBool ) ;
async = ( PRBool ) asyncBool ;
2006-04-20 07:36:50 +04:00
if ( argc > 3 ) {
JSString * userStr ;
userStr = JS_ValueToString ( cx , argv [ 3 ] ) ;
if ( userStr ) {
user = JS_GetStringBytes ( userStr ) ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
2006-04-20 07:36:50 +04:00
if ( argc > 4 ) {
JSString * passwordStr ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2006-04-20 07:37:17 +04:00
2006-04-20 07:36:50 +04:00
passwordStr = JS_ValueToString ( cx , argv [ 4 ] ) ;
if ( passwordStr ) {
password = JS_GetStringBytes ( passwordStr ) ;
}
}
}
}
}
return OpenRequest ( method , url , async , user , password ) ;
}
nsresult
nsXMLHttpRequest : : GetStreamForWString ( const PRUnichar * aStr ,
PRInt32 aLength ,
nsIInputStream * * aStream )
{
nsresult rv ;
nsCOMPtr < nsIUnicodeEncoder > encoder ;
nsAutoString charsetStr ;
char * postData ;
// We want to encode the string as utf-8, so get the right encoder
NS_WITH_SERVICE ( nsICharsetConverterManager ,
charsetConv ,
kCharsetConverterManagerCID ,
& rv ) ;
NS_ENSURE_SUCCESS ( rv , NS_ERROR_FAILURE ) ;
charsetStr . AssignWithConversion ( " UTF-8 " ) ;
rv = charsetConv - > GetUnicodeEncoder ( & charsetStr ,
getter_AddRefs ( encoder ) ) ;
NS_ENSURE_SUCCESS ( rv , NS_ERROR_FAILURE ) ;
// Convert to utf-8
PRInt32 charLength ;
const PRUnichar * unicodeBuf = aStr ;
PRInt32 unicodeLength = aLength ;
rv = encoder - > GetMaxLength ( unicodeBuf , unicodeLength , & charLength ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
# define MAX_HEADER_SIZE 128
// Allocate extra space for the header and trailing CRLF
postData = ( char * ) nsMemory : : Alloc ( MAX_HEADER_SIZE + charLength + 3 ) ;
if ( ! postData ) {
return NS_ERROR_OUT_OF_MEMORY ;
}
rv = encoder - > Convert ( unicodeBuf ,
& unicodeLength , postData + MAX_HEADER_SIZE , & charLength ) ;
if ( NS_FAILED ( rv ) ) {
nsMemory : : Free ( postData ) ;
return NS_ERROR_FAILURE ;
}
// Now that we know the real content length we can create the header
PR_snprintf ( postData ,
MAX_HEADER_SIZE ,
" Content-type: text/xml \015 \012 Content-Length: %d \015 \012 \015 \012 " ,
charLength ) ;
PRInt32 headerSize = nsCRT : : strlen ( postData ) ;
// Copy the post data to immediately follow the header
nsCRT : : memcpy ( postData + headerSize , postData + MAX_HEADER_SIZE , charLength ) ;
2006-04-20 07:37:22 +04:00
// Shove in the trailing CRLF
2006-04-20 07:37:14 +04:00
postData [ headerSize + charLength ] = nsCRT : : CR ;
postData [ headerSize + charLength + 1 ] = nsCRT : : LF ;
2006-04-20 07:36:50 +04:00
postData [ headerSize + charLength + 2 ] = ' \0 ' ;
// The new stream takes ownership of the buffer
rv = NS_NewByteArrayInputStream ( ( nsIByteArrayInputStream * * ) aStream ,
postData ,
headerSize + charLength + 2 ) ;
if ( NS_FAILED ( rv ) ) {
nsMemory : : Free ( postData ) ;
return NS_ERROR_FAILURE ;
}
return NS_OK ;
}
2006-04-20 07:37:08 +04:00
/*
2006-04-20 07:37:22 +04:00
* " Copy " from a stream .
2006-04-20 07:37:08 +04:00
*/
NS_METHOD
nsXMLHttpRequest : : StreamReaderFunc ( nsIInputStream * in ,
void * closure ,
const char * fromRawSegment ,
PRUint32 toOffset ,
PRUint32 count ,
PRUint32 * writeCount )
{
nsXMLHttpRequest * xmlHttpRequest = NS_STATIC_CAST ( nsXMLHttpRequest * , closure ) ;
2006-04-20 07:37:22 +04:00
if ( ! xmlHttpRequest | | ! writeCount ) {
NS_WARNING ( " XMLHttpRequest cannot read from stream: no closure or writeCount " ) ;
2006-04-20 07:37:08 +04:00
return NS_ERROR_FAILURE ;
}
// Copy for our own use
2006-04-20 07:37:22 +04:00
xmlHttpRequest - > mResponseBody . Append ( fromRawSegment , count ) ;
2006-04-20 07:37:08 +04:00
2006-04-20 07:37:22 +04:00
nsresult rv ;
// Give the same data to the parser.
// We need to wrap the data in a new lightweight stream and pass that
// to the parser, because calling ReadSegments() recursively on the same
// stream is not supported.
nsCOMPtr < nsISupports > supportsStream ;
rv = NS_NewByteInputStream ( getter_AddRefs ( supportsStream ) , fromRawSegment , count ) ;
if ( NS_SUCCEEDED ( rv ) ) {
nsCOMPtr < nsIInputStream > copyStream ( do_QueryInterface ( supportsStream ) ) ;
if ( copyStream ) {
rv = xmlHttpRequest - > mXMLParserStreamListener - > OnDataAvailable ( xmlHttpRequest - > mReadRequest , xmlHttpRequest - > mContext , copyStream , toOffset , count ) ;
} else {
NS_ERROR ( " NS_NewByteInputStream did not give out nsIInputStream! " ) ;
rv = NS_ERROR_UNEXPECTED ;
}
}
2006-04-20 07:37:08 +04:00
2006-04-20 07:37:22 +04:00
if ( NS_SUCCEEDED ( rv ) ) {
* writeCount = count ;
} else {
* writeCount = 0 ;
}
2006-04-20 07:37:08 +04:00
return rv ;
}
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
NS_IMETHODIMP
nsXMLHttpRequest : : OnDataAvailable ( nsIRequest * request , nsISupports * ctxt , nsIInputStream * inStr , PRUint32 sourceOffset , PRUint32 count )
{
2006-04-20 07:37:22 +04:00
NS_ENSURE_ARG_POINTER ( inStr ) ;
2006-04-20 07:37:08 +04:00
NS_ABORT_IF_FALSE ( mContext . get ( ) = = ctxt , " start context different from OnDataAvailable context " ) ;
PRUint32 totalRead ;
2006-04-20 07:37:22 +04:00
nsresult result = inStr - > ReadSegments ( nsXMLHttpRequest : : StreamReaderFunc , ( void * ) this , count , & totalRead ) ;
2006-04-20 07:37:08 +04:00
if ( NS_FAILED ( result ) ) {
mResponseBody . Truncate ( ) ;
}
return result ;
}
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
NS_IMETHODIMP
nsXMLHttpRequest : : OnStartRequest ( nsIRequest * request , nsISupports * ctxt )
{
mReadRequest = request ;
mContext = ctxt ;
return mXMLParserStreamListener - > OnStartRequest ( request , ctxt ) ;
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP
2006-04-20 07:37:13 +04:00
nsXMLHttpRequest : : OnStopRequest ( nsIRequest * request , nsISupports * ctxt , nsresult status )
2006-04-20 07:37:08 +04:00
{
2006-04-20 07:37:13 +04:00
nsresult rv = mXMLParserStreamListener - > OnStopRequest ( request , ctxt , status ) ;
2006-04-20 07:37:08 +04:00
mXMLParserStreamListener = nsnull ;
mReadRequest = nsnull ;
mContext = nsnull ;
return rv ;
}
2006-04-20 07:36:50 +04:00
/* void send (in nsISupports body); */
NS_IMETHODIMP
nsXMLHttpRequest : : Send ( nsISupports * body )
{
nsresult rv ;
2006-04-20 07:37:08 +04:00
// Return error if we're already processing a request
2006-04-20 07:36:54 +04:00
if ( XML_HTTP_REQUEST_SENT = = mStatus ) {
return NS_ERROR_FAILURE ;
}
// Make sure we've been opened
2006-04-20 07:36:50 +04:00
if ( ! mChannel ) {
return NS_ERROR_NOT_INITIALIZED ;
}
2006-04-20 07:37:22 +04:00
// Ignore argument if method is GET, there is no point in trying to upload anything
nsXPIDLCString method ;
mChannel - > GetRequestMethod ( getter_Copies ( method ) ) ; // If GET, method name will be uppercase
if ( body & & nsCRT : : strcmp ( " GET " , method . get ( ) ) ! = 0 ) {
nsCOMPtr < nsIInputStream > postDataStream ;
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMDocument > doc ( do_QueryInterface ( body ) ) ;
2006-04-20 07:36:51 +04:00
if ( doc ) {
// Get an XML serializer
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMSerializer > serializer ( do_CreateInstance ( NS_XMLSERIALIZER_CONTRACTID , & rv ) ) ;
2006-04-20 07:36:51 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
// Serialize the current document to string
nsXPIDLString serial ;
rv = serializer - > SerializeToString ( doc , getter_Copies ( serial ) ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
// Convert to a byte stream
2006-04-20 07:37:22 +04:00
rv = GetStreamForWString ( serial . get ( ) ,
nsCRT : : strlen ( serial . get ( ) ) ,
2006-04-20 07:36:51 +04:00
getter_AddRefs ( postDataStream ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
2006-04-20 07:36:50 +04:00
}
else {
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIInputStream > stream ( do_QueryInterface ( body ) ) ;
2006-04-20 07:36:51 +04:00
if ( stream ) {
postDataStream = stream ;
}
else {
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsISupportsWString > wstr ( do_QueryInterface ( body ) ) ;
2006-04-20 07:36:51 +04:00
if ( wstr ) {
nsXPIDLString holder ;
wstr - > GetData ( getter_Copies ( holder ) ) ;
2006-04-20 07:37:22 +04:00
rv = GetStreamForWString ( holder . get ( ) ,
nsCRT : : strlen ( holder . get ( ) ) ,
2006-04-20 07:36:51 +04:00
getter_AddRefs ( postDataStream ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
}
2006-04-20 07:36:50 +04:00
}
}
2006-04-20 07:36:51 +04:00
if ( postDataStream ) {
rv = mChannel - > SetUploadStream ( postDataStream ) ;
}
2006-04-20 07:36:50 +04:00
}
// Get and initialize a DOMImplementation
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMDOMImplementation > implementation ( do_CreateInstance ( kIDOMDOMImplementationCID , & rv ) ) ;
2006-04-20 07:36:50 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:36:51 +04:00
if ( mBaseURI ) {
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIPrivateDOMImplementation > privImpl ( do_QueryInterface ( implementation ) ) ;
2006-04-20 07:36:50 +04:00
if ( privImpl ) {
2006-04-20 07:36:51 +04:00
privImpl - > Init ( mBaseURI ) ;
2006-04-20 07:36:50 +04:00
}
}
2006-04-20 07:37:08 +04:00
// Create an empty document from it (resets current document as well)
2006-04-20 07:36:50 +04:00
nsAutoString emptyStr ;
rv = implementation - > CreateDocument ( emptyStr ,
emptyStr ,
nsnull ,
getter_AddRefs ( mDocument ) ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:37:08 +04:00
// Reset responseBody
mResponseBody . Truncate ( ) ;
2006-04-20 07:36:50 +04:00
// Register as a load listener on the document
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMEventReceiver > target ( do_QueryInterface ( mDocument ) ) ;
2006-04-20 07:36:50 +04:00
if ( target ) {
2006-04-20 07:37:08 +04:00
nsWeakPtr requestWeak ( getter_AddRefs ( NS_GetWeakReference ( NS_STATIC_CAST ( nsIXMLHttpRequest * , this ) ) ) ) ;
2006-04-20 07:36:56 +04:00
nsLoadListenerProxy * proxy = new nsLoadListenerProxy ( requestWeak ) ;
2006-04-20 07:36:54 +04:00
if ( ! proxy ) return NS_ERROR_OUT_OF_MEMORY ;
// This will addref the proxy
rv = target - > AddEventListenerByIID ( NS_STATIC_CAST ( nsIDOMEventListener * ,
proxy ) ,
NS_GET_IID ( nsIDOMLoadListener ) ) ;
2006-04-20 07:36:50 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
}
// Tell the document to start loading
nsCOMPtr < nsIStreamListener > listener ;
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDocument > document ( do_QueryInterface ( mDocument ) ) ;
2006-04-20 07:36:50 +04:00
if ( ! document ) {
return NS_ERROR_FAILURE ;
}
2006-04-20 07:36:54 +04:00
# ifdef IMPLEMENT_SYNC_LOAD
nsCOMPtr < nsIEventQueue > modalEventQueue ;
nsCOMPtr < nsIEventQueueService > eventQService ;
if ( ! mAsync ) {
nsCOMPtr < nsIXPCNativeCallContext > cc ;
NS_WITH_SERVICE ( nsIXPConnect , xpc , nsIXPConnect : : GetCID ( ) , & rv ) ;
if ( NS_SUCCEEDED ( rv ) ) {
rv = xpc - > GetCurrentNativeCallContext ( getter_AddRefs ( cc ) ) ;
}
if ( NS_SUCCEEDED ( rv ) & & cc ) {
JSContext * cx ;
rv = cc - > GetJSContext ( & cx ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
// We can only do this if we're called from a DOM script context
nsIScriptContext * scriptCX = ( nsIScriptContext * ) JS_GetContextPrivate ( cx ) ;
if ( ! scriptCX ) return NS_OK ;
// Get the nsIDocShellTreeOwner associated with the window
// containing this script context
// XXX Need to find a better way to do this rather than
// chaining through a bunch of getters and QIs
nsCOMPtr < nsIScriptGlobalObject > global ;
global = dont_AddRef ( scriptCX - > GetGlobalObject ( ) ) ;
if ( ! global ) return NS_ERROR_FAILURE ;
nsCOMPtr < nsIDocShell > docshell ;
rv = global - > GetDocShell ( getter_AddRefs ( docshell ) ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
nsCOMPtr < nsIDocShellTreeItem > item = do_QueryInterface ( docshell ) ;
if ( ! item ) return NS_ERROR_FAILURE ;
2006-04-20 07:37:11 +04:00
nsCOMPtr < nsIDocShellTreeOwner > treeOwner ;
rv = item - > GetTreeOwner ( getter_AddRefs ( treeOwner ) ) ;
2006-04-20 07:36:54 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:37:11 +04:00
nsCOMPtr < nsIInterfaceRequestor > treeRequestor ( do_GetInterface ( treeOwner ) ) ;
if ( ! treeRequestor ) return NS_ERROR_FAILURE ;
treeRequestor - > GetInterface ( NS_GET_IID ( nsIWebBrowserChrome ) , getter_AddRefs ( mChromeWindow ) ) ;
if ( ! mChromeWindow ) return NS_ERROR_FAILURE ;
2006-04-20 07:36:54 +04:00
eventQService = do_GetService ( kEventQueueServiceCID ) ;
if ( ! eventQService | |
NS_FAILED ( eventQService - > PushThreadEventQueue ( getter_AddRefs ( modalEventQueue ) ) ) ) {
return NS_ERROR_FAILURE ;
}
}
}
# endif
2006-04-20 07:36:50 +04:00
rv = document - > StartDocumentLoad ( kLoadAsData , mChannel ,
nsnull , nsnull ,
getter_AddRefs ( listener ) ,
PR_FALSE ) ;
2006-04-20 07:36:54 +04:00
# ifdef IMPLEMENT_SYNC_LOAD
if ( NS_FAILED ( rv ) ) {
if ( modalEventQueue ) {
eventQService - > PopThreadEventQueue ( modalEventQueue ) ;
}
return NS_ERROR_FAILURE ;
}
# else
2006-04-20 07:36:50 +04:00
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:36:54 +04:00
# endif
2006-04-20 07:36:50 +04:00
// Start reading from the channel
2006-04-20 07:36:54 +04:00
mStatus = XML_HTTP_REQUEST_SENT ;
2006-04-20 07:37:08 +04:00
mXMLParserStreamListener = listener ;
rv = mChannel - > AsyncOpen ( this , nsnull ) ;
2006-04-20 07:36:54 +04:00
# ifdef IMPLEMENT_SYNC_LOAD
if ( NS_FAILED ( rv ) ) {
if ( modalEventQueue ) {
eventQService - > PopThreadEventQueue ( modalEventQueue ) ;
}
return NS_ERROR_FAILURE ;
}
# else
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
# endif
# ifdef IMPLEMENT_SYNC_LOAD
// If we're synchronous, spin an event loop here and wait
2006-04-20 07:37:11 +04:00
if ( ! mAsync & & mChromeWindow ) {
rv = mChromeWindow - > ShowAsModal ( ) ;
2006-04-20 07:36:54 +04:00
eventQService - > PopThreadEventQueue ( modalEventQueue ) ;
if ( NS_FAILED ( rv ) ) return NS_ERROR_FAILURE ;
2006-04-20 07:36:50 +04:00
}
2006-04-20 07:36:54 +04:00
# endif
2006-04-20 07:36:50 +04:00
2006-04-20 07:36:54 +04:00
return NS_OK ;
2006-04-20 07:36:50 +04:00
}
/* void setRequestHeader (in string header, in string value); */
NS_IMETHODIMP
nsXMLHttpRequest : : SetRequestHeader ( const char * header , const char * value )
{
2006-04-20 07:37:18 +04:00
if ( mChannel )
return mChannel - > SetRequestHeader ( header , value ) ;
2006-04-20 07:36:50 +04:00
return NS_OK ;
}
// nsIDOMEventListener
nsresult
nsXMLHttpRequest : : HandleEvent ( nsIDOMEvent * aEvent )
{
return NS_OK ;
}
// nsIDOMLoadListener
nsresult
nsXMLHttpRequest : : Load ( nsIDOMEvent * aEvent )
{
2006-04-20 07:36:54 +04:00
mStatus = XML_HTTP_REQUEST_COMPLETED ;
# ifdef IMPLEMENT_SYNC_LOAD
2006-04-20 07:37:11 +04:00
if ( mChromeWindow ) {
mChromeWindow - > ExitModalEventLoop ( NS_OK ) ;
mChromeWindow = 0 ;
2006-04-20 07:36:54 +04:00
}
# endif
2006-04-20 07:36:50 +04:00
if ( mLoadEventListeners ) {
PRUint32 index , count ;
mLoadEventListeners - > Count ( & count ) ;
for ( index = 0 ; index < count ; index + + ) {
nsCOMPtr < nsISupports > current = dont_AddRef ( mLoadEventListeners - > ElementAt ( index ) ) ;
if ( current ) {
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMEventListener > listener ( do_QueryInterface ( current ) ) ;
2006-04-20 07:36:50 +04:00
if ( listener ) {
listener - > HandleEvent ( aEvent ) ;
}
}
}
}
return NS_OK ;
}
nsresult
nsXMLHttpRequest : : Unload ( nsIDOMEvent * aEvent )
{
return NS_OK ;
}
nsresult
nsXMLHttpRequest : : Abort ( nsIDOMEvent * aEvent )
{
2006-04-20 07:36:54 +04:00
mStatus = XML_HTTP_REQUEST_ABORTED ;
# ifdef IMPLEMENT_SYNC_LOAD
2006-04-20 07:37:11 +04:00
if ( mChromeWindow ) {
mChromeWindow - > ExitModalEventLoop ( NS_OK ) ;
mChromeWindow = 0 ;
2006-04-20 07:36:54 +04:00
}
# endif
2006-04-20 07:36:50 +04:00
return NS_OK ;
}
nsresult
nsXMLHttpRequest : : Error ( nsIDOMEvent * aEvent )
{
2006-04-20 07:36:54 +04:00
mStatus = XML_HTTP_REQUEST_ABORTED ;
# ifdef IMPLEMENT_SYNC_LOAD
2006-04-20 07:37:11 +04:00
if ( mChromeWindow ) {
mChromeWindow - > ExitModalEventLoop ( NS_OK ) ;
mChromeWindow = 0 ;
2006-04-20 07:36:54 +04:00
}
# endif
2006-04-20 07:36:50 +04:00
if ( mErrorEventListeners ) {
PRUint32 index , count ;
mErrorEventListeners - > Count ( & count ) ;
for ( index = 0 ; index < count ; index + + ) {
nsCOMPtr < nsISupports > current = dont_AddRef ( mErrorEventListeners - > ElementAt ( index ) ) ;
if ( current ) {
2006-04-20 07:37:08 +04:00
nsCOMPtr < nsIDOMEventListener > listener ( do_QueryInterface ( current ) ) ;
2006-04-20 07:36:50 +04:00
if ( listener ) {
listener - > HandleEvent ( aEvent ) ;
}
}
}
}
return NS_OK ;
}
2006-04-20 07:36:53 +04:00
static const char * kAllAccess = " AllAccess " ;
/* string canCreateWrapper (in nsIIDPtr iid); */
NS_IMETHODIMP
nsXMLHttpRequest : : CanCreateWrapper ( const nsIID * iid , char * * _retval )
{
if ( iid - > Equals ( NS_GET_IID ( nsIXMLHttpRequest ) ) ) {
* _retval = nsCRT : : strdup ( kAllAccess ) ;
}
return NS_OK ;
}
/* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
NS_IMETHODIMP
nsXMLHttpRequest : : CanCallMethod ( const nsIID * iid , const PRUnichar * methodName , char * * _retval )
{
if ( iid - > Equals ( NS_GET_IID ( nsIXMLHttpRequest ) ) ) {
* _retval = nsCRT : : strdup ( kAllAccess ) ;
}
return NS_OK ;
}
/* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
NS_IMETHODIMP
nsXMLHttpRequest : : CanGetProperty ( const nsIID * iid , const PRUnichar * propertyName , char * * _retval )
{
if ( iid - > Equals ( NS_GET_IID ( nsIXMLHttpRequest ) ) ) {
* _retval = nsCRT : : strdup ( kAllAccess ) ;
}
return NS_OK ;
}
/* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
NS_IMETHODIMP
nsXMLHttpRequest : : CanSetProperty ( const nsIID * iid , const PRUnichar * propertyName , char * * _retval )
{
if ( iid - > Equals ( NS_GET_IID ( nsIXMLHttpRequest ) ) ) {
* _retval = nsCRT : : strdup ( kAllAccess ) ;
}
return NS_OK ;
}
2006-04-20 07:37:18 +04:00
NS_IMPL_ISUPPORTS1 ( nsXMLHttpRequest : : nsHeaderVisitor , nsIHttpHeaderVisitor )
NS_IMETHODIMP nsXMLHttpRequest : :
nsHeaderVisitor : : VisitHeader ( const char * header , const char * value )
{
mHeaders . Append ( header ) ;
mHeaders . Append ( " : " ) ;
mHeaders . Append ( value ) ;
mHeaders . Append ( ' \n ' ) ;
return NS_OK ;
}