Bug 583288 (2/2) - Let forms using DELETE and PUT HTTP method when submitting. r=jst,sicking a2.0=sicking

This commit is contained in:
Mounir Lamouri 2010-09-10 07:00:10 +02:00
Родитель af33f56356
Коммит a21f5dcc0b
17 изменённых файлов: 522 добавлений и 57 удалений

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

@ -44,8 +44,10 @@ class nsIFormControl;
class nsISimpleEnumerator;
class nsIURI;
#define NS_FORM_METHOD_GET 0
#define NS_FORM_METHOD_POST 1
#define NS_FORM_METHOD_GET 0
#define NS_FORM_METHOD_POST 1
#define NS_FORM_METHOD_PUT 2
#define NS_FORM_METHOD_DELETE 3
#define NS_FORM_ENCTYPE_URLENCODED 0
#define NS_FORM_ENCTYPE_MULTIPART 1
#define NS_FORM_ENCTYPE_TEXTPLAIN 2

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

@ -39,8 +39,10 @@
#define nsFormSubmissionConstants_h__
static const nsAttrValue::EnumTable kFormMethodTable[] = {
{ "get", NS_FORM_METHOD_GET },
{ "post", NS_FORM_METHOD_POST },
{ "get", NS_FORM_METHOD_GET },
{ "post", NS_FORM_METHOD_POST },
{ "put", NS_FORM_METHOD_PUT },
{ "delete", NS_FORM_METHOD_DELETE },
{ 0 }
};
// Default method is 'get'.

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

