fixes bug 157133 "HTTP Interfaces need to be frozen" r=dougt sr=bzbarsky

This commit is contained in:
darin%netscape.com 2002-11-22 07:40:16 +00:00
Родитель becf310cdd
Коммит d9541f875d
23 изменённых файлов: 313 добавлений и 159 удалений

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

@ -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)