Fix for bug 88078. XMLHttpRequest now accepts non-HTTP URIs as well. This is similar to IE behavior. r=heikki, sr=jst

This commit is contained in:
vidur%netscape.com 2006-04-20 03:37:29 +00:00
Родитель 41091979e8
Коммит 4ebdf54359
3 изменённых файлов: 67 добавлений и 56 удалений

Просмотреть файл

@ -24,20 +24,20 @@
interface nsIDOMDocument;
interface nsIDOMEventListener;
interface nsIHttpChannel;
interface nsIChannel;
[scriptable, uuid(b7215e70-4157-11d4-9a42-000064657374)]
interface nsIXMLHttpRequest : nsISupports {
/**
* The HTTP request uses an HTTP channel in order to perform the
* request. This attribute represents the HTTP channel used
* for the request. NULL if the HTTP channel has not yet been
* The request uses a channel in order to perform the
* request. This attribute represents the channel used
* for the request. NULL if the channel has not yet been
* created.
*/
readonly attribute nsIHttpChannel channel;
readonly attribute nsIChannel channel;
/**
* The response to the HTTP request is parsed as if it were a
* The response to the request is parsed as if it were a
* text/xml stream. This attributes represents the response as
* a DOM Document object. NULL if the request is unsuccessful or
* has not yet been sent.
@ -45,7 +45,7 @@ interface nsIXMLHttpRequest : nsISupports {
readonly attribute nsIDOMDocument responseXML;
/**
* The response to the HTTP request as text.
* The response to the request as text.
* NULL if the request is unsuccessful or
* has not yet been sent.
*/
@ -53,24 +53,25 @@ interface nsIXMLHttpRequest : nsISupports {
/**
* The status of the response to the HTTP request.
* The status of the response to the request for HTTP requests.
*/
readonly attribute unsigned long status;
/**
* The string representing the status of the response to the
* HTTP request.
* The string representing the status of the response for
* HTTP requests.
*/
readonly attribute string statusText;
/**
* If the HTTP request has been sent already, this method will
* If the request has been sent already, this method will
* abort the request.
*/
void abort();
/**
* Returns all of the HTTP response headers as a string string.
* Returns all of the response headers as a string for HTTP
* requests.
*
* @returns A string containing all of the response headers.
* NULL if the response has not yet been received.
@ -78,7 +79,8 @@ interface nsIXMLHttpRequest : nsISupports {
string getAllResponseHeaders();
/**
* Returns the text of the header with the specified name.
* Returns the text of the header with the specified name for
* HTTP requests.
*
* @param header The name of the header to retrieve
* @returns A string containing the text of the header specified.
@ -89,10 +91,11 @@ interface nsIXMLHttpRequest : nsISupports {
/**
* Native (non-script) method to initialize a request. Note that
* the HTTP request is not sent until the <code>send</code> method
* the request is not sent until the <code>send</code> method
* is invoked.
*
* @param method The HTTP method - either "POST" or "GET".
* @param method The HTTP method - either "POST" or "GET". Ignored
* if the URL is not a HTTP URL.
* @param url The URL to which to send the request.
* @param async Whether the request is synchronous or asynchronous
* i.e. whether send returns only after the response
@ -114,7 +117,8 @@ interface nsIXMLHttpRequest : nsISupports {
* description of <code>openRequest</code>, but the last
* 3 are optional.
*
* @param method The HTTP method - either "POST" or "GET".
* @param method The HTTP method - either "POST" or "GET". Ignored
* if the URL is not a HTTP URL.
* @param url The URL to which to send the request.
* @param async (optional) Whether the request is synchronous or
* asynchronous i.e. whether send returns only after
@ -130,7 +134,7 @@ interface nsIXMLHttpRequest : nsISupports {
void open(in string method, in string url);
/**
* Sends the HTTP request. If the request is asynchronous, returns
* Sends the request. If the request is asynchronous, returns
* immediately after sending the request. If it is synchronous
* returns only after the response has been received.
*
@ -146,7 +150,7 @@ interface nsIXMLHttpRequest : nsISupports {
void send(in nsISupports body);
/**
* Sets a HTTP request header.
* Sets a HTTP request header for HTTP requests.
*
* @param header The name of the header to set in the request.
* @param value The body of the header.

Просмотреть файл

@ -358,8 +358,8 @@ nsXMLHttpRequest::SetOnerror(nsIDOMEventListener * aOnerror)
return NS_OK;
}
/* readonly attribute nsIHttpChannel channel; */
NS_IMETHODIMP nsXMLHttpRequest::GetChannel(nsIHttpChannel **aChannel)
/* readonly attribute nsIChannel channel; */
NS_IMETHODIMP nsXMLHttpRequest::GetChannel(nsIChannel **aChannel)
{
NS_ENSURE_ARG_POINTER(aChannel);
*aChannel = mChannel;
@ -535,10 +535,13 @@ NS_IMETHODIMP nsXMLHttpRequest::GetResponseText(PRUnichar **aResponseText)
NS_IMETHODIMP
nsXMLHttpRequest::GetStatus(PRUint32 *aStatus)
{
if (mChannel) {
return mChannel->GetResponseStatus(aStatus);
}
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel) {
return httpChannel->GetResponseStatus(aStatus);
}
*aStatus = 0;
return NS_OK;
}
@ -547,10 +550,12 @@ NS_IMETHODIMP
nsXMLHttpRequest::GetStatusText(char * *aStatusText)
{
NS_ENSURE_ARG_POINTER(aStatusText);
*aStatusText = nsnull;
if (mChannel) {
return mChannel->GetResponseStatusText(aStatusText);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel) {
return httpChannel->GetResponseStatusText(aStatusText);
}
*aStatusText = nsnull;
return NS_OK;
}
@ -572,14 +577,15 @@ nsXMLHttpRequest::GetAllResponseHeaders(char **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
if (mChannel) {
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel) {
nsHeaderVisitor *visitor = nsnull;
NS_NEWXPCOM(visitor, nsHeaderVisitor);
if (!visitor)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(visitor);
nsresult rv = mChannel->VisitResponseHeaders(visitor);
nsresult rv = httpChannel->VisitResponseHeaders(visitor);
if (NS_SUCCEEDED(rv))
*_retval = ToNewCString(visitor->Headers());
@ -596,10 +602,11 @@ nsXMLHttpRequest::GetResponseHeader(const char *header, char **_retval)
{
NS_ENSURE_ARG(header);
NS_ENSURE_ARG_POINTER(_retval);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
*_retval = nsnull;
if (mChannel)
return mChannel->GetResponseHeader(header, _retval);
if (httpChannel)
return httpChannel->GetResponseHeader(header, _retval);
return NS_OK;
}
@ -629,14 +636,6 @@ nsXMLHttpRequest::OpenRequest(const char *method,
rv = NS_NewURI(getter_AddRefs(uri), url, mBaseURI);
if (NS_FAILED(rv)) return rv;
// Only http URLs are allowed
// The following check takes the place of nsScriptSecurityManager::CheckLoadURI
// since loads of http URLs are always allowed.
PRBool isHTTP = PR_FALSE;
uri->SchemeIs("http", &isHTTP);
if (!isHTTP)
return NS_ERROR_INVALID_ARG;
if (user) {
nsCAutoString prehost;
prehost.Assign(user);
@ -648,18 +647,15 @@ nsXMLHttpRequest::OpenRequest(const char *method,
authp = PR_TRUE;
}
nsCOMPtr<nsIChannel> channel;
rv = NS_OpenURI(getter_AddRefs(channel), uri, nsnull, nsnull);
rv = NS_OpenURI(getter_AddRefs(mChannel), uri, nsnull, nsnull);
if (NS_FAILED(rv)) return rv;
mChannel = do_QueryInterface(channel);
if (!mChannel) {
return NS_ERROR_INVALID_ARG;
}
//mChannel->SetAuthTriedWithPrehost(authp);
rv = mChannel->SetRequestMethod(method);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel) {
rv = httpChannel->SetRequestMethod(method);
}
mStatus = XML_HTTP_REQUEST_OPENED;
@ -794,16 +790,21 @@ nsXMLHttpRequest::GetStreamForWString(const PRUnichar* aStr,
nsMemory::Free(postData);
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (!httpChannel) {
return NS_ERROR_FAILURE;
}
// If no content type header was set by the client, we set it to text/xml.
nsXPIDLCString header;
if( NS_OK != mChannel->GetRequestHeader("Content-Type", getter_Copies(header)) )
mChannel->SetRequestHeader("Content-Type", "text/xml" );
if( NS_OK != httpChannel->GetRequestHeader("Content-Type", getter_Copies(header)) )
httpChannel->SetRequestHeader("Content-Type", "text/xml" );
// set the content length header
char charLengthBuf [32];
PR_snprintf(charLengthBuf, sizeof(charLengthBuf), "%d", charLength);
mChannel->SetRequestHeader("Content-Length", charLengthBuf );
httpChannel->SetRequestHeader("Content-Length", charLengthBuf );
// Shove in the trailing and leading CRLF
postData[0] = nsCRT::CR;
@ -928,9 +929,13 @@ nsXMLHttpRequest::Send(nsISupports *body)
// 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
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (body && nsCRT::strcmp("GET",method.get()) != 0) {
if (httpChannel) {
httpChannel->GetRequestMethod(getter_Copies(method)); // If GET, method name will be uppercase
}
if (body && httpChannel && nsCRT::strcmp("GET",method.get()) != 0) {
nsCOMPtr<nsIInputStream> postDataStream;
nsCOMPtr<nsIDOMDocument> doc(do_QueryInterface(body));
@ -969,7 +974,7 @@ nsXMLHttpRequest::Send(nsISupports *body)
}
if (postDataStream) {
rv = mChannel->SetUploadStream(postDataStream);
rv = httpChannel->SetUploadStream(postDataStream);
}
}
@ -1120,8 +1125,10 @@ nsXMLHttpRequest::Send(nsISupports *body)
NS_IMETHODIMP
nsXMLHttpRequest::SetRequestHeader(const char *header, const char *value)
{
if (mChannel)
return mChannel->SetRequestHeader(header, value);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel)
return httpChannel->SetRequestHeader(header, value);
return NS_OK;
}

Просмотреть файл

@ -104,7 +104,7 @@ protected:
PRUint32 *writeCount);
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<nsIHttpChannel> mChannel;
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIRequest> mReadRequest;
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIURI> mBaseURI;