@ -508,6 +508,19 @@ public:
*/
NS_HIDDEN_(nsresult) GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult);
/**
* Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_VALUE.
* Gets the enum value string of an attribute and using a default value if
* the attribute is missing or the string is an invalid enum value.
*
* @param aType the name of the attribute.
* @param aDefault the default value if the attribute is missing or invalid.
* @param aResult string corresponding to the value [out].
*/
NS_HIDDEN_(nsresult) GetEnumAttr(nsIAtom* aAttr,
const char* aDefault,
nsAString& aResult);
protected:
/**
* Add/remove this element to the documents name cache
@ -694,19 +707,6 @@ protected:
*/
NS_HIDDEN_(nsresult) GetURIListAttr(nsIAtom* aAttr, nsAString& aResult);
/**
* Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_VALUE.
* Gets the enum value string of an attribute and using a default value if
* the attribute is missing or the string is an invalid enum value.
*
* @param aType the name of the attribute.
* @param aDefault the default value if the attribute is missing or invalid.
* @param aResult string corresponding to the value [out].
*/
NS_HIDDEN_(nsresult) GetEnumAttr(nsIAtom* aAttr,
const char* aDefault,
nsAString& aResult);
/**
* Locates the nsIEditor associated with this node. In general this is
* equivalent to GetEditorInternal(), but for designmode or contenteditable,

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

@ -878,11 +878,25 @@ nsHTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission)
getter_AddRefs(postDataStream));
NS_ENSURE_SUBMIT_SUCCESS(rv);
nsAutoString method;
if (originatingElement &&
originatingElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::formmethod)) {
if (!originatingElement->IsHTML()) {
return NS_ERROR_UNEXPECTED;
}
static_cast<nsGenericHTMLElement*>(originatingElement)->
GetEnumAttr(nsGkAtoms::formmethod, kFormDefaultMethod->tag, method);
} else {
GetEnumAttr(nsGkAtoms::method, kFormDefaultMethod->tag, method);
}
rv = linkHandler->OnLinkClickSync(this, actionURI,
target.get(),
postDataStream, nsnull,
getter_AddRefs(docShell),
getter_AddRefs(mSubmittingRequest));
getter_AddRefs(mSubmittingRequest),
NS_LossyConvertUTF16toASCII(method).get());
NS_ENSURE_SUBMIT_SUCCESS(rv);
}

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

@ -0,0 +1,8 @@
function handleRequest(request, response)
{
// Redirect to another domain.
// Using 307 to keep the method.
response.setStatusLine(null, 307, "Temp");
response.setHeader("Location",
"http://example.org:80/tests/content/html/content/test/583288_submit_server.sjs");
}

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

@ -0,0 +1,5 @@
function handleRequest(request, response)
{
// Send the HTTP method.
response.write(request.method);
}

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

@ -212,6 +212,11 @@ _TEST_FILES = \
test_bug590353-1.html \
test_bug590353-2.html \
test_bug593689.html \
test_bug583288-1.html \
test_bug583288-2.html \
test_bug583288-3.html \
583288_submit_server.sjs \
583288_redirect_server.sjs \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -0,0 +1,143 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=583288
-->
<head>
<title>Test for Bug 583288</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload='runTests();'>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=583288">Mozilla Bug 583288</a>
<p id="display"></p>
<style>
iframe { width: 70px; height: 40px;}
</style>
<!--<div id="content" style="display: none">-->
<div id="content">
<iframe name='get' id='get'></iframe>
<iframe name='post' id='post'></iframe>
<iframe name='put' id='put'></iframe>
<iframe name='del' id='del'></iframe>
<iframe name='get2' id='get2'></iframe>
<iframe name='post2' id='post2'></iframe>
<iframe name='put2' id='put2'></iframe>
<iframe name='del2' id='del2'></iframe>
<form action="583288_submit_server.sjs" target='get' method='get'>
</form>
<form action="583288_submit_server.sjs" target='post' method='post'>
</form>
<form action="583288_submit_server.sjs" target='put' method='put'>
</form>
<form action="583288_submit_server.sjs" target='del' method='delete'>
</form>
<form action="583288_submit_server.sjs">
<input type='submit' id='iget' value='get' formtarget='get2' formmethod='get'>
</form>
<form action="583288_submit_server.sjs">
<input type='submit' id='ipost' value='post' formtarget='post2' formmethod='post'>
</form>
<form action="583288_submit_server.sjs">
<input type='submit' id='iput' value='put' formtarget='put2' formmethod='put'>
</form>
<form action="583288_submit_server.sjs">
<input type='submit' id='idel' value='delete' formtarget='del2' formmethod='delete'>
</form>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 583288 **/
SimpleTest.waitForExplicitFinish();
var gTestResults = {
get: "GET",
get2: "GET",
post: "POST",
post2: "POST",
put: "PUT",
put2: "PUT",
del: "DELETE",
del2: "DELETE",
};
var gPendingLoad = 0; // Has to be set after depending on the frames number.
function runTests()
{
// We add a load event for the frames which will be called when the forms
// will be submitted.
var frames = [ document.getElementById('get'),
document.getElementById('get2'),
document.getElementById('post'),
document.getElementById('post2'),
document.getElementById('put'),
document.getElementById('put2'),
document.getElementById('del'),
document.getElementById('del2'),
];
gPendingLoad = frames.length;
for (var i=0; i<frames.length; ++i) {
frames[i].setAttribute('onload', "frameLoaded(this);");
}
// The four first forms can be submitted with .submit().
for (var i=0; i<4; ++i) {
document.forms[i].submit();
}
/**
* We are going to focus each element before interacting with them so we are
* sure they will be visible in the iframe.
* Considering we are using synthesizeKey that may be not required.
*
* Focusing the first element (id='iget') is launching the tests.
*/
document.getElementById('iget').addEventListener('focus', function(aEvent) {
aEvent.target.removeEventListener('focus', arguments.callee, false);
synthesizeKey("VK_RETURN", {});
document.getElementById('ipost').focus();
}, false);
document.getElementById('ipost').addEventListener('focus', function(aEvent) {
aEvent.target.removeEventListener('focus', arguments.callee, false);
synthesizeKey("VK_RETURN", {});
document.getElementById('iput').focus();
}, false);
document.getElementById('iput').addEventListener('focus', function(aEvent) {
aEvent.target.removeEventListener('focus', arguments.callee, false);
synthesizeKey("VK_RETURN", {});
document.getElementById('idel').focus();
}, false);
document.getElementById('idel').addEventListener('focus', function(aEvent) {
aEvent.target.removeEventListener('focus', arguments.callee, false);
synthesizeKey("VK_RETURN", {});
}, false);
document.getElementById('iget').focus();
}
function frameLoaded(aFrame) {
// Check if formaction/action has the correct behavior.
is(aFrame.contentDocument.documentElement.textContent, gTestResults[aFrame.name],
"the method used during the form submission should be " +
gTestResults[aFrame.name]);
if (--gPendingLoad == 0) {
SimpleTest.finish();
}
}
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,99 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=583288
-->
<head>
<title>Test for Bug 583288</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload='runTests();'>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=583288">Mozilla Bug 583288</a>
<p id="display"></p>
<style>
iframe { width: 70px; height: 40px;}
</style>
<!--<div id="content" style="display: none">-->
<div id="content">
<iframe name='get' id='get'></iframe>
<iframe name='post' id='post'></iframe>
<iframe name='put' id='put'></iframe>
<iframe name='del' id='del'></iframe>
<form action="http://example.org:80/tests/content/html/content/test/583288_submit_server.sjs" target='get' method='get'>
</form>
<form action="http://example.org:80/tests/content/html/content/test/583288_submit_server.sjs" target='post' method='post'>
</form>
<form action="http://example.org:80/tests/content/html/content/test/583288_submit_server.sjs" target='put' method='put'>
</form>
<form action="http://example.org:80/tests/content/html/content/test/583288_submit_server.sjs" target='del' method='delete'>
</form>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 583288 **/
SimpleTest.waitForExplicitFinish();
var gLoaded = 0;
function runTests()
{
// We add a load event for the frames which will be called when the forms
// will be submitted.
var frames = [ document.getElementById('get'),
document.getElementById('post'),
document.getElementById('put'),
document.getElementById('del'),
];
for (var i=0; i<2; ++i) {
frames[i].setAttribute('onload', "frameShouldLoad();");
}
for (var i=2; i<4; ++i) {
frames[i].setAttribute('onload', "frameShouldNotLoad();");
}
// The four forms can be submitted with .submit().
// Submitting those which should be blocked so we can considering if the the
// last ones are submitted, that means the firsts were blocked.
for (var i=3; i>=0; --i) {
document.forms[i].submit();
}
// After the two first succefull submissions, we are going to stop the test.
// The expected successfull submissions have been requested at the end so we
// expect them at the end. So if the two firsts ones didn't show up, we are
// assuming they have been blocked.
// Unfortunately, it doesn't sound like there is a better way to test that.
// The worst thing that can happen here is to have a random green (if the
// first two submissions were not blocked but came after the last two).
}
function frameShouldLoad() {
ok(true, "The form submission should succeed.");
if (++gLoaded == 2) {
finished();
}
}
function frameShouldNotLoad() {
ok(false, "The form submission should have been blocked");
if (++gLoaded == 2) {
finished();
}
}
function finished()
{
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,85 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=583288
-->
<head>
<title>Test for Bug 583288</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload='runTests();'>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=583288">Mozilla Bug 583288</a>
<p id="display"></p>
<style>
iframe { width: 70px; height: 40px;}
</style>
<!--<div id="content" style="display: none">-->
<div id="content">
<iframe name='get' id='get'></iframe>
<iframe name='post' id='post'></iframe>
<iframe name='put' id='put'></iframe>
<iframe name='del' id='del'></iframe>
<form action="583288_redirect_server.sjs" target='get' method='get'>
</form>
<form action="583288_redirect_server.sjs" target='post' method='post'>
</form>
<form action="583288_redirect_server.sjs" target='put' method='put'>
</form>
<form action="583288_redirect_server.sjs" target='del' method='delete'>
</form>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 583288 **/
SimpleTest.waitForExplicitFinish();
var gTestResults = {
get: "GET",
post: "POST",
put: "",
del: "",
};
var gPendingLoad = 0; // Has to be set after depending on the frames number.
function runTests()
{
// We add a load event for the frames which will be called when the forms
// will be submitted.
var frames = [ document.getElementById('get'),
document.getElementById('post'),
document.getElementById('put'),
document.getElementById('del'),
];
gPendingLoad = frames.length;
for (var i=0; i<gPendingLoad; ++i) {
frames[i].setAttribute('onload', "frameLoaded(this);");
}
// The four forms can be submitted with .submit().
for (var i=0; i<4; ++i) {
document.forms[i].submit();
}
}
function frameLoaded(aFrame) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
is(aFrame.contentDocument.documentElement.textContent, gTestResults[aFrame.name],
"cross-origin submission with redirection should work");
if (--gPendingLoad == 0) {
SimpleTest.finish();
}
}
</script>
</pre>
</body>
</html>

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

