diff --git a/mozilla/content/base/src/nsContentSink.cpp b/mozilla/content/base/src/nsContentSink.cpp index 71da88deba6..bcc57729ff5 100644 --- a/mozilla/content/base/src/nsContentSink.cpp +++ b/mozilla/content/base/src/nsContentSink.cpp @@ -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 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 baseURI; - nsCOMPtr webNav = do_QueryInterface(mDocShell); - rv = webNav->GetCurrentURI(getter_AddRefs(baseURI)); - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr 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 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 diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index e87f1ec126d..8b9175c6ce8 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -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 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 key = do_GetAtom(*name); + SetHeaderData(key, NS_ConvertASCIItoUCS2(headerVal)); + } + ++name; + } } else { nsCOMPtr fileChannel = do_QueryInterface(aChannel); if (fileChannel) { @@ -4376,6 +4418,16 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel) LL_MUL(modDate, msecs, intermediateValue); } } + } else { + nsCOMPtr partChannel = do_QueryInterface(aChannel); + if (partChannel) { + nsCAutoString contentDisp; + rv = partChannel->GetContentDisposition(contentDisp); + if (NS_SUCCEEDED(rv) && !contentDisp.IsEmpty()) { + SetHeaderData(nsHTMLAtoms::headerContentDisposition, + NS_ConvertASCIItoUCS2(contentDisp)); + } + } } } diff --git a/mozilla/content/html/document/src/nsMediaDocument.cpp b/mozilla/content/html/document/src/nsMediaDocument.cpp index 4c90eb36aa9..f57cbe8e2a3 100644 --- a/mozilla/content/html/document/src/nsMediaDocument.cpp +++ b/mozilla/content/html/document/src/nsMediaDocument.cpp @@ -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, diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 65b929ff09f..fadb5531f90 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -4278,22 +4278,16 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI, NS_IMETHODIMP nsDocShell::SetupRefreshURI(nsIChannel * aChannel) { - nsresult - rv; + nsresult rv; nsCOMPtr httpChannel(do_QueryInterface(aChannel, &rv)); if (NS_SUCCEEDED(rv)) { - nsCOMPtr 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 httpChannel(do_QueryInterface(aChannel)); + if (httpChannel) { + nsCOMPtr 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; } diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h index afff3ce05f6..fbcde1601bb 100644 --- a/mozilla/docshell/base/nsDocShell.h +++ b/mozilla/docshell/base/nsDocShell.h @@ -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,