Move processing of various headers from the content sink into the document so

it'll happen for all of our document types.  Bug 288921, r+sr=jst
This commit is contained in:
bzbarsky%mit.edu 2005-04-05 03:28:54 +00:00
Родитель 415fdc9b6e
Коммит f2c4953613
5 изменённых файлов: 93 добавлений и 67 удалений

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

@ -44,8 +44,6 @@
#include "nsINodeInfo.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIWebNavigation.h"
#include "nsIRefreshURI.h"
#include "nsCPrefetchService.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
@ -185,8 +183,6 @@ nsContentSink::Init(nsIDocument* aDoc,
mCSSLoader = aDoc->GetCSSLoader();
// XXX this presumes HTTP header info is already set in document
// XXX if it isn't we need to set it here...
ProcessHTTPHeaders(aChannel);
mNodeInfoManager = aDoc->NodeInfoManager();
@ -292,28 +288,16 @@ nsContentSink::ProcessHTTPHeaders(nsIChannel* aChannel)
return NS_OK;
}
static const char *const headers[] = {
"link",
"default-style",
"content-style-type",
"content-language",
"content-disposition",
// add more http headers if you need
// XXXbz don't add content-location support without reading bug
// 238654 and its dependencies/dups first.
0
};
// Note that the only header we care about is the "link" header, since we
// have all the infrastructure for kicking off stylesheet loads.
const char *const *name = headers;
nsCAutoString tmp;
nsCAutoString linkHeader;
while (*name) {
nsresult rv = httpchannel->GetResponseHeader(nsDependentCString(*name), tmp);
if (NS_SUCCEEDED(rv) && !tmp.IsEmpty()) {
nsCOMPtr<nsIAtom> key = do_GetAtom(*name);
ProcessHeaderData(key, NS_ConvertASCIItoUCS2(tmp));
}
++name;
nsresult rv = httpchannel->GetResponseHeader(NS_LITERAL_CSTRING("link"),
linkHeader);
if (NS_SUCCEEDED(rv) && !linkHeader.IsEmpty()) {
ProcessHeaderData(nsHTMLAtoms::link,
NS_ConvertASCIItoUTF16(linkHeader));
}
return NS_OK;
@ -328,29 +312,11 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
mDocument->SetHeaderData(aHeader, aValue);
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
// see if we have a refresh "header".
if (aHeader == nsHTMLAtoms::refresh) {
// first get our baseURI
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(mDocShell);
rv = webNav->GetCurrentURI(getter_AddRefs(baseURI));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIRefreshURI> reefer = do_QueryInterface(mDocShell);
if (reefer) {
rv = reefer->SetupRefreshURIFromHeader(baseURI,
NS_ConvertUCS2toUTF8(aValue));
if (NS_FAILED(rv)) {
return rv;
}
}
}
else if (aHeader == nsHTMLAtoms::setcookie) {
if (aHeader == nsHTMLAtoms::setcookie) {
// Note: Necko already handles cookies set via the channel. We can't just
// call SetCookie on the channel because we want to do some security checks
// here and want to use the prompt associated to our current window, not
// the window where the channel was dispatched.
nsCOMPtr<nsICookieService> cookieServ =
do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
@ -405,6 +371,7 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
}
else if (aHeader == nsHTMLAtoms::msthemecompatible) {
// Disable theming for the presshell if the value is no.
// XXXbz don't we want to support this as an HTTP header too?
nsAutoString value(aValue);
if (value.LowerCaseEqualsLiteral("no")) {
nsIPresShell* shell = mDocument->GetShellAt(0);
@ -413,7 +380,9 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
}
}
}
else if (mParser) {
// Don't report "refresh" headers back to necko, since our document handles
// them
else if (aHeader != nsHTMLAtoms::refresh && mParser) {
// we also need to report back HTTP-EQUIV headers to the channel
// so that it can process things like pragma: no-cache or other
// cache-control headers. Ideally this should also be the way for

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

@ -85,6 +85,9 @@
#include "nsIXBLService.h"
#include "nsIXPointer.h"
#include "nsIFileChannel.h"
#include "nsIMultiPartChannel.h"
#include "nsIRefreshURI.h"
#include "nsIWebNavigation.h"
#include "nsNetUtil.h" // for NS_MakeAbsoluteURI
@ -1081,7 +1084,7 @@ nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
NS_STATIC_CAST(nsIObserver *, mCharSetObservers.ElementAt(i));
observer->Observe(NS_STATIC_CAST(nsIDocument *, this), "charset",
NS_ConvertASCIItoUCS2(aCharSetID).get());
NS_ConvertASCIItoUTF16(aCharSetID).get());
}
}
}
@ -1234,6 +1237,21 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
}
}
}
if (aHeaderField == nsHTMLAtoms::refresh) {
// We get into this code before we have a script global yet, so get to
// our container via mDocumentContainer.
nsCOMPtr<nsIRefreshURI> refresher = do_QueryReferent(mDocumentContainer);
if (refresher) {
// Note: using mDocumentURI instead of mBaseURI here, for consistency
// (used to just use the current URI of our webnavigation, but that
// should really be the same thing). Note that this code can run
// before the current URI of the webnavigation has been updated, so we
// can't assert equality here.
refresher->SetupRefreshURIFromHeader(mDocumentURI,
NS_LossyConvertUTF16toASCII(aData));
}
}
}
PRBool
@ -4361,6 +4379,30 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
if (NS_FAILED(rv)) {
mReferrer.Truncate();
}
static const char *const headers[] = {
"default-style",
"content-style-type",
"content-language",
"content-disposition",
"refresh",
// add more http headers if you need
// XXXbz don't add content-location support without reading bug
// 238654 and its dependencies/dups first.
0
};
nsCAutoString headerVal;
const char *const *name = headers;
while (*name) {
rv =
httpChannel->GetResponseHeader(nsDependentCString(*name), headerVal);
if (NS_SUCCEEDED(rv) && !headerVal.IsEmpty()) {
nsCOMPtr<nsIAtom> key = do_GetAtom(*name);
SetHeaderData(key, NS_ConvertASCIItoUCS2(headerVal));
}
++name;
}
} else {
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(aChannel);
if (fileChannel) {
@ -4376,6 +4418,16 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
LL_MUL(modDate, msecs, intermediateValue);
}
}
} else {
nsCOMPtr<nsIMultiPartChannel> partChannel = do_QueryInterface(aChannel);
if (partChannel) {
nsCAutoString contentDisp;
rv = partChannel->GetContentDisposition(contentDisp);
if (NS_SUCCEEDED(rv) && !contentDisp.IsEmpty()) {
SetHeaderData(nsHTMLAtoms::headerContentDisposition,
NS_ConvertASCIItoUCS2(contentDisp));
}
}
}
}

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