@ -30,11 +30,9 @@ var methodTestData = [
// Default value.
[ "get" ],
// Valid values.
[ "get", "post" ],
[ "get", "post", "put", "delete" ],
// Invalid values.
[ "", " ", "foo" ],
// TODO values, see bug 583289 and bug 583288.
[ "delete", "put" ],
];
function checkAttribute(form, attrName, idlName, data)

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

@ -1412,7 +1412,8 @@ nsDocShell::LoadURI(nsIURI * aURI,
nsnull, // No SHEntry
aFirstParty,
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
nsnull, // No nsIRequest
nsnull); // Use default HTTP method
}
NS_IMETHODIMP
@ -4095,7 +4096,7 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
return InternalLoad(errorPageURI, nsnull, nsnull,
INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nsnull, nsnull,
nsnull, nsnull, LOAD_ERROR_PAGE,
nsnull, PR_TRUE, nsnull, nsnull);
nsnull, PR_TRUE, nsnull, nsnull, nsnull);
}
@ -4159,7 +4160,8 @@ nsDocShell::Reload(PRUint32 aReloadFlags)
nsnull, // No SHEntry
PR_TRUE,
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
nsnull, // No nsIRequest
nsnull); // Use default HTTP method
}
@ -5869,7 +5871,7 @@ nsDocShell::OnLocationChange(nsIWebProgress * aProgress,
return NS_OK;
}
void
nsresult
nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
PRUint32 aRedirectFlags,
@ -5878,13 +5880,44 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
NS_ASSERTION(aStateFlags & STATE_REDIRECTING,
"Calling OnRedirectStateChange when there is no redirect");
if (!(aStateFlags & STATE_IS_DOCUMENT))
return; // not a toplevel document
return NS_OK; // not a toplevel document
nsCOMPtr<nsIURI> oldURI, newURI;
aOldChannel->GetURI(getter_AddRefs(oldURI));
aNewChannel->GetURI(getter_AddRefs(newURI));
if (!oldURI || !newURI) {
return;
return NS_OK;
}
// HTTP channel with unsafe methods should not be redirected to a cross-domain.
if (!ChannelIsSafeMethod(aNewChannel)) {
// This code is very similar to the code of nsSameOriginChecker in
// nsContentUtils but we can't use nsSameOriginChecker because it
// needs to use a channel callback (which we already use).
// If nsSameOriginChecker happens to not use a channel callback
// anymore, this code would be a good candidate for refactoring.
nsCOMPtr<nsIPrincipal> oldPrincipal;
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
rv = secMan->GetChannelPrincipal(aOldChannel,
getter_AddRefs(oldPrincipal));
NS_ENSURE_SUCCESS(rv, NS_OK);
NS_ASSERTION(oldPrincipal, "oldPrincipal should not be null!");
nsCOMPtr<nsIURI> newOriginalURI;
aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
rv = oldPrincipal->CheckMayLoad(newURI, PR_FALSE);
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE);
}
// The requested tried to be redirected, we have to cancel it.
NS_ENSURE_SUCCESS(rv, rv);
}
// Below a URI visit is saved (see AddURIVisit method doc).
@ -5935,6 +5968,8 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
mLoadType = LOAD_NORMAL_REPLACE;
SetHistoryEntry(&mLSHE, nsnull);
}
return NS_OK;
}
NS_IMETHODIMP
@ -6306,7 +6341,8 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
nsnull, // No SHEntry
PR_TRUE, // first party site
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
nsnull, // No nsIRequest
nsnull); // Use default HTTP method
}
else {
DisplayLoadError(aStatus, url, nsnull, aChannel);
@ -7750,7 +7786,7 @@ public:
return mDocShell->InternalLoad(mURI, mReferrer, mOwner, mFlags,
nsnull, mTypeHint.get(),
mPostData, mHeadersData, mLoadType,
mSHEntry, mFirstParty, nsnull, nsnull);
mSHEntry, mFirstParty, nsnull, nsnull, nsnull);
}
private:
@ -7784,7 +7820,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
nsISHEntry * aSHEntry,
PRBool aFirstParty,
nsIDocShell** aDocShell,
nsIRequest** aRequest)
nsIRequest** aRequest,
const char* aHttpMethod)
{
nsresult rv = NS_OK;
@ -7986,7 +8023,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
aSHEntry,
aFirstParty,
aDocShell,
aRequest);
aRequest,
aHttpMethod);
if (rv == NS_ERROR_NO_CONTENT) {
// XXXbz except we never reach this code!
if (isNewWindow) {
@ -8421,7 +8459,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
aDocShell, getter_AddRefs(req),
(aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
(aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
(aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0);
(aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0,
aHttpMethod);
if (req && aRequest)
NS_ADDREF(*aRequest = req);
@ -8502,7 +8541,8 @@ nsDocShell::DoURILoad(nsIURI * aURI,
nsIRequest ** aRequest,
PRBool aIsNewWindowTarget,
PRBool aBypassClassifier,
PRBool aForceAllowCookies)
PRBool aForceAllowCookies,
const char* aHttpMethod)
{
nsresult rv;
nsCOMPtr<nsIURILoader> uriLoader;
@ -8685,6 +8725,20 @@ nsDocShell::DoURILoad(nsIURI * aURI,
// Referrer is currenly only set for link clicks here.
httpChannel->SetReferrer(aReferrerURI);
}
// If a specific HTTP method has been requested, set it.
if (aHttpMethod) {
// Tell the cache it _has_ to open a cache entry.
PRUint32 loadFlags;
if (NS_SUCCEEDED(channel->GetLoadFlags(&loadFlags))) {
channel->SetLoadFlags(loadFlags | nsICachingChannel::FORCE_OPEN_CACHE_ENTRY);
}
// The method name have to be correct.
// Otherwise SetRequestMethod will return a failure.
rv = httpChannel->SetRequestMethod(nsDependentCString(aHttpMethod));
NS_ENSURE_SUCCESS(rv, rv);
}
}
//
// Set the owner of the channel, but only for channels that can't
@ -8735,6 +8789,14 @@ nsDocShell::DoURILoad(nsIURI * aURI,
}
}
// If a specific HTTP channel has been set and it is not a safe method,
// we should prevent cross-origin requests.
if (aHttpMethod && ownerPrincipal && !ChannelIsSafeMethod(channel)) {
if (NS_FAILED(ownerPrincipal->CheckMayLoad(aURI, PR_FALSE))) {
return NS_OK;
}
}
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(channel);
if (scriptChannel) {
// Allow execution against our context if the principals match
@ -9946,7 +10008,8 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
aEntry, // SHEntry
PR_TRUE,
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
nsnull, // No nsIRequest
nsnull); // Use default HTTP method
return rv;
}
@ -10359,6 +10422,7 @@ NS_IMETHODIMP nsDocShell::MakeEditable(PRBool inWaitForUriLoad)
return mEditorData->MakeEditable(inWaitForUriLoad);
}
/* static */
bool
nsDocShell::ChannelIsPost(nsIChannel* aChannel)
{
@ -10372,6 +10436,21 @@ nsDocShell::ChannelIsPost(nsIChannel* aChannel)
return method.Equals("POST");
}
/* static */
bool
nsDocShell::ChannelIsSafeMethod(nsIChannel* aChannel)
{
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
if (!httpChannel) {
return false;
}
nsCAutoString method;
httpChannel->GetRequestMethod(method);
return method.Equals("GET") || method.Equals("POST") ||
method.Equals("HEAD");
}
void
nsDocShell::ExtractLastVisit(nsIChannel* aChannel,
nsIURI** aURI,
@ -11302,7 +11381,8 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
nsIInputStream* aPostDataStream,
nsIInputStream* aHeadersDataStream,
nsIDocShell** aDocShell,
nsIRequest** aRequest)
nsIRequest** aRequest,
const char* aHttpMethod)
{
// Initialize the DocShell / Request
if (aDocShell) {
@ -11378,7 +11458,8 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
nsnull, // No SHEntry
PR_TRUE, // first party site
aDocShell, // DocShell out-param
aRequest); // Request out-param
aRequest, // Request out-param
aHttpMethod); // HTTP Method
if (NS_SUCCEEDED(rv)) {
DispatchPings(aContent, referer);
}

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

