diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp
index 40b05439244..5ad464bf19a 100644
--- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp
+++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp
@@ -19,6 +19,7 @@
*
* Contributor(s):
* Pierre Phaneuf
+ * Peter Annema
*/
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
@@ -4298,15 +4299,14 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
*getter_AddRefs(nodeInfo));
NS_ENSURE_SUCCESS(rv, rv);
- nsIHTMLContent* it;
- rv = NS_NewHTMLMetaElement(&it, nodeInfo);
+ nsCOMPtr it;
+ rv = NS_NewHTMLMetaElement(getter_AddRefs(it), nodeInfo);
if (NS_OK == rv) {
// Add in the attributes and add the meta content object to the
// head container.
it->SetDocument(mDocument, PR_FALSE, PR_TRUE);
rv = AddAttributes(aNode, it);
- if (NS_OK != rv) {
- NS_RELEASE(it);
+ if (NS_FAILED(rv)) {
return rv;
}
parent->AppendChildTo(it, PR_FALSE, PR_FALSE);
@@ -4328,7 +4328,6 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
}//if (result.Length() > 0)
}//if (header.Length() > 0)
}//if(!mInsideNoXXXTag)
- NS_RELEASE(it);
}//if (NS_OK == rv)
}//if (nsnull != parent)
@@ -4375,42 +4374,6 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,nsString& aValue,nsIHTMLCont
// see if we have a refresh "header".
if (aHeader == nsHTMLAtoms::refresh) {
- // Refresh headers are parsed with the following format in mind
- //
- // By the time we are here, the following is true:
- // header = "REFRESH"
- // result = "5; URL=http://uri" // note the URL attribute is
- // optional, if it is absent, the currently loaded url is used.
- // Also note that the second and URL seperator can be either a ';'
- // or a ','. This breaks some websites. The ',' seperator should be
- // illegal but CNN is using it.
-
- //
- // We need to handle the following strings.
- // - X is a set of digits
- // - URI is either a relative or absolute URI
- // - FOO is any text
- //
- // ""
- // empty string. use the currently loaded URI
- // and refresh immediately.
- // "X"
- // Refresh the currently loaded URI in X milliseconds.
- // "X; URI"
- // Refresh using URI as the destination in X milliseconds.
- // "X; URI; Blah"
- // Refresh using URI as the destination in X milliseconds,
- // ignoring "Blah"
- // "URI"
- // Refresh immediately using URI as the destination.
- // "URI; Blah"
- // Refresh immediately using URI as the destination,
- // ignoring "Blah"
- //
- // Note that we need to remove any tokens wrapping the URI.
- // These tokens currently include spaces, double and single
- // quotes.
-
// first get our baseURI
nsCOMPtr docShell = do_QueryInterface(mWebShell, &rv);
if (NS_FAILED(rv)) return rv;
@@ -4419,96 +4382,12 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,nsString& aValue,nsIHTMLCont
nsCOMPtr webNav = do_QueryInterface(docShell);
rv = webNav->GetCurrentURI(getter_AddRefs(baseURI));
if (NS_FAILED(rv)) return rv;
-
- PRInt32 millis = -1;
- nsAutoString uriAttrib;
-
- PRInt32 semiColon = aValue.FindCharInSet(";,");
- nsAutoString token;
- if (semiColon > -1)
- aValue.Left(token, semiColon);
- else
- token = aValue;
-
- PRBool done = PR_FALSE;
- while (!done && !token.IsEmpty()) {
- token.CompressWhitespace();
- // Ref. bug 22886
- // Apparently CONTENT can also start with a period (.).
- // Ex:
- // So let's relax a little bit otherwise http://www.mozillazine.org/resources/
- // wouldn't get redirected to the correct URL.
- if (millis == -1 && (nsCRT::IsAsciiDigit(token.First()) || token.First()==PRUnichar('.'))) {
- PRBool tokenIsANumber = PR_TRUE;
- nsReadingIterator doneIterating; token.EndReading(doneIterating);
- nsReadingIterator iter; token.BeginReading(iter);
- while ( iter != doneIterating ) {
- if (!(tokenIsANumber = nsCRT::IsAsciiDigit(*iter)) && *iter!=PRUnichar('.'))
- break;
- ++iter;
- }
-
- if (tokenIsANumber) {
- PRInt32 err;
- millis = token.ToInteger(&err) * 1000;
- }
- else {
- done = PR_TRUE;
- }
- }
- else {
- done = PR_TRUE;
- }
- if (done) {
- PRInt32 loc = token.FindChar('=');
- if (loc > -1)
- token.Cut(0, loc+1);
- token.Trim(" \"'");
- uriAttrib.Assign(token);
- }
- else {
- // Increment to the next token.
- if (semiColon > -1) {
- semiColon++;
- PRInt32 semiColon2 = aValue.FindCharInSet(";,", semiColon);
- if (semiColon2 == -1) semiColon2 = aValue.Length();
- aValue.Mid(token, semiColon, semiColon2 - semiColon);
- semiColon = semiColon2;
- }
- else {
- done = PR_TRUE;
- }
- }
- } // end while
-
- nsCOMPtr uri;
- if (uriAttrib.Length() == 0) {
- uri = baseURI;
- } else {
- rv = NS_NewURI(getter_AddRefs(uri),
- uriAttrib, baseURI);
+
+ nsCOMPtr reefer = do_QueryInterface(mWebShell);
+ if (reefer) {
+ rv = reefer->RefreshURIFromHeader(baseURI, aValue);
+ if (NS_FAILED(rv)) return rv;
}
-
- if (NS_SUCCEEDED(rv)) {
- NS_WITH_SERVICE(nsIScriptSecurityManager,
- securityManager,
- NS_SCRIPTSECURITYMANAGER_CONTRACTID,
- &rv);
- if (NS_SUCCEEDED(rv)) {
- rv = securityManager->CheckLoadURI(baseURI,
- uri,
- nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
- if (NS_SUCCEEDED(rv)) {
- nsCOMPtr reefer =
- do_QueryInterface(mWebShell);
- if (reefer) {
- if (millis == -1) millis = 0;
- rv = reefer->RefreshURI(uri, millis,PR_FALSE, PR_TRUE);
- if (NS_FAILED(rv)) return rv;
- }//if (reefer)
- }//if (NS_SUCCEEDED(rv)) {
- }//if (NS_SUCCEEDED(rv)) {
- }//if (NS_SUCCEEDED(rv)) {
} // END refresh
else if (aHeader == nsHTMLAtoms::setcookie) {
nsCOMPtr docShell = do_QueryInterface(mWebShell, &rv);
diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp
index e76334fb78c..22f18521635 100644
--- a/mozilla/docshell/base/nsDocShell.cpp
+++ b/mozilla/docshell/base/nsDocShell.cpp
@@ -19,6 +19,7 @@
* Contributor(s):
* Travis Bogard
* Pierre Phaneuf
+ * Peter Annema
*/
#include "nsIComponentManager.h"
@@ -3833,92 +3834,198 @@ nsDocShell::OnNewURI(nsIURI *aURI, nsIChannel *aChannel, PRUint32 aLoadType)
return NS_OK;
}
+nsresult
+nsDocShell::RefreshURIFromHeader(nsIURI* aBaseURI, const nsAReadableString& aHeader)
+{
+ // Refresh headers are parsed with the following format in mind
+ //
+ // By the time we are here, the following is true:
+ // header = "REFRESH"
+ // content = "5; URL=http://uri" // note the URL attribute is
+ // optional, if it is absent, the currently loaded url is used.
+ // Also note that the seconds and URL separator can be either
+ // a ';' or a ','. The ',' separator should be illegal but CNN
+ // is using it.
+ //
+ // We need to handle the following strings, where
+ // - X is a set of digits
+ // - URI is either a relative or absolute URI
+ //
+ // Note that URI should start with "url=" but we allow omission
+ //
+ // "" || ";" || ","
+ // empty string. use the currently loaded URI
+ // and refresh immediately.
+ // "X" || "X;" || "X,"
+ // Refresh the currently loaded URI in X seconds.
+ // "X; URI" || "X, URI"
+ // Refresh using URI as the destination in X seconds.
+ // "URI" || "; URI" || ", URI"
+ // Refresh immediately using URI as the destination.
+ //
+ // Currently, anything immediately following the URI, if
+ // seperated by any char in the set "'\"\t\r\n " will be
+ // ignored. So "10; url=go.html ; foo=bar" will work,
+ // and so will "10; url='go.html'; foo=bar". However,
+ // "10; url=go.html; foo=bar" will result in the uri
+ // "go.html;" since ';' and ',' are valid uri characters.
+ //
+ // Note that we need to remove any tokens wrapping the URI.
+ // These tokens currently include spaces, double and single
+ // quotes.
+
+ // when done, seconds is 0 or the given number of seconds
+ // uriAttrib is empty or the URI specified
+ nsAutoString uriAttrib;
+ PRInt32 seconds = 0;
+
+ nsReadingIterator iter, tokenStart, doneIterating;
+
+ aHeader.BeginReading(iter);
+ aHeader.EndReading(doneIterating);
+
+ // skip leading whitespace
+ while (iter != doneIterating && nsCRT::IsAsciiSpace(*iter))
+ ++iter;
+
+ tokenStart = iter;
+
+ // skip leading + and -
+ if (iter != doneIterating && (*iter == '-' || *iter == '+'))
+ ++iter;
+
+ // parse number
+ while (iter != doneIterating && (*iter >= '0' && *iter <= '9')) {
+ seconds = seconds * 10 + (*iter - '0');
+ ++iter;
+ }
+
+ // bug 22886, part 2: allow X to start with or contain a '.'
+ if (iter != doneIterating && *iter == '.') {
+ ++iter;
+ // throw away any digits following it
+ while (iter != doneIterating && (*iter >= '0' && *iter <= '9'))
+ ++iter;
+ }
+
+ if (iter != doneIterating) {
+ // if this isn't whitespace, a ';' or a ',', we just parsed part of a URI
+ if (!(nsCRT::IsAsciiSpace(*iter) || *iter == ';' || *iter == ',')) {
+ // back to square 1
+ iter = tokenStart;
+ seconds = 0;
+ } else {
+ // if we started with a '-', number is negative
+ if (*tokenStart == '-')
+ seconds = -seconds;
+
+ // skip whitespace
+ while (iter != doneIterating && nsCRT::IsAsciiSpace(*iter))
+ ++iter;
+
+ // skip ';' or ','
+ if (iter != doneIterating && (*iter == ';' || *iter == ',')) {
+ ++iter;
+
+ // skip whitespace
+ while (iter != doneIterating && nsCRT::IsAsciiSpace(*iter))
+ ++iter;
+ }
+ }
+ }
+
+ // possible start of URI
+ tokenStart = iter;
+
+ // skip "url = " to real start of URI
+ if (iter != doneIterating && (*iter == 'u' || *iter == 'U')) {
+ ++iter;
+ if (iter != doneIterating && (*iter == 'r' || *iter == 'R')) {
+ ++iter;
+ if (iter != doneIterating && (*iter == 'l' || *iter == 'L')) {
+ ++iter;
+
+ // skip whitespace
+ while (iter != doneIterating && nsCRT::IsAsciiSpace(*iter))
+ ++iter;
+
+ if (iter != doneIterating && *iter == '=') {
+ ++iter;
+
+ // skip whitespace
+ while (iter != doneIterating && nsCRT::IsAsciiSpace(*iter))
+ ++iter;
+
+ // found real start of URI
+ tokenStart = iter;
+ }
+ }
+ }
+ }
+
+ // skip a leading '"' (believe it or not, '\'' is a valid URI char)
+ if (tokenStart != doneIterating && *tokenStart == '"')
+ ++tokenStart;
+
+ // set iter to start of URI
+ iter = tokenStart;
+
+ // tokenStart here points to the beginning of URI
+
+ // skip anything which isn't whitespace or '"')
+ while (iter != doneIterating && !(nsCRT::IsAsciiSpace(*iter) || *iter == '"'))
+ ++iter;
+
+ // URI is whatever's contained from tokenStart to iter.
+ // note: if tokenStart == doneIterating, so is iter.
+
+ nsresult rv = NS_OK;
+
+ nsCOMPtr uri;
+ if (tokenStart == iter) {
+ uri = aBaseURI;
+ } else {
+ uriAttrib = Substring(tokenStart, iter);
+ rv = NS_NewURI(getter_AddRefs(uri), uriAttrib, aBaseURI);
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
+ if (NS_SUCCEEDED(rv)) {
+ rv = securityManager->CheckLoadURI(aBaseURI, uri, nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
+ if (NS_SUCCEEDED(rv)) {
+ // since we can't travel back in time yet, just pretend it was meant figuratively
+ if (seconds < 0)
+ seconds = 0;
+
+ rv = RefreshURI(uri, seconds * 1000, PR_FALSE, PR_TRUE);
+ }
+ }
+ }
+ return rv;
+}
+
NS_IMETHODIMP
nsDocShell::SetupRefreshURI(nsIChannel * aChannel)
{
- nsCOMPtr httpChannel(do_QueryInterface(aChannel));
- if(httpChannel)
- {
- nsCOMPtr referrer;
- httpChannel->GetReferrer(getter_AddRefs(referrer));
+ nsresult rv;
+ nsCOMPtr httpChannel(do_QueryInterface(aChannel, &rv));
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr referrer;
+ rv = httpChannel->GetReferrer(getter_AddRefs(referrer));
+
+ if (NS_SUCCEEDED(rv)) {
SetReferrerURI(referrer);
+ nsCOMPtr refreshAtom(dont_AddRef(NS_NewAtom("refresh")));
nsXPIDLCString refreshHeader;
- nsCOMPtr refreshAtom ( dont_AddRef( NS_NewAtom("refresh") ) );
-
- httpChannel -> GetResponseHeader (refreshAtom, getter_Copies (refreshHeader));
+ rv = httpChannel->GetResponseHeader(refreshAtom, getter_Copies(refreshHeader));
if (refreshHeader)
- {
- nsCOMPtr baseURI = mCurrentURI;
-
- PRInt32 millis = -1;
- nsAutoString uriAttrib;
- nsString result; result.AssignWithConversion (refreshHeader);
-
- PRInt32 semiColon = result.FindCharInSet(";,");
- nsAutoString token;
- if (semiColon > -1)
- result.Left(token, semiColon);
- else
- token = result;
-
- PRBool done = PR_FALSE;
- while (!done && !token.IsEmpty()) {
- token.CompressWhitespace();
- if (millis == -1 && nsCRT::IsAsciiDigit(token.First())) {
- PRInt32 i = 0;
- PRUnichar value = nsnull;
- for ( ; i < (PRInt32) token.Length (); i++)
- {
- value = token[i];
- if (!nsCRT::IsAsciiDigit(value)) {
- i = -1;
- break;
- }
- }
-
- if (i > -1) {
- PRInt32 err;
- millis = token.ToInteger(&err) * 1000;
- } else {
- done = PR_TRUE;
- }
- } else {
- done = PR_TRUE;
- }
- if (done) {
- PRInt32 loc = token.FindChar('=');
- if (loc > -1)
- token.Cut(0, loc+1);
- token.Trim(" \"'");
- uriAttrib = token;
- } else {
- // Increment to the next token.
- if (semiColon > -1) {
- semiColon++;
- PRInt32 semiColon2 = result.FindCharInSet(";,", semiColon);
- if (semiColon2 == -1) semiColon2 = result.Length();
- result.Mid(token, semiColon, semiColon2 - semiColon);
- semiColon = semiColon2;
- } else {
- done = PR_TRUE;
- }
- }
- } // end while
-
- nsCOMPtr uri;
- if (!uriAttrib.Length()) {
- uri = baseURI;
- } else {
- NS_NewURI(getter_AddRefs(uri), uriAttrib, baseURI);
- }
-
- RefreshURI (uri, millis, PR_FALSE, PR_TRUE);
- }
- }
-
- return NS_OK;
+ rv = RefreshURIFromHeader(mCurrentURI, NS_ConvertUTF8toUCS2(refreshHeader));
+ }
+ }
+ return rv;
}
NS_IMETHODIMP nsDocShell::OnLoadingSite(nsIChannel* aChannel)
@@ -4096,8 +4203,6 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadTyp
nsCOMPtr postData;
nsCOMPtr referrerURI;
- PRBool repost = PR_TRUE;
-
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
nsCOMPtr hEntry(do_QueryInterface(aEntry));
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE);
@@ -4108,6 +4213,8 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadTyp
NS_ERROR_FAILURE);
#if 0
+ PRBool repost = PR_TRUE;
+
/* Ask whether to repost form post data */
if (postData) {
nsCOMPtr prompter;
diff --git a/mozilla/webshell/public/nsIRefreshURI.idl b/mozilla/webshell/public/nsIRefreshURI.idl
index a00ea621cea..c4e9cc4dda8 100644
--- a/mozilla/webshell/public/nsIRefreshURI.idl
+++ b/mozilla/webshell/public/nsIRefreshURI.idl
@@ -33,16 +33,25 @@ interface nsIRefreshURI : nsISupports {
* @param repeat Do you want the uri to be repeatedly refreshed every millis milliseconds.
* @param flag to check if this is for a META refresh
*/
- void refreshURI(in nsIURI aURI, in long aMillis, in boolean aRepeat, in boolean aMetaRefresh);
+ void refreshURI(in nsIURI aURI, in long aMillis, in boolean aRepeat, in boolean aMetaRefresh);
/**
- * Checks the passed in channel to see if there is a refresh header, if there is,
- * will setup a refreahURI by calling refreshURI
- */
- void setupRefreshURI(in nsIChannel aChannel);
+ * Checks the passed in channel to see if there is a refresh header, if there is,
+ * will setup a refreahURI by calling refreshURI
+ */
+ void setupRefreshURI(in nsIChannel aChannel);
+ /**
+ * Parses the passed in header string and will call refreshURI with
+ * the parsed values
+ *
+ * @param aBaseURI base URI to resolve refresh uri against
+ * @param aHeader The meta refresh header string
+ */
+ void refreshURIFromHeader(in nsIURI aBaseURI, in AString aHeader);
+
/**
* Cancels all timer loads.
*/
- void cancelRefreshURITimers();
+ void cancelRefreshURITimers();
};