@ -167,8 +167,6 @@ nsMediaDocument::StartDocumentLoad(const char* aCommand,
return rv;
}
RetrieveRelevantHeaders(aChannel);
// We try to set the charset of the current document to that of the
// 'genuine' (as opposed to an intervening 'chrome') parent document
// that may be in a different window/tab. Even if we fail here,

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

@ -4278,22 +4278,16 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
NS_IMETHODIMP nsDocShell::SetupRefreshURI(nsIChannel * aChannel)
{
nsresult
rv;
nsresult rv;
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel, &rv));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIURI> referrer;
rv = httpChannel->GetReferrer(getter_AddRefs(referrer));
nsCAutoString refreshHeader;
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("refresh"),
refreshHeader);
if (NS_SUCCEEDED(rv)) {
SetReferrerURI(referrer);
nsCAutoString refreshHeader;
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("refresh"),
refreshHeader);
if (!refreshHeader.IsEmpty())
rv = SetupRefreshURIFromHeader(mCurrentURI, refreshHeader);
if (!refreshHeader.IsEmpty()) {
SetupReferrerFromChannel(aChannel);
rv = SetupRefreshURIFromHeader(mCurrentURI, refreshHeader);
}
}
return rv;
@ -6220,6 +6214,18 @@ nsDocShell::ScrollIfAnchor(nsIURI * aURI, PRBool * aWasAnchor,
return rv;
}
void
nsDocShell::SetupReferrerFromChannel(nsIChannel * aChannel)
{
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
if (httpChannel) {
nsCOMPtr<nsIURI> referrer;
nsresult rv = httpChannel->GetReferrer(getter_AddRefs(referrer));
if (NS_SUCCEEDED(rv)) {
SetReferrerURI(referrer);
}
}
}
PRBool
nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel,
@ -6356,9 +6362,8 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel,
}
PRBool onLocationChangeNeeded = SetCurrentURI(aURI, aChannel,
aFireOnLocationChange);
// if there's a refresh header in the channel, this method
// will set it up for us.
SetupRefreshURI(aChannel);
// Make sure to store the referrer from the channel, if any
SetupReferrerFromChannel(aChannel);
return onLocationChangeNeeded;
}

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

@ -274,6 +274,8 @@ protected:
nsIStreamListener ** aContentHandler, nsIContentViewer ** aViewer);
NS_IMETHOD SetupNewViewer(nsIContentViewer * aNewViewer);
void SetupReferrerFromChannel(nsIChannel * aChannel);
NS_IMETHOD GetEldestPresContext(nsPresContext** aPresContext);
void GetCurrentDocumentOwner(nsISupports ** aOwner);
virtual nsresult DoURILoad(nsIURI * aURI,