@ -243,7 +243,8 @@ public:
nsIInputStream* aPostDataStream = 0,
nsIInputStream* aHeadersDataStream = 0,
nsIDocShell** aDocShell = 0,
nsIRequest** aRequest = 0);
nsIRequest** aRequest = 0,
const char* aHttpMethod = 0);
NS_IMETHOD OnOverLink(nsIContent* aContent,
nsIURI* aURI,
const PRUnichar* aTargetSpec);
@ -325,7 +326,8 @@ protected:
nsIRequest ** aRequest,
PRBool aIsNewWindowTarget,
PRBool aBypassClassifier,
PRBool aForceAllowCookies);
PRBool aForceAllowCookies,
const char* aHttpMethod);
NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData,
nsIChannel * aChannel);
virtual nsresult DoChannelLoad(nsIChannel * aChannel,
@ -434,10 +436,10 @@ protected:
// overridden from nsDocLoader, this provides more information than the
// normal OnStateChange with flags STATE_REDIRECTING
virtual void OnRedirectStateChange(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
PRUint32 aRedirectFlags,
PRUint32 aStateFlags);
virtual nsresult OnRedirectStateChange(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
PRUint32 aRedirectFlags,
PRUint32 aStateFlags);
/**
* Helper function that determines if channel is an HTTP POST.
@ -447,7 +449,17 @@ protected:
*
* @return True iff channel is an HTTP post.
*/
bool ChannelIsPost(nsIChannel* aChannel);
static bool ChannelIsPost(nsIChannel* aChannel);
/**
* Helper function that determines if the HTTP channel has a safe method
*
* @param aChannel The channel to test
*
* @return Whether the channel has a safe HTTP method.
* @note Will return false if the channel isn't an HTTP channel.
*/
static bool ChannelIsSafeMethod(nsIChannel* aChannel);
/**
* Helper function that finds the last URI and its transition flags for a

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

@ -71,7 +71,7 @@ interface nsIPrincipal;
interface nsIWebBrowserPrint;
interface nsIVariant;
[scriptable, uuid(74470127-87eb-4f79-8293-1616fe9cb689)]
[scriptable, uuid(0e1e1ee5-5baa-4e27-98af-3197d70d0304)]
interface nsIDocShell : nsISupports
{
/**
@ -155,6 +155,10 @@ interface nsIDocShell : nsISupports
* @param aLoadFlags - Flags to modify load behaviour. Flags are defined
* in nsIWebNavigation.
* @param aSHEntry - Active Session History entry (if loading from SH)
* @param firstParty -
* @param aDocShell -
* @param aRequest -
* @param aHttpMethod - Force the HTTP channel to use a specific HTTP method
*/
[noscript]void internalLoad(in nsIURI aURI,
in nsIURI aReferrer,
@ -168,7 +172,8 @@ interface nsIDocShell : nsISupports
in nsISHEntry aSHEntry,
in boolean firstParty,
out nsIDocShell aDocShell,
out nsIRequest aRequest);
out nsIRequest aRequest,
in string aHttpMethod);
/**
* Do either a history.pushState() or history.replaceState() operation,

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

@ -1609,7 +1609,9 @@ NS_IMETHODIMP nsDocLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
#endif /* DEBUG */
}
OnRedirectStateChange(aOldChannel, aNewChannel, aFlags, stateFlags);
nsresult rv = OnRedirectStateChange(aOldChannel, aNewChannel, aFlags,
stateFlags);
NS_ENSURE_SUCCESS(rv, rv);
FireOnStateChange(this, aOldChannel, stateFlags, NS_OK);
}

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

