Mozilla/mozilla/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
darin%netscape.com 1f831ea881 Fixes bug 80939 "Sherlock plugin updating fails due to incorrectly cached HTTP HEAD request" r=gagan, sr=dougt
git-svn-id: svn://10.0.0.236/trunk@95161 18797224-902f-48f8-a5cc-f745e15eee43
2001-05-16 23:58:06 +00:00

171 lines
5.0 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com> (original author)
*/
#include "nsHttpHeaderArray.h"
#include "nsHttp.h"
//-----------------------------------------------------------------------------
// nsHttpHeaderArray <public>
//-----------------------------------------------------------------------------
nsresult
nsHttpHeaderArray::SetHeader(nsHttpAtom header, const char *value)
{
nsEntry *entry = nsnull;
PRInt32 index;
// If a NULL value is passed in, then delete the header entry...
index = LookupEntry(header, &entry);
if (!value) {
if (entry) {
mHeaders.RemoveElementAt(index);
delete entry;
}
return NS_OK;
}
// Create a new entry or...
if (!entry) {
entry = new nsEntry(header, value);
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
if (!mHeaders.AppendElement(entry)) {
NS_WARNING("AppendElement failed");
delete entry;
}
}
// Append the new value to the existing value iff...
else if (CanAppendToHeader(header)) {
if (header == nsHttp::Set_Cookie ||
header == nsHttp::WWW_Authenticate ||
header == nsHttp::Proxy_Authenticate)
// Special case these headers and use a newline delimiter to
// delimit the values from one another as commas may appear
// in the values of these headers contrary to what the spec says.
entry->value.Append('\n');
else
// Delimit each value from the others using a comma (per HTTP spec)
entry->value.Append(", ");
entry->value.Append(value);
}
// Replace the existing string with the new value
else
entry->value = value;
return NS_OK;
}
const char *
nsHttpHeaderArray::PeekHeader(nsHttpAtom header)
{
nsEntry *entry = nsnull;
LookupEntry(header, &entry);
return entry ? entry->value.get() : nsnull;
}
nsresult
nsHttpHeaderArray::GetHeader(nsHttpAtom header, char **result)
{
const char *val = PeekHeader(header);
return val ? DupString(val, result) : NS_ERROR_NOT_AVAILABLE;
}
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(entry->header, entry->value.get())))
break;
}
return NS_OK;
}
void
nsHttpHeaderArray::Flatten(nsACString &buf)
{
PRInt32 i, count = mHeaders.Count();
for (i=0; i<count; ++i) {
nsEntry *entry = (nsEntry *) mHeaders[i];
buf.Append(entry->header);
buf.Append(": ");
buf.Append(entry->value);
buf.Append("\r\n");
}
}
const char *
nsHttpHeaderArray::PeekHeaderAt(PRUint32 index, nsHttpAtom &header)
{
nsEntry *entry = (nsEntry *) mHeaders[index];
if (!entry)
return nsnull;
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();
}
//-----------------------------------------------------------------------------
// nsHttpHeaderArray <private>
//-----------------------------------------------------------------------------
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;
}
PRBool
nsHttpHeaderArray::CanAppendToHeader(nsHttpAtom header)
{
return header == nsHttp::Accept_Charset ||
header == nsHttp::User_Agent ||
header == nsHttp::Referer ||
header == nsHttp::Host ||
header == nsHttp::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;
}