mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 1198544 - Prevent FetchDriver from creating multiple responses if OnStopRequest yields a failing status code. r=nsm
This commit is contained in:
parent
21a44de982
commit
6841a351b6
@ -72,7 +72,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
OnResponseAvailable(InternalResponse* aResponse) override;
|
||||
OnResponseAvailableInternal(InternalResponse* aResponse) override;
|
||||
|
||||
void
|
||||
OnResponseEnd() override;
|
||||
@ -99,7 +99,7 @@ public:
|
||||
explicit MainThreadFetchResolver(Promise* aPromise);
|
||||
|
||||
void
|
||||
OnResponseAvailable(InternalResponse* aResponse) override;
|
||||
OnResponseAvailableInternal(InternalResponse* aResponse) override;
|
||||
|
||||
private:
|
||||
~MainThreadFetchResolver();
|
||||
@ -237,7 +237,7 @@ MainThreadFetchResolver::MainThreadFetchResolver(Promise* aPromise)
|
||||
}
|
||||
|
||||
void
|
||||
MainThreadFetchResolver::OnResponseAvailable(InternalResponse* aResponse)
|
||||
MainThreadFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(MainThreadFetchResolver);
|
||||
AssertIsOnMainThread();
|
||||
@ -317,7 +317,7 @@ public:
|
||||
};
|
||||
|
||||
void
|
||||
WorkerFetchResolver::OnResponseAvailable(InternalResponse* aResponse)
|
||||
WorkerFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
|
@ -884,13 +884,19 @@ FetchDriver::OnStopRequest(nsIRequest* aRequest,
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
workers::AssertIsOnMainThread();
|
||||
if (mPipeOutputStream) {
|
||||
mPipeOutputStream->Close();
|
||||
if (NS_FAILED(aStatusCode)) {
|
||||
nsCOMPtr<nsIAsyncOutputStream> outputStream = do_QueryInterface(mPipeOutputStream);
|
||||
if (outputStream) {
|
||||
outputStream->CloseWithStatus(NS_BINDING_FAILED);
|
||||
}
|
||||
// We proceed as usual here, since we've already created a successful response
|
||||
// from OnStartRequest.
|
||||
SucceedWithResponse();
|
||||
return aStatusCode;
|
||||
}
|
||||
|
||||
if (NS_FAILED(aStatusCode)) {
|
||||
FailWithNetworkError();
|
||||
return aStatusCode;
|
||||
if (mPipeOutputStream) {
|
||||
mPipeOutputStream->Close();
|
||||
}
|
||||
|
||||
ContinueHttpFetchAfterNetworkFetch();
|
||||
|
@ -32,14 +32,27 @@ class InternalResponse;
|
||||
class FetchDriverObserver
|
||||
{
|
||||
public:
|
||||
FetchDriverObserver() : mGotResponseAvailable(false)
|
||||
{ }
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchDriverObserver);
|
||||
virtual void OnResponseAvailable(InternalResponse* aResponse) = 0;
|
||||
void OnResponseAvailable(InternalResponse* aResponse)
|
||||
{
|
||||
MOZ_ASSERT(!mGotResponseAvailable);
|
||||
mGotResponseAvailable = true;
|
||||
OnResponseAvailableInternal(aResponse);
|
||||
}
|
||||
virtual void OnResponseEnd()
|
||||
{ };
|
||||
|
||||
protected:
|
||||
virtual ~FetchDriverObserver()
|
||||
{ };
|
||||
|
||||
virtual void OnResponseAvailableInternal(InternalResponse* aResponse) = 0;
|
||||
|
||||
private:
|
||||
bool mGotResponseAvailable;
|
||||
};
|
||||
|
||||
class FetchDriver final : public nsIStreamListener,
|
||||
|
@ -319,6 +319,23 @@ fetch(new Request('body-blob', {method: 'POST', body: new Blob(new String('my bo
|
||||
finish();
|
||||
});
|
||||
|
||||
expectAsyncResult();
|
||||
fetch('interrupt.sjs')
|
||||
.then(function(res) {
|
||||
my_ok(true, "interrupted fetch succeeded");
|
||||
res.text().then(function(body) {
|
||||
my_ok(false, "interrupted fetch shouldn't have complete body");
|
||||
finish();
|
||||
},
|
||||
function() {
|
||||
my_ok(true, "interrupted fetch shouldn't have complete body");
|
||||
finish();
|
||||
})
|
||||
}, function(e) {
|
||||
my_ok(false, "interrupted fetch failed");
|
||||
finish();
|
||||
});
|
||||
|
||||
['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'].forEach(function(method) {
|
||||
fetchXHRWithMethod('xhr-method-test.txt', method, function(xhr) {
|
||||
my_ok(xhr.status == 200, method + " load should be successful");
|
||||
|
20
dom/workers/test/serviceworkers/fetch/interrupt.sjs
Normal file
20
dom/workers/test/serviceworkers/fetch/interrupt.sjs
Normal file
@ -0,0 +1,20 @@
|
||||
function handleRequest(request, response) {
|
||||
var body = "a";
|
||||
for (var i = 0; i < 20; i++) {
|
||||
body += body;
|
||||
}
|
||||
|
||||
response.seizePower();
|
||||
response.write("HTTP/1.1 200 OK\r\n")
|
||||
var count = 10;
|
||||
response.write("Content-Length: " + body.length * count + "\r\n");
|
||||
response.write("Content-Type: text/plain; charset=utf-8\r\n");
|
||||
response.write("Cache-Control: no-cache, must-revalidate\r\n");
|
||||
response.write("\r\n");
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
response.write(body);
|
||||
}
|
||||
|
||||
throw Components.results.NS_BINDING_ABORTED;
|
||||
}
|
@ -50,6 +50,7 @@ support-files =
|
||||
fetch/https/clonedresponse/register.html
|
||||
fetch/https/clonedresponse/unregister.html
|
||||
fetch/https/clonedresponse/https_test.js
|
||||
fetch/interrupt.sjs
|
||||
fetch/origin/index.sjs
|
||||
fetch/origin/index-to-https.sjs
|
||||
fetch/origin/realindex.html
|
||||
|
Loading…
Reference in New Issue
Block a user