@ -69,11 +69,11 @@ struct nsListenerInfo;
****************************************************************************/
#define NS_THIS_DOCLOADER_IMPL_CID \
{ /* b4ec8387-98aa-4c08-93b6-6d23069c06f2 */ \
0xb4ec8387, \
0x98aa, \
0x4c08, \
{0x93, 0xb6, 0x6d, 0x23, 0x06, 0x9c, 0x06, 0xf2} \
{ \
0x306cae1f, \
0x90ee, \
0x4e51, \
{0xaf, 0x27, 0x9c, 0x13, 0xde, 0xba, 0x91, 0xb6} \
}
class nsDocLoader : public nsIDocumentLoader,
@ -179,10 +179,12 @@ protected:
// @param aRedirectFlags The flags being sent to OnStateChange that
// indicate the type of redirect.
// @param aStateFlags The channel flags normally sent to OnStateChange.
virtual void OnRedirectStateChange(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
PRUint32 aRedirectFlags,
PRUint32 aStateFlags) {}
//
// @return Something else than NS_OK if the redirection should be cancelled.
virtual nsresult OnRedirectStateChange(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
PRUint32 aRedirectFlags,
PRUint32 aStateFlags) { return NS_OK; }
void doStartDocumentLoad();
void doStartURLLoad(nsIRequest *request);

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

@ -48,7 +48,7 @@ class nsGUIEvent;
// Interface ID for nsILinkHandler
#define NS_ILINKHANDLER_IID \
{ 0x71627c30, 0xd3c5, 0x4ad0,{0xb5, 0x33, 0x6e, 0x01, 0x91, 0xf2, 0x79, 0x32}}
{ 0x1fa72627, 0x646b, 0x4573,{0xb5, 0xc8, 0xb4, 0x65, 0xc6, 0x78, 0xd4, 0x9d}}
/**
* Interface used for handling clicks on links
@ -87,6 +87,7 @@ public:
* @param aHeadersDataStream ???
* @param aDocShell (out-param) the DocShell that the request was opened on
* @param aRequest the request that was opened
* @param aHttpMethod forces the http channel to use a specific method
*/
NS_IMETHOD OnLinkClickSync(nsIContent* aContent,
nsIURI* aURI,
@ -94,7 +95,8 @@ public:
nsIInputStream* aPostDataStream = 0,
nsIInputStream* aHeadersDataStream = 0,
nsIDocShell** aDocShell = 0,
nsIRequest** aRequest = 0) = 0;
nsIRequest** aRequest = 0,
const char* aHttpMethod = 0) = 0;
/**
* Process a mouse-over a link.