зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 325808 "HTTP code could use a HasToken function" r=biesi, sr=bzbarsky
This commit is contained in:
Родитель
b804178071
Коммит
4982455809
|
@ -214,3 +214,30 @@ nsHttp::ResolveAtom(const char *str)
|
|||
stub->key = atom._val = heapAtom->value;
|
||||
return atom;
|
||||
}
|
||||
|
||||
const char *
|
||||
nsHttp::FindToken(const char *input, const char *token, const char *seps)
|
||||
{
|
||||
if (!input)
|
||||
return nsnull;
|
||||
|
||||
int inputLen = strlen(input);
|
||||
int tokenLen = strlen(token);
|
||||
|
||||
if (inputLen < tokenLen)
|
||||
return nsnull;
|
||||
|
||||
const char *inputTop = input;
|
||||
const char *inputEnd = input + inputLen - tokenLen;
|
||||
for (; input <= inputEnd; ++input) {
|
||||
if (PL_strncasecmp(input, token, tokenLen) == 0) {
|
||||
if (input > inputTop && !strchr(seps, *(input - 1)))
|
||||
continue;
|
||||
if (input < inputEnd && !strchr(seps, *(input + tokenLen)))
|
||||
continue;
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -122,8 +122,8 @@ typedef PRUint8 nsHttpVersion;
|
|||
|
||||
struct nsHttpAtom
|
||||
{
|
||||
operator const char *() { return _val; }
|
||||
const char *get() { return _val; }
|
||||
operator const char *() const { return _val; }
|
||||
const char *get() const { return _val; }
|
||||
|
||||
void operator=(const char *v) { _val = v; }
|
||||
void operator=(const nsHttpAtom &a) { _val = a._val; }
|
||||
|
@ -144,13 +144,20 @@ struct nsHttp
|
|||
return ResolveAtom(PromiseFlatCString(s).get());
|
||||
}
|
||||
|
||||
/* Declare all atoms
|
||||
*
|
||||
* The atom names and values are stored in nsHttpAtomList.h and
|
||||
* are brought to you by the magic of C preprocessing
|
||||
*
|
||||
* Add new atoms to nsHttpAtomList and all support logic will be auto-generated
|
||||
*/
|
||||
// find the first instance (case-insensitive comparison) of the given
|
||||
// |token| in the |input| string. the |token| is bounded by elements of
|
||||
// |separators| and may appear at the beginning or end of the |input|
|
||||
// string. null is returned if the |token| is not found. |input| may be
|
||||
// null, in which case null is returned.
|
||||
static const char *FindToken(const char *input, const char *token,
|
||||
const char *separators);
|
||||
|
||||
// Declare all atoms
|
||||
//
|
||||
// The atom names and values are stored in nsHttpAtomList.h and are brought
|
||||
// to you by the magic of C preprocessing. Add new atoms to nsHttpAtomList
|
||||
// and all support logic will be auto-generated.
|
||||
//
|
||||
#define HTTP_ATOM(_name, _value) static nsHttpAtom _name;
|
||||
#include "nsHttpAtomList.h"
|
||||
#undef HTTP_ATOM
|
||||
|
@ -163,12 +170,7 @@ struct nsHttp
|
|||
static inline PRUint32
|
||||
PRTimeToSeconds(PRTime t_usec)
|
||||
{
|
||||
PRTime usec_per_sec;
|
||||
PRUint32 t_sec;
|
||||
LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
|
||||
LL_DIV(t_usec, t_usec, usec_per_sec);
|
||||
LL_L2I(t_sec, t_usec);
|
||||
return t_sec;
|
||||
return PRUint32( t_usec / PR_USEC_PER_SEC );
|
||||
}
|
||||
|
||||
#define NowInSeconds() PRTimeToSeconds(PR_Now())
|
||||
|
@ -177,12 +179,10 @@ PRTimeToSeconds(PRTime t_usec)
|
|||
#undef CLAMP
|
||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||
|
||||
// nsCRT::strdup likes to convert nsnull to ""
|
||||
#define strdup_if(s) (s ? nsCRT::strdup(s) : nsnull)
|
||||
|
||||
// round q-value to one decimal place; return most significant digit as uint.
|
||||
#define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.05) * 10.0))
|
||||
|
||||
#define HTTP_LWS " \t"
|
||||
#define HTTP_HEADER_VALUE_SEPS HTTP_LWS ","
|
||||
|
||||
#endif // nsHttp_h__
|
||||
|
|
|
@ -383,7 +383,8 @@ nsHttpChannel::Connect(PRBool firstTime)
|
|||
// out to net to validate it. this call sets mCachedContentIsValid
|
||||
// and may set request headers as required for cache validation.
|
||||
rv = CheckCache();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "cache check failed");
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("cache check failed");
|
||||
|
||||
// read straight from the cache if possible...
|
||||
if (mCachedContentIsValid) {
|
||||
|
@ -877,15 +878,14 @@ nsHttpChannel::ProcessNormal()
|
|||
// must do this early on so as to prevent it from being seen up stream.
|
||||
// The same problem exists for Content-Encoding: compress in default
|
||||
// Apache installs.
|
||||
const char *encoding = mResponseHead->PeekHeader(nsHttp::Content_Encoding);
|
||||
if (encoding && PL_strcasestr(encoding, "gzip") && (
|
||||
if (mResponseHead->HasHeaderValue(nsHttp::Content_Encoding, "gzip") && (
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_GZIP) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_GZIP2) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_GZIP3))) {
|
||||
// clear the Content-Encoding header
|
||||
mResponseHead->ClearHeader(nsHttp::Content_Encoding);
|
||||
}
|
||||
else if (encoding && PL_strcasestr(encoding, "compress") && (
|
||||
else if (mResponseHead->HasHeaderValue(nsHttp::Content_Encoding, "compress") && (
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_COMPRESS) ||
|
||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_COMPRESS2))) {
|
||||
// clear the Content-Encoding header
|
||||
|
@ -1427,7 +1427,7 @@ nsHttpChannel::CheckCache()
|
|||
|
||||
// Get the method that was used to generate the cached response
|
||||
rv = mCacheEntry->GetMetaDataElement("request-method", getter_Copies(buf));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsHttpAtom method = nsHttp::ResolveAtom(buf);
|
||||
if (method == nsHttp::Head) {
|
||||
|
@ -1441,7 +1441,7 @@ nsHttpChannel::CheckCache()
|
|||
// We'll need this value in later computations...
|
||||
PRUint32 lastModifiedTime;
|
||||
rv = mCacheEntry->GetLastModified(&lastModifiedTime);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Determine if this is the first time that this cache entry
|
||||
// has been accessed during this session.
|
||||
|
@ -1450,7 +1450,7 @@ nsHttpChannel::CheckCache()
|
|||
|
||||
// Get the cached HTTP response headers
|
||||
rv = mCacheEntry->GetMetaDataElement("response-head", getter_Copies(buf));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Parse the cached HTTP response headers
|
||||
NS_ASSERTION(!mCachedResponseHead, "memory leak detected");
|
||||
|
@ -1458,7 +1458,7 @@ nsHttpChannel::CheckCache()
|
|||
if (!mCachedResponseHead)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
rv = mCachedResponseHead->Parse((char *) buf.get());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
buf.Adopt(0);
|
||||
|
||||
// If we were only granted read access, then assume the entry is valid.
|
||||
|
@ -1480,7 +1480,7 @@ nsHttpChannel::CheckCache()
|
|||
if (contentLength != nsInt64(-1)) {
|
||||
PRUint32 size;
|
||||
rv = mCacheEntry->GetDataSize(&size);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (nsInt64(size) != contentLength) {
|
||||
LOG(("Cached data size does not match the Content-Length header "
|
||||
|
@ -1488,7 +1488,7 @@ nsHttpChannel::CheckCache()
|
|||
if ((nsInt64(size) < contentLength) && mCachedResponseHead->IsResumable()) {
|
||||
// looks like a partial entry.
|
||||
rv = SetupByteRangeRequest(size);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mCachedContentIsPartial = PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1544,7 +1544,7 @@ nsHttpChannel::CheckCache()
|
|||
PRUint32 time = 0; // a temporary variable for storing time values...
|
||||
|
||||
rv = mCacheEntry->GetExpirationTime(&time);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (NowInSeconds() <= time)
|
||||
doValidation = PR_FALSE;
|
||||
|
@ -1557,7 +1557,7 @@ nsHttpChannel::CheckCache()
|
|||
// is consistent with existing browsers and is generally expected
|
||||
// by web authors.
|
||||
rv = mCachedResponseHead->ComputeFreshnessLifetime(&time);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (time == 0)
|
||||
doValidation = PR_TRUE;
|
||||
|
@ -3362,8 +3362,7 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
|||
// Adjust mCaps according to our request headers:
|
||||
// - If "Connection: close" is set as a request header, then do not bother
|
||||
// trying to establish a keep-alive connection.
|
||||
const char *connHeader = mRequestHead.PeekHeader(nsHttp::Connection);
|
||||
if (PL_strcasestr(connHeader, "close"))
|
||||
if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close"))
|
||||
mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE | NS_HTTP_ALLOW_PIPELINING);
|
||||
|
||||
mIsPending = PR_TRUE;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsHttpConnectionInfo.h"
|
||||
#include "nsHttpConnection.h"
|
||||
#include "nsHttpTransaction.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "prmon.h"
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ nsHttpHandler::IsAcceptableEncoding(const char *enc)
|
|||
if (!PL_strncasecmp(enc, "x-", 2))
|
||||
enc += 2;
|
||||
|
||||
return PL_strcasestr(mAcceptEncodings.get(), enc) != nsnull;
|
||||
return nsHttp::FindToken(mAcceptEncodings.get(), enc, HTTP_LWS ",") != nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -56,22 +56,18 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header,
|
|||
// 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 (!merge && entry) {
|
||||
if (!merge && entry)
|
||||
mHeaders.RemoveElementAt(index);
|
||||
delete entry;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create a new entry, or...
|
||||
if (!entry) {
|
||||
entry = new nsEntry(header, value);
|
||||
entry = mHeaders.AppendElement(); //new nsEntry(header, value);
|
||||
if (!entry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!mHeaders.AppendElement(entry)) {
|
||||
NS_WARNING("AppendElement failed");
|
||||
delete entry;
|
||||
}
|
||||
entry->header = header;
|
||||
entry->value = value;
|
||||
}
|
||||
// Append the new value to the existing value iff...
|
||||
else if (merge && CanAppendToHeader(header)) {
|
||||
|
@ -96,14 +92,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header,
|
|||
void
|
||||
nsHttpHeaderArray::ClearHeader(nsHttpAtom header)
|
||||
{
|
||||
nsEntry *entry = nsnull;
|
||||
PRInt32 index;
|
||||
|
||||
index = LookupEntry(header, &entry);
|
||||
if (entry) {
|
||||
mHeaders.RemoveElementAt(index);
|
||||
delete entry;
|
||||
}
|
||||
mHeaders.RemoveElement(header, nsEntry::MatchHeader());
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -129,10 +118,11 @@ nsresult
|
|||
nsHttpHeaderArray::VisitHeaders(nsIHttpHeaderVisitor *visitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(visitor);
|
||||
PRInt32 i, count = mHeaders.Count();
|
||||
for (i=0; i<count; ++i) {
|
||||
nsEntry *entry = (nsEntry *) mHeaders[i];
|
||||
if (NS_FAILED(visitor->VisitHeader(nsDependentCString(entry->header), entry->value)))
|
||||
PRUint32 i, count = mHeaders.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
const nsEntry &entry = mHeaders[i];
|
||||
if (NS_FAILED(visitor->VisitHeader(nsDependentCString(entry.header),
|
||||
entry.value)))
|
||||
break;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -206,16 +196,16 @@ nsHttpHeaderArray::ParseHeaderLine(char *line, nsHttpAtom *hdr, char **val)
|
|||
void
|
||||
nsHttpHeaderArray::Flatten(nsACString &buf, PRBool pruneProxyHeaders)
|
||||
{
|
||||
PRInt32 i, count = mHeaders.Count();
|
||||
for (i=0; i<count; ++i) {
|
||||
nsEntry *entry = (nsEntry *) mHeaders[i];
|
||||
PRUint32 i, count = mHeaders.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
const nsEntry &entry = mHeaders[i];
|
||||
// prune proxy headers if requested
|
||||
if (pruneProxyHeaders && ((entry->header == nsHttp::Proxy_Authorization) ||
|
||||
(entry->header == nsHttp::Proxy_Connection)))
|
||||
if (pruneProxyHeaders && ((entry.header == nsHttp::Proxy_Authorization) ||
|
||||
(entry.header == nsHttp::Proxy_Connection)))
|
||||
continue;
|
||||
buf.Append(entry->header);
|
||||
buf.Append(entry.header);
|
||||
buf.AppendLiteral(": ");
|
||||
buf.Append(entry->value);
|
||||
buf.Append(entry.value);
|
||||
buf.AppendLiteral("\r\n");
|
||||
}
|
||||
}
|
||||
|
@ -223,20 +213,15 @@ nsHttpHeaderArray::Flatten(nsACString &buf, PRBool pruneProxyHeaders)
|
|||
const char *
|
||||
nsHttpHeaderArray::PeekHeaderAt(PRUint32 index, nsHttpAtom &header)
|
||||
{
|
||||
nsEntry *entry = (nsEntry *) mHeaders[index];
|
||||
if (!entry)
|
||||
return nsnull;
|
||||
const nsEntry &entry = mHeaders[index];
|
||||
|
||||
header = entry->header;
|
||||
return entry->value.get();
|
||||
header = entry.header;
|
||||
return entry.value.get();
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpHeaderArray::Clear()
|
||||
{
|
||||
PRInt32 i, count = mHeaders.Count();
|
||||
for (i=0; i<count; ++i)
|
||||
delete (nsEntry *) mHeaders[i];
|
||||
mHeaders.Clear();
|
||||
}
|
||||
|
||||
|
@ -247,14 +232,10 @@ nsHttpHeaderArray::Clear()
|
|||
PRInt32
|
||||
nsHttpHeaderArray::LookupEntry(nsHttpAtom header, nsEntry **entry)
|
||||
{
|
||||
PRInt32 i, count = mHeaders.Count();
|
||||
for (i=0; i<count; ++i) {
|
||||
*entry = (nsEntry *) mHeaders[i];
|
||||
if ((*entry)->header == header)
|
||||
return i;
|
||||
}
|
||||
*entry = nsnull;
|
||||
return -1;
|
||||
PRUint32 index = mHeaders.IndexOf(header, 0, nsEntry::MatchHeader());
|
||||
if (index != PR_UINT32_MAX)
|
||||
*entry = &mHeaders[index];
|
||||
return index;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#ifndef nsHttpHeaderArray_h__
|
||||
#define nsHttpHeaderArray_h__
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -58,6 +58,17 @@ public:
|
|||
nsresult GetHeader(nsHttpAtom header, nsACString &value);
|
||||
void ClearHeader(nsHttpAtom h);
|
||||
|
||||
// Find the location of the given header value, or null if none exists.
|
||||
const char *FindHeaderValue(nsHttpAtom header, const char *value) {
|
||||
return nsHttp::FindToken(PeekHeader(header), value,
|
||||
HTTP_HEADER_VALUE_SEPS);
|
||||
}
|
||||
|
||||
// Determine if the given header value exists.
|
||||
PRBool HasHeaderValue(nsHttpAtom header, const char *value) {
|
||||
return FindHeaderValue(header, value) != nsnull;
|
||||
}
|
||||
|
||||
nsresult VisitHeaders(nsIHttpHeaderVisitor *visitor);
|
||||
|
||||
// parse a header line, return the header atom and a pointer to the
|
||||
|
@ -66,7 +77,7 @@ public:
|
|||
|
||||
void Flatten(nsACString &, PRBool pruneProxyHeaders=PR_FALSE);
|
||||
|
||||
PRUint32 Count() { return (PRUint32) mHeaders.Count(); }
|
||||
PRUint32 Count() { return mHeaders.Length(); }
|
||||
|
||||
const char *PeekHeaderAt(PRUint32 i, nsHttpAtom &header);
|
||||
|
||||
|
@ -75,18 +86,23 @@ public:
|
|||
private:
|
||||
struct nsEntry
|
||||
{
|
||||
nsEntry(nsHttpAtom h, const nsACString &v)
|
||||
: header(h) { value = v; }
|
||||
nsEntry() {}
|
||||
|
||||
nsHttpAtom header;
|
||||
nsCString value;
|
||||
|
||||
struct MatchHeader {
|
||||
PRBool Equals(const nsEntry &entry, const nsHttpAtom &header) const {
|
||||
return entry.header == header;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
PRInt32 LookupEntry(nsHttpAtom header, nsEntry **);
|
||||
PRBool CanAppendToHeader(nsHttpAtom header);
|
||||
|
||||
private:
|
||||
nsAutoVoidArray mHeaders;
|
||||
nsTArray<nsEntry> mHeaders;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,6 +70,9 @@ public:
|
|||
void ClearHeader(nsHttpAtom h) { mHeaders.ClearHeader(h); }
|
||||
void ClearHeaders() { mHeaders.Clear(); }
|
||||
|
||||
const char *FindHeaderValue(nsHttpAtom h, const char *v) { return mHeaders.FindHeaderValue(h, v); }
|
||||
PRBool HasHeaderValue(nsHttpAtom h, const char *v) { return mHeaders.HasHeaderValue(h, v); }
|
||||
|
||||
void Flatten(nsACString &, PRBool pruneProxyHeaders = PR_FALSE);
|
||||
|
||||
private:
|
||||
|
|
|
@ -387,8 +387,7 @@ nsHttpResponseHead::MustValidateIfExpired()
|
|||
// cache, that cache MUST NOT use the entry after it becomes stale to respond to
|
||||
// a subsequent request without first revalidating it with the origin server.
|
||||
//
|
||||
const char *val = PeekHeader(nsHttp::Cache_Control);
|
||||
return val && PL_strcasestr(val, "must-revalidate");
|
||||
return HasHeaderValue(nsHttp::Cache_Control, "must-revalidate");
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -399,7 +398,7 @@ nsHttpResponseHead::IsResumable()
|
|||
return mVersion >= NS_HTTP_VERSION_1_1 &&
|
||||
PeekHeader(nsHttp::Content_Length) &&
|
||||
(PeekHeader(nsHttp::ETag) || PeekHeader(nsHttp::Last_Modified)) &&
|
||||
PL_strcasestr(PeekHeader(nsHttp::Accept_Ranges), "bytes");
|
||||
HasHeaderValue(nsHttp::Accept_Ranges, "bytes");
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -631,18 +630,13 @@ nsHttpResponseHead::ParseCacheControl(const char *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")) != nsnull) {
|
||||
s += (sizeof("no-cache") - 1);
|
||||
if (*s != '=')
|
||||
mCacheControlNoCache = PR_TRUE;
|
||||
}
|
||||
if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS))
|
||||
mCacheControlNoCache = PR_TRUE;
|
||||
|
||||
// search header value for occurance of "no-store"
|
||||
if (PL_strcasestr(val, "no-store"))
|
||||
if (nsHttp::FindToken(val, "no-store", HTTP_HEADER_VALUE_SEPS))
|
||||
mCacheControlNoStore = PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -660,6 +654,6 @@ nsHttpResponseHead::ParsePragma(const char *val)
|
|||
// 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 (PL_strcasestr(val, "no-cache"))
|
||||
if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS))
|
||||
mPragmaNoCache = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,9 @@ public:
|
|||
void ClearHeader(nsHttpAtom h) { mHeaders.ClearHeader(h); }
|
||||
void ClearHeaders() { mHeaders.Clear(); }
|
||||
|
||||
const char *FindHeaderValue(nsHttpAtom h, const char *v) { return mHeaders.FindHeaderValue(h, v); }
|
||||
PRBool HasHeaderValue(nsHttpAtom h, const char *v) { return mHeaders.HasHeaderValue(h, v); }
|
||||
|
||||
void SetContentType(const nsACString &s) { mContentType = s; }
|
||||
void SetContentCharset(const nsACString &s) { mContentCharset = s; }
|
||||
void SetContentLength(PRInt64);
|
||||
|
|
|
@ -775,8 +775,7 @@ nsHttpTransaction::HandleContentStart()
|
|||
// we're done with the socket. please note that _all_ other
|
||||
// decoding is done when the channel receives the content data
|
||||
// so as not to block the socket transport thread too much.
|
||||
const char *val = mResponseHead->PeekHeader(nsHttp::Transfer_Encoding);
|
||||
if (PL_strcasestr(val, "chunked")) {
|
||||
if (mResponseHead->HasHeaderValue(nsHttp::Transfer_Encoding, "chunked")) {
|
||||
// we only support the "chunked" transfer encoding right now.
|
||||
mChunkedDecoder = new nsHttpChunkedDecoder();
|
||||
if (!mChunkedDecoder)
|
||||
|
|
Загрузка…
Ссылка в новой задаче