зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 157133 "HTTP Interfaces need to be frozen" r=dougt sr=bzbarsky
This commit is contained in:
Родитель
becf310cdd
Коммит
d9541f875d
|
@ -398,9 +398,8 @@ nsScriptLoader::ProcessScriptElement(nsIDOMHTMLScriptElement *aElement,
|
|||
if (httpChannel) {
|
||||
// HTTP content negotation has little value in this context.
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("*/*"));
|
||||
NS_LITERAL_CSTRING("*/*"),
|
||||
PR_FALSE);
|
||||
httpChannel->SetReferrer(documentURI);
|
||||
}
|
||||
rv = NS_NewStreamLoader(getter_AddRefs(loader), channel, this, reqsup);
|
||||
|
|
|
@ -5319,7 +5319,8 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
|
|||
(void)aHeader->GetUnicode(&header);
|
||||
(void)httpChannel->SetResponseHeader(
|
||||
NS_ConvertUCS2toUTF8(header),
|
||||
NS_ConvertUCS2toUTF8(aValue));
|
||||
NS_ConvertUCS2toUTF8(aValue),
|
||||
PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1594,9 +1594,8 @@ CSSLoaderImpl::LoadSheet(URLKey& aKey, SheetLoadData* aData)
|
|||
if (httpChannel) {
|
||||
// send a minimal Accept header for text/css
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/css,*/*;q=0.1"));
|
||||
NS_LITERAL_CSTRING("text/css,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
result = httpChannel->SetReferrer(document_uri);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -689,9 +689,8 @@ nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
|
|||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel) {
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"));
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
|
||||
httpChannel->SetReferrer(mDocumentURL);
|
||||
}
|
||||
|
@ -1094,7 +1093,8 @@ nsXMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsI
|
|||
(void)aHeader->GetUnicode(&header);
|
||||
(void)httpChannel->SetResponseHeader(
|
||||
NS_ConvertUCS2toUTF8(header),
|
||||
NS_ConvertUCS2toUTF8(aValue));
|
||||
NS_ConvertUCS2toUTF8(aValue),
|
||||
PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5447,7 +5447,7 @@ nsDocShell::AddHeadersToChannel(nsIInputStream * aHeadersData,
|
|||
// FINALLY: we can set the header!
|
||||
//
|
||||
|
||||
rv = aChannel->SetRequestHeader(headerName, headerValue);
|
||||
rv = aChannel->SetRequestHeader(headerName, headerValue, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
|
|
@ -191,13 +191,14 @@ nsCookieHTTPNotify::OnModifyRequest(nsIHttpChannel *aHttpChannel)
|
|||
rv = mCookieService->GetCookieStringFromHttp(pURL, pFirstURL, &cookie);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Clear any existing Cookie request header
|
||||
rv = aHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Cookie"), NS_LITERAL_CSTRING(""));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Set the cookie into the request headers
|
||||
const char *headerVal = "";
|
||||
if (cookie && *cookie)
|
||||
rv = aHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Cookie"), nsDependentCString(cookie));
|
||||
headerVal = cookie;
|
||||
|
||||
// Set the cookie into the request headers overwriting any existing header.
|
||||
rv = aHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Cookie"),
|
||||
nsDependentCString(headerVal),
|
||||
PR_FALSE);
|
||||
nsMemory::Free((void *)cookie);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -791,10 +791,13 @@ nsXMLHttpRequest::GetStreamForWString(const PRUnichar* aStr,
|
|||
nsCAutoString header;
|
||||
if( NS_FAILED(httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), header)) )
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
|
||||
NS_LITERAL_CSTRING("text/xml") );
|
||||
NS_LITERAL_CSTRING("text/xml"),
|
||||
PR_FALSE);
|
||||
|
||||
// set the content length header
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"), nsPrintfCString("%d", charLength) );
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"),
|
||||
nsPrintfCString("%d", charLength),
|
||||
PR_FALSE);
|
||||
|
||||
// Shove in the trailing and leading CRLF
|
||||
postData[0] = nsCRT::CR;
|
||||
|
@ -1320,15 +1323,10 @@ nsXMLHttpRequest::SetRequestHeader(const char *header, const char *value)
|
|||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
|
||||
|
||||
if (httpChannel) {
|
||||
// We need to set, not add to, the header. Using empty value will
|
||||
// clear existing header.
|
||||
nsresult rv = httpChannel->SetRequestHeader(nsDependentCString(header),
|
||||
nsCString());
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
// Now set it for real
|
||||
// We need to set, not add to, the header.
|
||||
return httpChannel->SetRequestHeader(nsDependentCString(header),
|
||||
nsDependentCString(value));
|
||||
nsDependentCString(value),
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -1594,9 +1594,8 @@ CSSLoaderImpl::LoadSheet(URLKey& aKey, SheetLoadData* aData)
|
|||
if (httpChannel) {
|
||||
// send a minimal Accept header for text/css
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/css,*/*;q=0.1"));
|
||||
NS_LITERAL_CSTRING("text/css,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
result = httpChannel->SetReferrer(document_uri);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,9 +201,8 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
|||
newHttpChannel = do_QueryInterface(*aResult);
|
||||
if (newHttpChannel) {
|
||||
newHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
newHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1"));
|
||||
NS_LITERAL_CSTRING("video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(newHttpChannel);
|
||||
NS_ENSURE_TRUE(httpChannelInternal, NS_ERROR_UNEXPECTED);
|
||||
|
|
|
@ -1567,7 +1567,7 @@ nsPluginStreamInfo::RequestRead(nsByteRange* rangeList)
|
|||
if(!httpChannel)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString);
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, PR_FALSE);
|
||||
|
||||
mPluginStreamListenerPeer->mAbort = PR_TRUE; // instruct old stream listener to cancel
|
||||
// the request on the next ODA.
|
||||
|
@ -5822,7 +5822,7 @@ nsPluginHostImpl::AddHeadersToChannel(const char *aHeadersData,
|
|||
// FINALLY: we can set the header!
|
||||
//
|
||||
|
||||
rv = aChannel->SetRequestHeader(headerName, headerValue);
|
||||
rv = aChannel->SetRequestHeader(headerName, headerValue, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
return rv;
|
||||
|
|
|
@ -25,62 +25,94 @@
|
|||
#include "nsIChannel.idl"
|
||||
|
||||
interface nsIHttpHeaderVisitor;
|
||||
interface nsISimpleEnumerator;
|
||||
|
||||
[scriptable, uuid(d78b53c8-d03f-4fd8-b2ee-7b36fcd150d1)]
|
||||
/**
|
||||
* nsIHttpChannel
|
||||
*
|
||||
* This interface allows for the modification of HTTP request parameters and
|
||||
* the inspection of the resulting HTTP response status and headers when they
|
||||
* become available.
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
[scriptable, uuid(9277fe09-f0cc-4cd9-bbce-581dd94b0260)]
|
||||
interface nsIHttpChannel : nsIChannel
|
||||
{
|
||||
/**************************************************************************
|
||||
* Request info...
|
||||
* REQUEST CONFIGURATION
|
||||
*
|
||||
* Modifying request parameters after asyncOpen has been called is an error.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The request method is case insensitive
|
||||
* Set/get the HTTP request method (default is "GET"). Setter is case
|
||||
* insensitive; getter returns an uppercase string.
|
||||
*
|
||||
* NOTE: The data for a "POST" or "PUT" request can be configured via
|
||||
* nsIUploadChannel; however, after setting the upload data, it may be
|
||||
* necessary to set the request method explicitly. The documentation
|
||||
* for nsIUploadChannel has further details.
|
||||
*/
|
||||
attribute ACString requestMethod;
|
||||
|
||||
/**
|
||||
* Get/set the referrer URI on the request. This is the address (URI) of
|
||||
* the resource from which this channel's URI was obtained (see RFC2616
|
||||
* section 14.36).
|
||||
* Get/set the HTTP referrer URI. This is the address (URI) of the
|
||||
* resource from which this channel's URI was obtained (see RFC2616 section
|
||||
* 14.36).
|
||||
*
|
||||
* NOTE: The channel may silently refuse to set the Referer header if the
|
||||
* URI does not pass certain security checks (e.g., a "https://" URL will
|
||||
* never be sent as the referrer for a plaintext HTTP request). The
|
||||
* implementation is not required to throw an exception when the referrer
|
||||
* URI is rejected.
|
||||
*/
|
||||
attribute nsIURI referrer;
|
||||
|
||||
/**
|
||||
* Header strings are case insensitive. Setting a header is additive; to
|
||||
* clear a header, assign an empty string.
|
||||
* Get the value of a particular request header.
|
||||
*
|
||||
* @param aHeader
|
||||
* The case-insensitive name of the request header to query (e.g.,
|
||||
* "Cache-Control").
|
||||
*
|
||||
* @return the value of the request header.
|
||||
*/
|
||||
ACString getRequestHeader(in ACString header);
|
||||
void setRequestHeader(in ACString header, in ACString value);
|
||||
void visitRequestHeaders(in nsIHttpHeaderVisitor visitor);
|
||||
|
||||
/**************************************************************************
|
||||
* Response info...
|
||||
*/
|
||||
|
||||
readonly attribute unsigned long responseStatus;
|
||||
readonly attribute ACString responseStatusText;
|
||||
readonly attribute boolean requestSucceeded;
|
||||
ACString getRequestHeader(in ACString aHeader);
|
||||
|
||||
/**
|
||||
* Header strings are case insensitive. Setting a header is additive; to
|
||||
* clear a header, assign an empty string.
|
||||
* Set the value of a particular request header.
|
||||
*
|
||||
* This method allows, for example, the cookies module to add "Cookie"
|
||||
* headers to the outgoing HTTP request.
|
||||
*
|
||||
* @param aHeader
|
||||
* The case-insensitive name of the request header to set (e.g.,
|
||||
* "Cookie").
|
||||
* @param aValue
|
||||
* The request header value to set (e.g., "X=1").
|
||||
* @param aMerge
|
||||
* If true, the new header value will be merged with any existing
|
||||
* values for the specified header. This flag is ignored if the
|
||||
* specified header does not support merging (e.g., the "Content-
|
||||
* Type" header can only have one value). The list of headers for
|
||||
* which this flag is ignored is an implementation detail. If this
|
||||
* flag is false, then the header value will be replaced with the
|
||||
* contents of |aValue|.
|
||||
*
|
||||
* If aValue is empty and aMerge is false, the header will be cleared.
|
||||
*/
|
||||
ACString getResponseHeader(in ACString header);
|
||||
void setResponseHeader(in ACString header, in ACString value);
|
||||
void visitResponseHeaders(in nsIHttpHeaderVisitor visitor);
|
||||
void setRequestHeader(in ACString aHeader,
|
||||
in ACString aValue,
|
||||
in boolean aMerge);
|
||||
|
||||
/**
|
||||
* True if the server sent a "Cache-control: no-store" response header.
|
||||
* Call this method to visit all request headers. Calling setRequestHeader
|
||||
* while visiting request headers has undefined behavior. Don't do it!
|
||||
*
|
||||
* @param aVisitor
|
||||
* the header visitor instance.
|
||||
*/
|
||||
boolean isNoStoreResponse();
|
||||
|
||||
/**
|
||||
* True if the server sent the equivalent of a "Cache-control: no-cache"
|
||||
* response header. Other equivalent response headers include: "Pragma:
|
||||
* no-cache" and "Expires" with a date-value in the past.
|
||||
*/
|
||||
boolean isNoCacheResponse();
|
||||
void visitRequestHeaders(in nsIHttpHeaderVisitor aVisitor);
|
||||
|
||||
/**
|
||||
* This attribute is a hint to the channel to indicate whether or not
|
||||
|
@ -89,7 +121,8 @@ interface nsIHttpChannel : nsIChannel
|
|||
* if the application knows that the corresponding document is likely
|
||||
* to be very large.
|
||||
*
|
||||
* TRUE by default, though other factors may prevent pipelining.
|
||||
* This attribute is true by default, though other factors may prevent
|
||||
* pipelining.
|
||||
*/
|
||||
attribute boolean allowPipelining;
|
||||
|
||||
|
@ -97,6 +130,107 @@ interface nsIHttpChannel : nsIChannel
|
|||
* This attribute specifies the number of redirects this channel is allowed
|
||||
* to make. If zero, the channel will fail to redirect and will generate
|
||||
* a NS_ERROR_REDIRECT_LOOP failure status.
|
||||
*
|
||||
* NOTE: An HTTP redirect results in a new channel being created. If the
|
||||
* new channel supports nsIHttpChannel, then it will be assigned a value
|
||||
* to its |redirectionLimit| attribute one less than the value of the
|
||||
* redirected channel's |redirectionLimit| attribute. The initial value
|
||||
* for this attribute may be a configurable preference (depending on the
|
||||
* implementation).
|
||||
*/
|
||||
attribute unsigned long redirectionLimit;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* RESPONSE INFO
|
||||
*
|
||||
* Accessing response info before the onStartRequest event is an error.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the HTTP response code (e.g., 200).
|
||||
*/
|
||||
readonly attribute unsigned long responseStatus;
|
||||
|
||||
/**
|
||||
* Get the HTTP response status text (e.g., "OK").
|
||||
*
|
||||
* NOTE: This returns the raw (possibly 8-bit) text from the server. There
|
||||
* are no assumptions made about the charset of the returned text. You
|
||||
* have been warned!
|
||||
*/
|
||||
readonly attribute ACString responseStatusText;
|
||||
|
||||
/**
|
||||
* Returns true if the HTTP response code indicates success. The value of
|
||||
* nsIRequest::status will be NS_OK even when processing a 404 response
|
||||
* because a 404 response may include a message body that (in some cases)
|
||||
* should be shown to the user.
|
||||
*
|
||||
* Use this attribute to distinguish server error pages from normal pages,
|
||||
* instead of comparing the response status manually against the set of
|
||||
* valid response codes, if that is required by your application.
|
||||
*/
|
||||
readonly attribute boolean requestSucceeded;
|
||||
|
||||
/**
|
||||
* Get the value of a particular response header.
|
||||
*
|
||||
* @param aHeader
|
||||
* The case-insensitive name of the response header to query (e.g.,
|
||||
* "Set-Cookie").
|
||||
*
|
||||
* @return the value of the response header.
|
||||
*/
|
||||
ACString getResponseHeader(in ACString header);
|
||||
|
||||
/**
|
||||
* Set the value of a particular response header.
|
||||
*
|
||||
* This method allows, for example, the HTML content sink to inform the HTTP
|
||||
* channel about HTTP-EQUIV headers found in HTML <META> tags.
|
||||
*
|
||||
* @param aHeader
|
||||
* The case-insensitive name of the response header to set (e.g.,
|
||||
* "Cache-control").
|
||||
* @param aValue
|
||||
* The response header value to set (e.g., "no-cache").
|
||||
* @param aMerge
|
||||
* If true, the new header value will be merged with any existing
|
||||
* values for the specified header. This flag is ignored if the
|
||||
* specified header does not support merging (e.g., the "Content-
|
||||
* Type" header can only have one value). The list of headers for
|
||||
* which this flag is ignored is an implementation detail. If this
|
||||
* flag is false, then the header value will be replaced with the
|
||||
* contents of |aValue|.
|
||||
*
|
||||
* If aValue is empty and aMerge is false, the header will be cleared.
|
||||
*/
|
||||
void setResponseHeader(in ACString header,
|
||||
in ACString value,
|
||||
in boolean merge);
|
||||
|
||||
/**
|
||||
* Call this method to visit all response headers. Calling
|
||||
* setResponseHeader while visiting response headers has undefined
|
||||
* behavior. Don't do it!
|
||||
*
|
||||
* @param aVisitor
|
||||
* the header visitor instance.
|
||||
*/
|
||||
void visitResponseHeaders(in nsIHttpHeaderVisitor aVisitor);
|
||||
|
||||
/**
|
||||
* Returns true if the server sent a "Cache-Control: no-store" response
|
||||
* header.
|
||||
*/
|
||||
boolean isNoStoreResponse();
|
||||
|
||||
/**
|
||||
* Returns true if the server sent the equivalent of a "Cache-control:
|
||||
* no-cache" response header. Equivalent response headers include:
|
||||
* "Pragma: no-cache", "Expires: 0", and "Expires" with a date value
|
||||
* in the past relative to the value of the "Date" header.
|
||||
*/
|
||||
boolean isNoCacheResponse();
|
||||
};
|
||||
|
|
|
@ -492,11 +492,11 @@ nsHttpChannel::SetupTransaction()
|
|||
// We need to send 'Pragma:no-cache' to inhibit proxy caching even if
|
||||
// no proxy is configured since we might be talking with a transparent
|
||||
// proxy, i.e. one that operates at the network level. See bug #14772.
|
||||
mRequestHead.SetHeader(nsHttp::Pragma, NS_LITERAL_CSTRING("no-cache"));
|
||||
mRequestHead.SetHeader(nsHttp::Pragma, NS_LITERAL_CSTRING("no-cache"), PR_TRUE);
|
||||
// If we're configured to speak HTTP/1.1 then also send 'Cache-control:
|
||||
// no-cache'
|
||||
if (mRequestHead.Version() >= NS_HTTP_VERSION_1_1)
|
||||
mRequestHead.SetHeader(nsHttp::Cache_Control, NS_LITERAL_CSTRING("no-cache"));
|
||||
mRequestHead.SetHeader(nsHttp::Cache_Control, NS_LITERAL_CSTRING("no-cache"), PR_TRUE);
|
||||
}
|
||||
else if ((mLoadFlags & VALIDATE_ALWAYS) && (mCacheAccess & nsICache::ACCESS_READ)) {
|
||||
// We need to send 'Cache-Control: max-age=0' to force each cache along
|
||||
|
@ -505,9 +505,9 @@ nsHttpChannel::SetupTransaction()
|
|||
//
|
||||
// If we're configured to speak HTTP/1.0 then just send 'Pragma: no-cache'
|
||||
if (mRequestHead.Version() >= NS_HTTP_VERSION_1_1)
|
||||
mRequestHead.SetHeader(nsHttp::Cache_Control, NS_LITERAL_CSTRING("max-age=0"));
|
||||
mRequestHead.SetHeader(nsHttp::Cache_Control, NS_LITERAL_CSTRING("max-age=0"), PR_TRUE);
|
||||
else
|
||||
mRequestHead.SetHeader(nsHttp::Pragma, NS_LITERAL_CSTRING("no-cache"));
|
||||
mRequestHead.SetHeader(nsHttp::Pragma, NS_LITERAL_CSTRING("no-cache"), PR_TRUE);
|
||||
}
|
||||
|
||||
return mTransaction->SetupRequest(&mRequestHead, mUploadStream,
|
||||
|
@ -688,13 +688,13 @@ nsHttpChannel::ProcessNormal()
|
|||
mResponseHead->ContentType().Equals(NS_LITERAL_CSTRING(APPLICATION_GZIP2)) ||
|
||||
mResponseHead->ContentType().Equals(NS_LITERAL_CSTRING(APPLICATION_GZIP3)))) {
|
||||
// clear the Content-Encoding header
|
||||
mResponseHead->SetHeader(nsHttp::Content_Encoding, NS_LITERAL_CSTRING(""));
|
||||
mResponseHead->ClearHeader(nsHttp::Content_Encoding);
|
||||
}
|
||||
else if (encoding && PL_strcasestr(encoding, "compress") && (
|
||||
mResponseHead->ContentType().Equals(NS_LITERAL_CSTRING(APPLICATION_COMPRESS)) ||
|
||||
mResponseHead->ContentType().Equals(NS_LITERAL_CSTRING(APPLICATION_COMPRESS2)))) {
|
||||
// clear the Content-Encoding header
|
||||
mResponseHead->SetHeader(nsHttp::Content_Encoding, NS_LITERAL_CSTRING(""));
|
||||
mResponseHead->ClearHeader(nsHttp::Content_Encoding);
|
||||
}
|
||||
|
||||
// this must be called before firing OnStartRequest, since http clients,
|
||||
|
@ -1141,8 +1141,8 @@ nsHttpChannel::CheckCache()
|
|||
PRBool doValidation = PR_FALSE;
|
||||
|
||||
// Be optimistic: assume that we won't need to do validation
|
||||
mRequestHead.SetHeader(nsHttp::If_Modified_Since, NS_LITERAL_CSTRING(""));
|
||||
mRequestHead.SetHeader(nsHttp::If_None_Match, NS_LITERAL_CSTRING(""));
|
||||
mRequestHead.ClearHeader(nsHttp::If_Modified_Since);
|
||||
mRequestHead.ClearHeader(nsHttp::If_None_Match);
|
||||
|
||||
// If the LOAD_FROM_CACHE flag is set, any cached data can simply be used.
|
||||
if (mLoadFlags & LOAD_FROM_CACHE) {
|
||||
|
@ -2511,7 +2511,7 @@ nsHttpChannel::SetReferrer(nsIURI *referrer)
|
|||
|
||||
// clear existing referrer, if any
|
||||
mReferrer = nsnull;
|
||||
mRequestHead.SetHeader(nsHttp::Referer, NS_LITERAL_CSTRING(""));
|
||||
mRequestHead.ClearHeader(nsHttp::Referer);
|
||||
|
||||
if (!referrer)
|
||||
return NS_OK;
|
||||
|
@ -2656,12 +2656,14 @@ nsHttpChannel::GetRequestHeader(const nsACString &header, nsACString &value)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::SetRequestHeader(const nsACString &header, const nsACString &value)
|
||||
nsHttpChannel::SetRequestHeader(const nsACString &header,
|
||||
const nsACString &value,
|
||||
PRBool merge)
|
||||
{
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
|
||||
LOG(("nsHttpChannel::SetRequestHeader [this=%x header=%s value=%s]\n",
|
||||
this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get()));
|
||||
LOG(("nsHttpChannel::SetRequestHeader [this=%x header=\"%s\" value=\"%s\" merge=%u]\n",
|
||||
this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get(), merge));
|
||||
|
||||
nsHttpAtom atom = nsHttp::ResolveAtom(header);
|
||||
if (!atom) {
|
||||
|
@ -2669,7 +2671,7 @@ nsHttpChannel::SetRequestHeader(const nsACString &header, const nsACString &valu
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return mRequestHead.SetHeader(atom, value);
|
||||
return mRequestHead.SetHeader(atom, value, merge);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2766,10 +2768,12 @@ nsHttpChannel::GetResponseHeader(const nsACString &header, nsACString &value)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::SetResponseHeader(const nsACString &header, const nsACString &value)
|
||||
nsHttpChannel::SetResponseHeader(const nsACString &header,
|
||||
const nsACString &value,
|
||||
PRBool merge)
|
||||
{
|
||||
LOG(("nsHttpChannel::SetResponseHeader [this=%x header=\"%s\" value=\"%s\"]\n",
|
||||
this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get()));
|
||||
LOG(("nsHttpChannel::SetResponseHeader [this=%x header=\"%s\" value=\"%s\" merge=%u]\n",
|
||||
this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get(), merge));
|
||||
|
||||
if (!mResponseHead)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
@ -2785,7 +2789,7 @@ nsHttpChannel::SetResponseHeader(const nsACString &header, const nsACString &val
|
|||
atom == nsHttp::Transfer_Encoding)
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
nsresult rv = mResponseHead->SetHeader(atom, value);
|
||||
nsresult rv = mResponseHead->SetHeader(atom, value, merge);
|
||||
|
||||
// XXX temporary hack until http supports some form of a header change observer
|
||||
if ((atom == nsHttp::Set_Cookie) && NS_SUCCEEDED(rv))
|
||||
|
|
|
@ -295,19 +295,22 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request,
|
|||
// with HTTP/1.0 servers/proxies. We use "Proxy-Connection:" when
|
||||
// we're talking to an http proxy, and "Connection:" otherwise
|
||||
|
||||
const char* connectionType = "close";
|
||||
NS_NAMED_LITERAL_CSTRING(close, "close");
|
||||
NS_NAMED_LITERAL_CSTRING(keepAlive, "keep-alive");
|
||||
|
||||
const nsACString *connectionType = &close;
|
||||
if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
|
||||
rv = request->SetHeader(nsHttp::Keep_Alive, nsPrintfCString("%u", mIdleTimeout));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
connectionType = "keep-alive";
|
||||
connectionType = &keepAlive;
|
||||
} else if (useProxy) {
|
||||
// Bug 92006
|
||||
request->SetHeader(nsHttp::Connection, NS_LITERAL_CSTRING("close"));
|
||||
request->SetHeader(nsHttp::Connection, close);
|
||||
}
|
||||
|
||||
const nsHttpAtom &header =
|
||||
useProxy ? nsHttp::Proxy_Connection : nsHttp::Connection;
|
||||
return request->SetHeader(header, nsDependentCString(connectionType));
|
||||
const nsHttpAtom &header = useProxy ? nsHttp::Proxy_Connection
|
||||
: nsHttp::Connection;
|
||||
return request->SetHeader(header, *connectionType);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -29,22 +29,26 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsHttpHeaderArray::SetHeader(nsHttpAtom header, const nsACString &value)
|
||||
nsHttpHeaderArray::SetHeader(nsHttpAtom header,
|
||||
const nsACString &value,
|
||||
PRBool merge)
|
||||
{
|
||||
nsEntry *entry = nsnull;
|
||||
PRInt32 index;
|
||||
|
||||
// If an empty value is passed in, then delete the header entry...
|
||||
index = LookupEntry(header, &entry);
|
||||
|
||||
// If an empty value is passed in, then delete the header entry...
|
||||
// unless we are merging, in which case this function becomes a NOP.
|
||||
if (value.IsEmpty()) {
|
||||
if (entry) {
|
||||
if (!merge && entry) {
|
||||
mHeaders.RemoveElementAt(index);
|
||||
delete entry;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create a new entry or...
|
||||
// Create a new entry, or...
|
||||
if (!entry) {
|
||||
entry = new nsEntry(header, value);
|
||||
if (!entry)
|
||||
|
@ -55,7 +59,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header, const nsACString &value)
|
|||
}
|
||||
}
|
||||
// Append the new value to the existing value iff...
|
||||
else if (CanAppendToHeader(header)) {
|
||||
else if (merge && CanAppendToHeader(header)) {
|
||||
if (header == nsHttp::Set_Cookie ||
|
||||
header == nsHttp::WWW_Authenticate ||
|
||||
header == nsHttp::Proxy_Authenticate)
|
||||
|
@ -74,6 +78,19 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header, const nsACString &value)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpHeaderArray::ClearHeader(nsHttpAtom header)
|
||||
{
|
||||
nsEntry *entry = nsnull;
|
||||
PRInt32 index;
|
||||
|
||||
index = LookupEntry(header, &entry);
|
||||
if (entry) {
|
||||
mHeaders.RemoveElementAt(index);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
nsHttpHeaderArray::PeekHeader(nsHttpAtom header)
|
||||
{
|
||||
|
@ -219,18 +236,16 @@ nsHttpHeaderArray::LookupEntry(nsHttpAtom header, nsEntry **entry)
|
|||
PRBool
|
||||
nsHttpHeaderArray::CanAppendToHeader(nsHttpAtom header)
|
||||
{
|
||||
return header == nsHttp::Accept_Charset ||
|
||||
header == nsHttp::Content_Type ||
|
||||
header == nsHttp::User_Agent ||
|
||||
header == nsHttp::Referer ||
|
||||
header == nsHttp::Host ||
|
||||
header == nsHttp::Authorization ||
|
||||
header == nsHttp::Proxy_Authorization ||
|
||||
header == nsHttp::If_Modified_Since ||
|
||||
header == nsHttp::If_Unmodified_Since ||
|
||||
header == nsHttp::From ||
|
||||
header == nsHttp::Location ||
|
||||
header == nsHttp::Max_Forwards
|
||||
?
|
||||
PR_FALSE : PR_TRUE;
|
||||
return header != nsHttp::Content_Type &&
|
||||
header != nsHttp::Content_Length &&
|
||||
header != nsHttp::User_Agent &&
|
||||
header != nsHttp::Referer &&
|
||||
header != nsHttp::Host &&
|
||||
header != nsHttp::Authorization &&
|
||||
header != nsHttp::Proxy_Authorization &&
|
||||
header != nsHttp::If_Modified_Since &&
|
||||
header != nsHttp::If_Unmodified_Since &&
|
||||
header != nsHttp::From &&
|
||||
header != nsHttp::Location &&
|
||||
header != nsHttp::Max_Forwards;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,9 @@ public:
|
|||
|
||||
const char *PeekHeader(nsHttpAtom header);
|
||||
|
||||
nsresult SetHeader(nsHttpAtom header, const nsACString &value);
|
||||
nsresult SetHeader(nsHttpAtom header, const nsACString &value, PRBool merge = PR_FALSE);
|
||||
nsresult GetHeader(nsHttpAtom header, nsACString &value);
|
||||
void ClearHeader(nsHttpAtom h);
|
||||
|
||||
nsresult VisitHeaders(nsIHttpHeaderVisitor *visitor);
|
||||
|
||||
|
|
|
@ -49,10 +49,11 @@ public:
|
|||
nsHttpVersion Version() { return mVersion; }
|
||||
const nsAFlatCString &RequestURI() { return mRequestURI; }
|
||||
|
||||
const char *PeekHeader(nsHttpAtom h) { return mHeaders.PeekHeader(h); }
|
||||
nsresult SetHeader(nsHttpAtom h, const nsACString &v) { return mHeaders.SetHeader(h, v); }
|
||||
nsresult GetHeader(nsHttpAtom h, nsACString &v) { return mHeaders.GetHeader(h, v); }
|
||||
void ClearHeaders() { mHeaders.Clear(); }
|
||||
const char *PeekHeader(nsHttpAtom h) { return mHeaders.PeekHeader(h); }
|
||||
nsresult SetHeader(nsHttpAtom h, const nsACString &v, PRBool m=PR_FALSE) { return mHeaders.SetHeader(h, v, m); }
|
||||
nsresult GetHeader(nsHttpAtom h, nsACString &v) { return mHeaders.GetHeader(h, v); }
|
||||
void ClearHeader(nsHttpAtom h) { mHeaders.ClearHeader(h); }
|
||||
void ClearHeaders() { mHeaders.Clear(); }
|
||||
|
||||
void Flatten(nsACString &, PRBool pruneProxyHeaders = PR_FALSE);
|
||||
|
||||
|
|
|
@ -34,16 +34,19 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsHttpResponseHead::SetHeader(nsHttpAtom hdr, const nsACString &val)
|
||||
nsHttpResponseHead::SetHeader(nsHttpAtom hdr,
|
||||
const nsACString &val,
|
||||
PRBool merge)
|
||||
{
|
||||
nsresult rv = mHeaders.SetHeader(hdr, val);
|
||||
nsresult rv = mHeaders.SetHeader(hdr, val, merge);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// response to changes in these headers
|
||||
// respond to changes in these headers. we need to reparse the entire
|
||||
// header since the change may have merged in additional values.
|
||||
if (hdr == nsHttp::Cache_Control)
|
||||
ParseCacheControl(PromiseFlatCString(val).get());
|
||||
ParseCacheControl(mHeaders.PeekHeader(hdr));
|
||||
else if (hdr == nsHttp::Pragma)
|
||||
ParsePragma(PromiseFlatCString(val).get());
|
||||
ParsePragma(mHeaders.PeekHeader(hdr));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -53,9 +56,9 @@ nsHttpResponseHead::SetContentLength(PRInt32 len)
|
|||
{
|
||||
mContentLength = len;
|
||||
if (len < 0)
|
||||
SetHeader(nsHttp::Content_Length, NS_LITERAL_CSTRING(""));
|
||||
mHeaders.ClearHeader(nsHttp::Content_Length);
|
||||
else
|
||||
SetHeader(nsHttp::Content_Length, nsPrintfCString("%d", len));
|
||||
mHeaders.SetHeader(nsHttp::Content_Length, nsPrintfCString("%d", len));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -64,19 +67,16 @@ nsHttpResponseHead::Flatten(nsACString &buf, PRBool pruneTransients)
|
|||
if (mVersion == NS_HTTP_VERSION_0_9)
|
||||
return;
|
||||
|
||||
buf.Append("HTTP/");
|
||||
buf.Append(NS_LITERAL_CSTRING("HTTP/"));
|
||||
if (mVersion == NS_HTTP_VERSION_1_1)
|
||||
buf.Append("1.1 ");
|
||||
buf.Append(NS_LITERAL_CSTRING("1.1 "));
|
||||
else
|
||||
buf.Append("1.0 ");
|
||||
buf.Append(NS_LITERAL_CSTRING("1.0 "));
|
||||
|
||||
char b[32];
|
||||
PR_snprintf(b, sizeof(b), "%u", PRUintn(mStatus));
|
||||
|
||||
buf.Append(b);
|
||||
buf.Append(' ');
|
||||
buf.Append(mStatusText);
|
||||
buf.Append("\r\n");
|
||||
buf.Append(nsPrintfCString("%u", PRUintn(mStatus)) +
|
||||
NS_LITERAL_CSTRING(" ") +
|
||||
mStatusText +
|
||||
NS_LITERAL_CSTRING("\r\n"));
|
||||
|
||||
if (!pruneTransients) {
|
||||
mHeaders.Flatten(buf, PR_FALSE);
|
||||
|
@ -104,10 +104,10 @@ nsHttpResponseHead::Flatten(nsACString &buf, PRBool pruneTransients)
|
|||
continue;
|
||||
|
||||
// otherwise, write out the "header: value\r\n" line
|
||||
buf.Append(header.get());
|
||||
buf.Append(": ");
|
||||
buf.Append(value);
|
||||
buf.Append("\r\n");
|
||||
buf.Append(nsDependentCString(header.get()) +
|
||||
NS_LITERAL_CSTRING(": ") +
|
||||
nsDependentCString(value) +
|
||||
NS_LITERAL_CSTRING("\r\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ nsHttpResponseHead::ParseStatusLine(char *line)
|
|||
void
|
||||
nsHttpResponseHead::ParseHeaderLine(char *line)
|
||||
{
|
||||
nsHttpAtom hdr;
|
||||
nsHttpAtom hdr = {0};
|
||||
char *val;
|
||||
|
||||
mHeaders.ParseHeaderLine(line, &hdr, &val);
|
||||
|
@ -427,11 +427,8 @@ nsHttpResponseHead::UpdateHeaders(nsHttpHeaderArray &headers)
|
|||
else {
|
||||
LOG(("new response header [%s: %s]\n", header.get(), val));
|
||||
|
||||
// delete the current header value (if any)
|
||||
mHeaders.SetHeader(header, NS_LITERAL_CSTRING(""));
|
||||
|
||||
// copy the new header value...
|
||||
mHeaders.SetHeader(header, nsDependentCString(val));
|
||||
// overwrite the current header value with the new value...
|
||||
SetHeader(header, nsDependentCString(val));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,19 +630,18 @@ nsHttpResponseHead::ParseContentType(char *type)
|
|||
void
|
||||
nsHttpResponseHead::ParseCacheControl(const char *val)
|
||||
{
|
||||
if (!val) {
|
||||
// clear no-cache flag
|
||||
if (!(val && *val)) {
|
||||
// clear flags
|
||||
mCacheControlNoCache = PR_FALSE;
|
||||
mCacheControlNoStore = PR_FALSE;
|
||||
return;
|
||||
}
|
||||
else if (!*val)
|
||||
return;
|
||||
|
||||
const char *s = val;
|
||||
|
||||
// search header value for occurance(s) of "no-cache" but ignore
|
||||
// occurance(s) of "no-cache=blah"
|
||||
while (s = PL_strcasestr(s, "no-cache")) {
|
||||
while ((s = PL_strcasestr(s, "no-cache")) != nsnull) {
|
||||
s += (sizeof("no-cache") - 1);
|
||||
if (*s != '=')
|
||||
mCacheControlNoCache = PR_TRUE;
|
||||
|
@ -661,15 +657,15 @@ nsHttpResponseHead::ParsePragma(const char *val)
|
|||
{
|
||||
LOG(("nsHttpResponseHead::ParsePragma [val=%s]\n", val));
|
||||
|
||||
if (!val) {
|
||||
if (!(val && *val)) {
|
||||
// clear no-cache flag
|
||||
mPragmaNoCache = PR_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Although 'Pragma:no-cache' is not a standard HTTP response header (it's
|
||||
// Although 'Pragma: no-cache' is not a standard HTTP response header (it's
|
||||
// a request header), caching is inhibited when this header is present so
|
||||
// as to match existing Navigator behavior.
|
||||
if (*val && PL_strcasestr(val, "no-cache"))
|
||||
if (PL_strcasestr(val, "no-cache"))
|
||||
mPragmaNoCache = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -58,8 +58,9 @@ public:
|
|||
PRBool NoCache() { return (mCacheControlNoCache || mPragmaNoCache); }
|
||||
|
||||
const char *PeekHeader(nsHttpAtom h) { return mHeaders.PeekHeader(h); }
|
||||
nsresult SetHeader(nsHttpAtom h, const nsACString &v);
|
||||
nsresult SetHeader(nsHttpAtom h, const nsACString &v, PRBool m=PR_FALSE);
|
||||
nsresult GetHeader(nsHttpAtom h, nsACString &v) { return mHeaders.GetHeader(h, v); }
|
||||
void ClearHeader(nsHttpAtom h) { mHeaders.ClearHeader(h); }
|
||||
void ClearHeaders() { mHeaders.Clear(); }
|
||||
|
||||
void SetContentType(const nsACString &s) { mContentType = s; }
|
||||
|
|
|
@ -457,7 +457,7 @@ nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
|||
if (mHttpChannel) {
|
||||
// we don't want view-source following Refresh: headers, so clear it
|
||||
mHttpChannel->SetResponseHeader(NS_LITERAL_CSTRING("Refresh"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
NS_LITERAL_CSTRING(""), PR_FALSE);
|
||||
}
|
||||
return mListener->OnStartRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
|
||||
this),
|
||||
|
|
|
@ -932,7 +932,7 @@ nsMultiMixedConv::ParseHeaders(nsIChannel *aChannel, char *&aPtr,
|
|||
// it's header observers.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (httpChannel) {
|
||||
rv = httpChannel->SetResponseHeader(headerStr, headerVal);
|
||||
rv = httpChannel->SetResponseHeader(headerStr, headerVal, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
} else if (headerStr.EqualsIgnoreCase("content-range") ||
|
||||
|
|
|
@ -471,7 +471,8 @@ nsresult StartLoadingURL(const char* aUrlString)
|
|||
if (pHTTPCon) {
|
||||
// Setting a sample header.
|
||||
rv = pHTTPCon->SetRequestHeader(NS_LITERAL_CSTRING("sample-header"),
|
||||
NS_LITERAL_CSTRING("Sample-Value"));
|
||||
NS_LITERAL_CSTRING("Sample-Value"),
|
||||
PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
InputTestConsumer* listener;
|
||||
|
|
|
@ -293,7 +293,8 @@ nsPrefetchService::ProcessNextURI()
|
|||
if (httpChannel) {
|
||||
httpChannel->SetReferrer(referrer);
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("X-Moz"),
|
||||
NS_LITERAL_CSTRING("prefetch"));
|
||||
NS_LITERAL_CSTRING("prefetch"),
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
rv = mCurrentChannel->AsyncOpen(listener, nsnull);
|
||||
|
|
|
@ -3895,7 +3895,8 @@ InternetSearchDataSource::DoSearch(nsIRDFResource *source, nsIRDFResource *engin
|
|||
if (httpMultiChannel)
|
||||
{
|
||||
httpMultiChannel->SetRequestHeader(NS_LITERAL_CSTRING("MultiSearch"),
|
||||
NS_LITERAL_CSTRING("true"));
|
||||
NS_LITERAL_CSTRING("true"),
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
// get it just from the cache if we can (do not validate)
|
||||
|
|
Загрузка…
Ссылка в новой задаче