mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1073231 Implement Request and Response Clone() methods. r=nsm r=baku
This commit is contained in:
parent
b880944866
commit
3869f5c2b9
@ -62,7 +62,7 @@ MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, JSEXN_TYPEERR, "Headers require name/val
|
|||||||
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, JSEXN_TYPEERR, "Permission denied to pass cross-origin object as {0}.")
|
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, JSEXN_TYPEERR, "Permission denied to pass cross-origin object as {0}.")
|
||||||
MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, JSEXN_TYPEERR, "Missing required {0}.")
|
MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, JSEXN_TYPEERR, "Missing required {0}.")
|
||||||
MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, JSEXN_TYPEERR, "Invalid request method {0}.")
|
MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, JSEXN_TYPEERR, "Invalid request method {0}.")
|
||||||
MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR, 0, JSEXN_TYPEERR, "Request body has already been consumed.")
|
MSG_DEF(MSG_FETCH_BODY_CONSUMED_ERROR, 0, JSEXN_TYPEERR, "Body has already been consumed.")
|
||||||
MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, JSEXN_TYPEERR, "Response statusText may not contain newline or carriage return.")
|
MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, JSEXN_TYPEERR, "Response statusText may not contain newline or carriage return.")
|
||||||
MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEERR, "NetworkError when attempting to fetch resource.")
|
MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEERR, "NetworkError when attempting to fetch resource.")
|
||||||
MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.")
|
MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.")
|
||||||
|
@ -1164,7 +1164,7 @@ FetchBody<Derived>::ConsumeBody(ConsumeType aType, ErrorResult& aRv)
|
|||||||
{
|
{
|
||||||
mConsumeType = aType;
|
mConsumeType = aType;
|
||||||
if (BodyUsed()) {
|
if (BodyUsed()) {
|
||||||
aRv.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR);
|
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ template <class Derived>
|
|||||||
class FetchBody {
|
class FetchBody {
|
||||||
public:
|
public:
|
||||||
bool
|
bool
|
||||||
BodyUsed() { return mBodyUsed; }
|
BodyUsed() const { return mBodyUsed; }
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
ArrayBuffer(ErrorResult& aRv)
|
ArrayBuffer(ErrorResult& aRv)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "nsIContentPolicy.h"
|
#include "nsIContentPolicy.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
|
#include "nsStreamUtils.h"
|
||||||
|
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
@ -43,6 +44,53 @@ InternalRequest::GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult
|
|||||||
return copy.forget();
|
return copy.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<InternalRequest>
|
||||||
|
InternalRequest::Clone()
|
||||||
|
{
|
||||||
|
nsRefPtr<InternalRequest> clone = new InternalRequest(*this);
|
||||||
|
|
||||||
|
if (!mBodyStream) {
|
||||||
|
return clone.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> clonedBody;
|
||||||
|
nsCOMPtr<nsIInputStream> replacementBody;
|
||||||
|
|
||||||
|
nsresult rv = NS_CloneInputStream(mBodyStream, getter_AddRefs(clonedBody),
|
||||||
|
getter_AddRefs(replacementBody));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; }
|
||||||
|
|
||||||
|
clone->mBodyStream.swap(clonedBody);
|
||||||
|
if (replacementBody) {
|
||||||
|
mBodyStream.swap(replacementBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalRequest::InternalRequest(const InternalRequest& aOther)
|
||||||
|
: mMethod(aOther.mMethod)
|
||||||
|
, mURL(aOther.mURL)
|
||||||
|
, mHeaders(new InternalHeaders(*aOther.mHeaders))
|
||||||
|
, mContentPolicyType(aOther.mContentPolicyType)
|
||||||
|
, mReferrer(aOther.mReferrer)
|
||||||
|
, mMode(aOther.mMode)
|
||||||
|
, mCredentialsMode(aOther.mCredentialsMode)
|
||||||
|
, mResponseTainting(aOther.mResponseTainting)
|
||||||
|
, mCacheMode(aOther.mCacheMode)
|
||||||
|
, mAuthenticationFlag(aOther.mAuthenticationFlag)
|
||||||
|
, mForceOriginHeader(aOther.mForceOriginHeader)
|
||||||
|
, mPreserveContentCodings(aOther.mPreserveContentCodings)
|
||||||
|
, mSameOriginDataURL(aOther.mSameOriginDataURL)
|
||||||
|
, mSandboxedStorageAreaURLs(aOther.mSandboxedStorageAreaURLs)
|
||||||
|
, mSkipServiceWorker(aOther.mSkipServiceWorker)
|
||||||
|
, mSynchronous(aOther.mSynchronous)
|
||||||
|
, mUnsafeRequest(aOther.mUnsafeRequest)
|
||||||
|
, mUseURLCredentials(aOther.mUseURLCredentials)
|
||||||
|
{
|
||||||
|
// NOTE: does not copy body stream... use the fallible Clone() for that
|
||||||
|
}
|
||||||
|
|
||||||
InternalRequest::~InternalRequest()
|
InternalRequest::~InternalRequest()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -67,28 +67,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit InternalRequest(const InternalRequest& aOther)
|
already_AddRefed<InternalRequest> Clone();
|
||||||
: mMethod(aOther.mMethod)
|
|
||||||
, mURL(aOther.mURL)
|
|
||||||
, mHeaders(aOther.mHeaders)
|
|
||||||
, mBodyStream(aOther.mBodyStream)
|
|
||||||
, mContentPolicyType(aOther.mContentPolicyType)
|
|
||||||
, mReferrer(aOther.mReferrer)
|
|
||||||
, mMode(aOther.mMode)
|
|
||||||
, mCredentialsMode(aOther.mCredentialsMode)
|
|
||||||
, mResponseTainting(aOther.mResponseTainting)
|
|
||||||
, mCacheMode(aOther.mCacheMode)
|
|
||||||
, mAuthenticationFlag(aOther.mAuthenticationFlag)
|
|
||||||
, mForceOriginHeader(aOther.mForceOriginHeader)
|
|
||||||
, mPreserveContentCodings(aOther.mPreserveContentCodings)
|
|
||||||
, mSameOriginDataURL(aOther.mSameOriginDataURL)
|
|
||||||
, mSandboxedStorageAreaURLs(aOther.mSandboxedStorageAreaURLs)
|
|
||||||
, mSkipServiceWorker(aOther.mSkipServiceWorker)
|
|
||||||
, mSynchronous(aOther.mSynchronous)
|
|
||||||
, mUnsafeRequest(aOther.mUnsafeRequest)
|
|
||||||
, mUseURLCredentials(aOther.mUseURLCredentials)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GetMethod(nsCString& aMethod) const
|
GetMethod(nsCString& aMethod) const
|
||||||
@ -293,6 +272,9 @@ public:
|
|||||||
GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult& aRv) const;
|
GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult& aRv) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
|
||||||
|
explicit InternalRequest(const InternalRequest& aOther);
|
||||||
|
|
||||||
~InternalRequest();
|
~InternalRequest();
|
||||||
|
|
||||||
nsCString mMethod;
|
nsCString mMethod;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "nsIDOMFile.h"
|
#include "nsIDOMFile.h"
|
||||||
|
|
||||||
#include "mozilla/dom/InternalHeaders.h"
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
|
#include "nsStreamUtils.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
@ -22,7 +23,7 @@ InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusTe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Headers are not copied since BasicResponse and CORSResponse both need custom
|
// Headers are not copied since BasicResponse and CORSResponse both need custom
|
||||||
// header handling.
|
// header handling. Body is not copied as it cannot be shared directly.
|
||||||
InternalResponse::InternalResponse(const InternalResponse& aOther)
|
InternalResponse::InternalResponse(const InternalResponse& aOther)
|
||||||
: mType(aOther.mType)
|
: mType(aOther.mType)
|
||||||
, mTerminationReason(aOther.mTerminationReason)
|
, mTerminationReason(aOther.mTerminationReason)
|
||||||
@ -30,11 +31,35 @@ InternalResponse::InternalResponse(const InternalResponse& aOther)
|
|||||||
, mFinalURL(aOther.mFinalURL)
|
, mFinalURL(aOther.mFinalURL)
|
||||||
, mStatus(aOther.mStatus)
|
, mStatus(aOther.mStatus)
|
||||||
, mStatusText(aOther.mStatusText)
|
, mStatusText(aOther.mStatusText)
|
||||||
, mBody(aOther.mBody)
|
|
||||||
, mContentType(aOther.mContentType)
|
, mContentType(aOther.mContentType)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<InternalResponse>
|
||||||
|
InternalResponse::Clone()
|
||||||
|
{
|
||||||
|
nsRefPtr<InternalResponse> clone = new InternalResponse(*this);
|
||||||
|
clone->mHeaders = new InternalHeaders(*mHeaders);
|
||||||
|
|
||||||
|
if (!mBody) {
|
||||||
|
return clone.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> clonedBody;
|
||||||
|
nsCOMPtr<nsIInputStream> replacementBody;
|
||||||
|
|
||||||
|
nsresult rv = NS_CloneInputStream(mBody, getter_AddRefs(clonedBody),
|
||||||
|
getter_AddRefs(replacementBody));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; }
|
||||||
|
|
||||||
|
clone->mBody.swap(clonedBody);
|
||||||
|
if (replacementBody) {
|
||||||
|
mBody.swap(replacementBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone.forget();
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<InternalResponse>
|
already_AddRefed<InternalResponse>
|
||||||
InternalResponse::BasicResponse(InternalResponse* aInner)
|
InternalResponse::BasicResponse(InternalResponse* aInner)
|
||||||
@ -43,6 +68,7 @@ InternalResponse::BasicResponse(InternalResponse* aInner)
|
|||||||
nsRefPtr<InternalResponse> basic = new InternalResponse(*aInner);
|
nsRefPtr<InternalResponse> basic = new InternalResponse(*aInner);
|
||||||
basic->mType = ResponseType::Basic;
|
basic->mType = ResponseType::Basic;
|
||||||
basic->mHeaders = InternalHeaders::BasicHeaders(aInner->mHeaders);
|
basic->mHeaders = InternalHeaders::BasicHeaders(aInner->mHeaders);
|
||||||
|
basic->mBody.swap(aInner->mBody);
|
||||||
return basic.forget();
|
return basic.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +80,7 @@ InternalResponse::CORSResponse(InternalResponse* aInner)
|
|||||||
nsRefPtr<InternalResponse> cors = new InternalResponse(*aInner);
|
nsRefPtr<InternalResponse> cors = new InternalResponse(*aInner);
|
||||||
cors->mType = ResponseType::Cors;
|
cors->mType = ResponseType::Cors;
|
||||||
cors->mHeaders = InternalHeaders::CORSHeaders(aInner->mHeaders);
|
cors->mHeaders = InternalHeaders::CORSHeaders(aInner->mHeaders);
|
||||||
|
cors->mBody.swap(aInner->mBody);
|
||||||
return cors.forget();
|
return cors.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ public:
|
|||||||
|
|
||||||
InternalResponse(uint16_t aStatus, const nsACString& aStatusText);
|
InternalResponse(uint16_t aStatus, const nsACString& aStatusText);
|
||||||
|
|
||||||
|
already_AddRefed<InternalResponse> Clone();
|
||||||
|
|
||||||
static already_AddRefed<InternalResponse>
|
static already_AddRefed<InternalResponse>
|
||||||
NetworkError()
|
NetworkError()
|
||||||
{
|
{
|
||||||
@ -125,8 +127,8 @@ private:
|
|||||||
~InternalResponse()
|
~InternalResponse()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Used to create filtered responses.
|
// Used to create filtered and cloned responses.
|
||||||
// Does not copy headers.
|
// Does not copy headers or body stream.
|
||||||
explicit InternalResponse(const InternalResponse& aOther);
|
explicit InternalResponse(const InternalResponse& aOther);
|
||||||
|
|
||||||
ResponseType mType;
|
ResponseType mType;
|
||||||
|
@ -63,7 +63,7 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||||||
inputReq->GetBody(getter_AddRefs(body));
|
inputReq->GetBody(getter_AddRefs(body));
|
||||||
if (body) {
|
if (body) {
|
||||||
if (inputReq->BodyUsed()) {
|
if (inputReq->BodyUsed()) {
|
||||||
aRv.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR);
|
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
inputReq->SetBodyUsed();
|
inputReq->SetBodyUsed();
|
||||||
@ -255,12 +255,20 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Request>
|
already_AddRefed<Request>
|
||||||
Request::Clone() const
|
Request::Clone(ErrorResult& aRv) const
|
||||||
{
|
{
|
||||||
// FIXME(nsm): Bug 1073231. This is incorrect, but the clone method isn't
|
if (BodyUsed()) {
|
||||||
// well defined yet.
|
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
||||||
nsRefPtr<Request> request = new Request(mOwner,
|
return nullptr;
|
||||||
new InternalRequest(*mRequest));
|
}
|
||||||
|
|
||||||
|
nsRefPtr<InternalRequest> ir = mRequest->Clone();
|
||||||
|
if (!ir) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<Request> request = new Request(mOwner, ir);
|
||||||
return request.forget();
|
return request.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Request>
|
already_AddRefed<Request>
|
||||||
Clone() const;
|
Clone(ErrorResult& aRv) const;
|
||||||
|
|
||||||
already_AddRefed<InternalRequest>
|
already_AddRefed<InternalRequest>
|
||||||
GetInternalRequest();
|
GetInternalRequest();
|
||||||
|
@ -190,19 +190,23 @@ Response::Constructor(const GlobalObject& aGlobal,
|
|||||||
return r.forget();
|
return r.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(nsm): Bug 1073231: This is currently unspecced!
|
|
||||||
already_AddRefed<Response>
|
already_AddRefed<Response>
|
||||||
Response::Clone()
|
Response::Clone(ErrorResult& aRv) const
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mOwner);
|
if (BodyUsed()) {
|
||||||
nsRefPtr<Response> response = new Response(global, mInternalResponse);
|
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<InternalResponse> ir = mInternalResponse->Clone();
|
||||||
|
nsRefPtr<Response> response = new Response(mOwner, ir);
|
||||||
return response.forget();
|
return response.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Response::SetBody(nsIInputStream* aBody)
|
Response::SetBody(nsIInputStream* aBody)
|
||||||
{
|
{
|
||||||
// FIXME(nsm): Do we flip bodyUsed here?
|
MOZ_ASSERT(!BodyUsed());
|
||||||
mInternalResponse->SetBody(aBody);
|
mInternalResponse->SetBody(aBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Response>
|
already_AddRefed<Response>
|
||||||
Clone();
|
Clone(ErrorResult& aRv) const;
|
||||||
|
|
||||||
void
|
void
|
||||||
SetBody(nsIInputStream* aBody);
|
SetBody(nsIInputStream* aBody);
|
||||||
|
@ -23,7 +23,8 @@ interface Request {
|
|||||||
readonly attribute RequestCredentials credentials;
|
readonly attribute RequestCredentials credentials;
|
||||||
readonly attribute RequestCache cache;
|
readonly attribute RequestCache cache;
|
||||||
|
|
||||||
[NewObject] Request clone();
|
[Throws,
|
||||||
|
NewObject] Request clone();
|
||||||
|
|
||||||
// Bug 1124638 - Allow chrome callers to set the context.
|
// Bug 1124638 - Allow chrome callers to set the context.
|
||||||
[ChromeOnly]
|
[ChromeOnly]
|
||||||
|
@ -25,7 +25,8 @@ interface Response {
|
|||||||
readonly attribute ByteString statusText;
|
readonly attribute ByteString statusText;
|
||||||
[SameObject] readonly attribute Headers headers;
|
[SameObject] readonly attribute Headers headers;
|
||||||
|
|
||||||
[NewObject] Response clone();
|
[Throws,
|
||||||
|
NewObject] Response clone();
|
||||||
};
|
};
|
||||||
Response implements Body;
|
Response implements Body;
|
||||||
|
|
||||||
|
@ -27,21 +27,70 @@ function testDefaultCtor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testClone() {
|
function testClone() {
|
||||||
var req = (new Request("./cloned_request.txt", {
|
var orig = new Request("./cloned_request.txt", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { "Content-Length": 5 },
|
headers: { "Content-Length": 5 },
|
||||||
body: "Sample body",
|
body: "Sample body",
|
||||||
mode: "same-origin",
|
mode: "same-origin",
|
||||||
credentials: "same-origin",
|
credentials: "same-origin",
|
||||||
})).clone();
|
});
|
||||||
ok(req.method === "POST", "Request method is POST");
|
var clone = orig.clone();
|
||||||
ok(req.headers instanceof Headers, "Request should have non-null Headers object");
|
ok(clone.method === "POST", "Request method is POST");
|
||||||
is(req.headers.get('content-length'), "5", "Request content-length should be 5.");
|
ok(clone.headers instanceof Headers, "Request should have non-null Headers object");
|
||||||
ok(req.url === (new URL("./cloned_request.txt", self.location.href)).href,
|
|
||||||
|
is(clone.headers.get('content-length'), "5", "Response content-length should be 5.");
|
||||||
|
orig.headers.set('content-length', 6);
|
||||||
|
is(clone.headers.get('content-length'), "5", "Request content-length should be 5.");
|
||||||
|
|
||||||
|
ok(clone.url === (new URL("./cloned_request.txt", self.location.href)).href,
|
||||||
"URL should be resolved with entry settings object's API base URL");
|
"URL should be resolved with entry settings object's API base URL");
|
||||||
ok(req.referrer === "about:client", "Default referrer is `client` which serializes to about:client.");
|
ok(clone.referrer === "about:client", "Default referrer is `client` which serializes to about:client.");
|
||||||
ok(req.mode === "same-origin", "Request mode is same-origin");
|
ok(clone.mode === "same-origin", "Request mode is same-origin");
|
||||||
ok(req.credentials === "same-origin", "Default credentials is same-origin");
|
ok(clone.credentials === "same-origin", "Default credentials is same-origin");
|
||||||
|
|
||||||
|
ok(!orig.bodyUsed, "Original body is not consumed.");
|
||||||
|
ok(!clone.bodyUsed, "Clone body is not consumed.");
|
||||||
|
|
||||||
|
var origBody = null;
|
||||||
|
var clone2 = null;
|
||||||
|
return orig.text().then(function (body) {
|
||||||
|
origBody = body;
|
||||||
|
is(origBody, "Sample body", "Original body string matches");
|
||||||
|
ok(orig.bodyUsed, "Original body is consumed.");
|
||||||
|
ok(!clone.bodyUsed, "Clone body is not consumed.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
orig.clone()
|
||||||
|
ok(false, "Cannot clone Request whose body is already consumed");
|
||||||
|
} catch (e) {
|
||||||
|
is(e.name, "TypeError", "clone() of consumed body should throw TypeError");
|
||||||
|
}
|
||||||
|
|
||||||
|
clone2 = clone.clone();
|
||||||
|
return clone.text();
|
||||||
|
}).then(function (body) {
|
||||||
|
is(body, origBody, "Clone body matches original body.");
|
||||||
|
ok(clone.bodyUsed, "Clone body is consumed.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
clone.clone()
|
||||||
|
ok(false, "Cannot clone Request whose body is already consumed");
|
||||||
|
} catch (e) {
|
||||||
|
is(e.name, "TypeError", "clone() of consumed body should throw TypeError");
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone2.text();
|
||||||
|
}).then(function (body) {
|
||||||
|
is(body, origBody, "Clone body matches original body.");
|
||||||
|
ok(clone2.bodyUsed, "Clone body is consumed.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
clone2.clone()
|
||||||
|
ok(false, "Cannot clone Request whose body is already consumed");
|
||||||
|
} catch (e) {
|
||||||
|
is(e.name, "TypeError", "clone() of consumed body should throw TypeError");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function testUsedRequest() {
|
function testUsedRequest() {
|
||||||
@ -266,7 +315,6 @@ onmessage = function() {
|
|||||||
var done = function() { postMessage({ type: 'finish' }) }
|
var done = function() { postMessage({ type: 'finish' }) }
|
||||||
|
|
||||||
testDefaultCtor();
|
testDefaultCtor();
|
||||||
testClone();
|
|
||||||
testSimpleUrlParse();
|
testSimpleUrlParse();
|
||||||
testUrlFragment();
|
testUrlFragment();
|
||||||
testMethod();
|
testMethod();
|
||||||
@ -278,6 +326,7 @@ onmessage = function() {
|
|||||||
.then(testBodyUsed)
|
.then(testBodyUsed)
|
||||||
.then(testBodyExtraction)
|
.then(testBodyExtraction)
|
||||||
.then(testUsedRequest)
|
.then(testUsedRequest)
|
||||||
|
.then(testClone())
|
||||||
// Put more promise based tests here.
|
// Put more promise based tests here.
|
||||||
.then(done)
|
.then(done)
|
||||||
.catch(function(e) {
|
.catch(function(e) {
|
||||||
|
@ -18,15 +18,63 @@ function testDefaultCtor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testClone() {
|
function testClone() {
|
||||||
var res = (new Response("This is a body", {
|
var orig = new Response("This is a body", {
|
||||||
status: 404,
|
status: 404,
|
||||||
statusText: "Not Found",
|
statusText: "Not Found",
|
||||||
headers: { "Content-Length": 5 },
|
headers: { "Content-Length": 5 },
|
||||||
})).clone();
|
});
|
||||||
is(res.status, 404, "Response status is 404");
|
var clone = orig.clone();
|
||||||
is(res.statusText, "Not Found", "Response statusText is POST");
|
is(clone.status, 404, "Response status is 404");
|
||||||
ok(res.headers instanceof Headers, "Response should have non-null Headers object");
|
is(clone.statusText, "Not Found", "Response statusText is POST");
|
||||||
is(res.headers.get('content-length'), "5", "Response content-length should be 5.");
|
ok(clone.headers instanceof Headers, "Response should have non-null Headers object");
|
||||||
|
|
||||||
|
is(clone.headers.get('content-length'), "5", "Response content-length should be 5.");
|
||||||
|
orig.headers.set('content-length', 6);
|
||||||
|
is(clone.headers.get('content-length'), "5", "Response content-length should be 5.");
|
||||||
|
|
||||||
|
ok(!orig.bodyUsed, "Original body is not consumed.");
|
||||||
|
ok(!clone.bodyUsed, "Clone body is not consumed.");
|
||||||
|
|
||||||
|
var origBody = null;
|
||||||
|
var clone2 = null;
|
||||||
|
return orig.text().then(function (body) {
|
||||||
|
origBody = body;
|
||||||
|
is(origBody, "This is a body", "Original body string matches");
|
||||||
|
ok(orig.bodyUsed, "Original body is consumed.");
|
||||||
|
ok(!clone.bodyUsed, "Clone body is not consumed.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
orig.clone()
|
||||||
|
ok(false, "Cannot clone Response whose body is already consumed");
|
||||||
|
} catch (e) {
|
||||||
|
is(e.name, "TypeError", "clone() of consumed body should throw TypeError");
|
||||||
|
}
|
||||||
|
|
||||||
|
clone2 = clone.clone();
|
||||||
|
return clone.text();
|
||||||
|
}).then(function (body) {
|
||||||
|
is(body, origBody, "Clone body matches original body.");
|
||||||
|
ok(clone.bodyUsed, "Clone body is consumed.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
clone.clone()
|
||||||
|
ok(false, "Cannot clone Response whose body is already consumed");
|
||||||
|
} catch (e) {
|
||||||
|
is(e.name, "TypeError", "clone() of consumed body should throw TypeError");
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone2.text();
|
||||||
|
}).then(function (body) {
|
||||||
|
is(body, origBody, "Clone body matches original body.");
|
||||||
|
ok(clone2.bodyUsed, "Clone body is consumed.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
clone2.clone()
|
||||||
|
ok(false, "Cannot clone Response whose body is already consumed");
|
||||||
|
} catch (e) {
|
||||||
|
is(e.name, "TypeError", "clone() of consumed body should throw TypeError");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRedirect() {
|
function testRedirect() {
|
||||||
|
Loading…
Reference in New Issue
Block a user