Skip to content

Commit f2d0f74

Browse files
authored
Merge pull request #3735 from cloudflare/mar/request-signal
Revert request Request.signal detection to client disconnects.
2 parents efcc877 + 7142cb5 commit f2d0f74

12 files changed

+17
-314
lines changed

src/workerd/api/BUILD.bazel

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -680,9 +680,3 @@ wd_test(
680680
args = ["--experimental"],
681681
data = ["tests/disable-importable-env-test.js"],
682682
)
683-
684-
wd_test(
685-
src = "tests/request-client-disconnect.wd-test",
686-
args = ["--experimental"],
687-
data = ["tests/request-client-disconnect.js"],
688-
)

src/workerd/api/basics.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ class EventTarget: public jsg::Object {
512512
// An implementation of the Web Platform Standard AbortSignal API
513513
class AbortSignal final: public EventTarget {
514514
public:
515-
enum class Flag { NONE, NEVER_ABORTS, IGNORE_FOR_SUBREQUESTS };
515+
enum class Flag { NONE, NEVER_ABORTS };
516516

517517
AbortSignal(kj::Maybe<kj::Exception> exception = kj::none,
518518
jsg::Optional<jsg::JsRef<jsg::JsValue>> maybeReason = kj::none,
@@ -603,14 +603,9 @@ class AbortSignal final: public EventTarget {
603603
tracker.trackField("reason", reason);
604604
}
605605

606-
bool isIgnoredForSubrequests() const {
607-
return flag == Flag::IGNORE_FOR_SUBREQUESTS;
608-
}
609-
610606
private:
611607
IoOwn<RefcountedCanceler> canceler;
612608
Flag flag;
613-
614609
kj::Maybe<jsg::JsRef<jsg::JsValue>> reason;
615610
kj::Maybe<jsg::JsRef<jsg::JsValue>> onAbortHandler;
616611

@@ -622,9 +617,7 @@ class AbortSignal final: public EventTarget {
622617
// An implementation of the Web Platform Standard AbortController API
623618
class AbortController final: public jsg::Object {
624619
public:
625-
explicit AbortController(AbortSignal::Flag abortSignalFlag = AbortSignal::Flag::NONE)
626-
: signal(jsg::alloc<AbortSignal>(
627-
kj::none /* exception */, kj::none /* maybeReason */, abortSignalFlag)) {}
620+
explicit AbortController(): signal(jsg::alloc<AbortSignal>()) {}
628621

629622
static jsg::Ref<AbortController> constructor() {
630623
return jsg::alloc<AbortController>();

src/workerd/api/global-scope.c++

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ kj::Promise<DeferredProxy<void>> ServiceWorkerGlobalScope::request(kj::HttpMetho
145145
kj::HttpService::Response& response,
146146
kj::Maybe<kj::StringPtr> cfBlobJson,
147147
Worker::Lock& lock,
148-
kj::Maybe<ExportedHandler&> exportedHandler,
149-
kj::Maybe<jsg::Ref<AbortSignal>> abortSignal) {
148+
kj::Maybe<ExportedHandler&> exportedHandler) {
150149
TRACE_EVENT("workerd", "ServiceWorkerGlobalScope::request()");
151150
// To construct a ReadableStream object, we're supposed to pass in an Own<AsyncInputStream>, so
152151
// that it can drop the reference whenever it gets GC'ed. But in this case the stream's lifetime
@@ -217,17 +216,7 @@ kj::Promise<DeferredProxy<void>> ServiceWorkerGlobalScope::request(kj::HttpMetho
217216

218217
auto jsRequest = jsg::alloc<Request>(method, url, Request::Redirect::MANUAL, kj::mv(jsHeaders),
219218
jsg::alloc<Fetcher>(IoContext::NEXT_CLIENT_CHANNEL, Fetcher::RequiresHostAndProtocol::YES),
220-
/* signal */ kj::none, kj::mv(cf), kj::mv(body),
221-
/* thisSignal */ kj::mv(abortSignal), Request::CacheMode::NONE);
222-
223-
// signal vs thisSignal
224-
// --------------------
225-
// The fetch spec definition of Request has a distinction between the
226-
// "signal" (which is an optional AbortSignal passed in with the options), and "this' signal",
227-
// which is an AbortSignal that is always available via the request.signal accessor.
228-
//
229-
// redirect
230-
// --------
219+
kj::none /** AbortSignal **/, kj::mv(cf), kj::mv(body));
231220
// I set the redirect mode to manual here, so that by default scripts that just pass requests
232221
// through to a fetch() call will behave the same as scripts which don't call .respondWith(): if
233222
// the request results in a redirect, the visitor will see that redirect.

src/workerd/api/global-scope.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,7 @@ class ServiceWorkerGlobalScope: public WorkerGlobalScope {
463463
kj::HttpService::Response& response,
464464
kj::Maybe<kj::StringPtr> cfBlobJson,
465465
Worker::Lock& lock,
466-
kj::Maybe<ExportedHandler&> exportedHandler,
467-
kj::Maybe<jsg::Ref<AbortSignal>> abortSignal);
466+
kj::Maybe<ExportedHandler&> exportedHandler);
468467
// TODO(cleanup): Factor out the shared code used between old-style event listeners vs. module
469468
// exports and move that code somewhere more appropriate.
470469

src/workerd/api/http.c++

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ jsg::Ref<Request> Request::constructor(
996996
cacheMode = oldRequest->getCacheMode();
997997
redirect = oldRequest->getRedirectEnum();
998998
fetcher = oldRequest->getFetcher();
999-
signal = oldRequest->getThisSignal();
999+
signal = oldRequest->getSignal();
10001000
}
10011001
}
10021002

@@ -1052,7 +1052,6 @@ jsg::Ref<Request> Request::constructor(
10521052
// explicitly say `signal: null`, they must want to drop the signal that was on the
10531053
// original request.
10541054
signal = kj::mv(s);
1055-
initDict.signal = kj::none;
10561055
}
10571056

10581057
KJ_IF_SOME(newCf, initDict.cf) {
@@ -1106,7 +1105,7 @@ jsg::Ref<Request> Request::constructor(
11061105
cacheMode = otherRequest->cacheMode;
11071106
responseBodyEncoding = otherRequest->responseBodyEncoding;
11081107
fetcher = otherRequest->getFetcher();
1109-
signal = otherRequest->getThisSignal();
1108+
signal = otherRequest->getSignal();
11101109
headers = jsg::alloc<Headers>(*otherRequest->headers);
11111110
cf = otherRequest->cf.deepClone(js);
11121111
KJ_IF_SOME(b, otherRequest->getBody()) {
@@ -1125,8 +1124,7 @@ jsg::Ref<Request> Request::constructor(
11251124

11261125
// TODO(conform): If `init` has a keepalive flag, pass it to the Body constructor.
11271126
return jsg::alloc<Request>(method, url, redirect, KJ_ASSERT_NONNULL(kj::mv(headers)),
1128-
kj::mv(fetcher), kj::mv(signal), kj::mv(cf), kj::mv(body), /* thisSignal */ kj::none,
1129-
cacheMode, responseBodyEncoding);
1127+
kj::mv(fetcher), kj::mv(signal), kj::mv(cf), kj::mv(body), cacheMode, responseBodyEncoding);
11301128
}
11311129

11321130
jsg::Ref<Request> Request::clone(jsg::Lock& js) {
@@ -1136,8 +1134,8 @@ jsg::Ref<Request> Request::clone(jsg::Lock& js) {
11361134
auto bodyClone = Body::clone(js);
11371135

11381136
return jsg::alloc<Request>(method, url, redirect, kj::mv(headersClone), getFetcher(),
1139-
/* signal */ getThisSignal(), kj::mv(cfClone), kj::mv(bodyClone), /* thisSignal */ kj::none,
1140-
cacheMode, responseBodyEncoding);
1137+
/* signal */ getThisSignal(js), kj::mv(cfClone), kj::mv(bodyClone), cacheMode,
1138+
responseBodyEncoding);
11411139

11421140
// signal
11431141
//-------
@@ -1186,7 +1184,7 @@ jsg::Optional<jsg::JsObject> Request::getCf(jsg::Lock& js) {
11861184
// that's a bit silly and unnecessary.
11871185
// The name "thisSignal" is derived from the fetch spec, which draws a
11881186
// distinction between the "signal" and "this' signal".
1189-
jsg::Ref<AbortSignal> Request::getThisSignal() {
1187+
jsg::Ref<AbortSignal> Request::getThisSignal(jsg::Lock& js) {
11901188
KJ_IF_SOME(s, signal) {
11911189
return s.addRef();
11921190
}
@@ -1198,14 +1196,6 @@ jsg::Ref<AbortSignal> Request::getThisSignal() {
11981196
return newSignal;
11991197
}
12001198

1201-
void Request::clearSignalIfIgnoredForSubrequest() {
1202-
KJ_IF_SOME(s, signal) {
1203-
if (s->isIgnoredForSubrequests()) {
1204-
signal = kj::none;
1205-
}
1206-
}
1207-
}
1208-
12091199
kj::Maybe<Request::Redirect> Request::tryParseRedirect(kj::StringPtr redirect) {
12101200
if (strcasecmp(redirect.cStr(), "follow") == 0) {
12111201
return Redirect::FOLLOW;
@@ -2257,11 +2247,6 @@ jsg::Promise<jsg::Ref<Response>> fetchImplNoOutputLock(jsg::Lock& js,
22572247
// front is robust, and won't add significant overhead compared to the rest of fetch().
22582248
auto jsRequest = Request::constructor(js, kj::mv(requestOrUrl), kj::mv(requestInit));
22592249

2260-
// Clear the request's signal if the 'ignoreForSubrequests' flag is set. This happens when
2261-
// a request from an incoming fetch is passed-through to another fetch. We want to avoid
2262-
// aborting the subrequest in that case.
2263-
jsRequest->clearSignalIfIgnoredForSubrequest();
2264-
22652250
// This URL list keeps track of redirections and becomes a source for Response's URL list. The
22662251
// first URL in the list is the Request's URL (visible to JS via Request::getUrl()). The last URL
22672252
// in the list is the Request's "current" URL (eventually visible to JS via Response::getUrl()).

src/workerd/api/http.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ class Request final: public Body {
791791
Request(kj::HttpMethod method, kj::StringPtr url, Redirect redirect,
792792
jsg::Ref<Headers> headers, kj::Maybe<jsg::Ref<Fetcher>> fetcher,
793793
kj::Maybe<jsg::Ref<AbortSignal>> signal, CfProperty&& cf,
794-
kj::Maybe<Body::ExtractedBody> body, kj::Maybe<jsg::Ref<AbortSignal>> thisSignal,
794+
kj::Maybe<Body::ExtractedBody> body,
795795
CacheMode cacheMode = CacheMode::NONE,
796796
Response_BodyEncoding responseBodyEncoding = Response_BodyEncoding::AUTO)
797797
: Body(kj::mv(body), *headers), method(method), url(kj::str(url)),
@@ -802,15 +802,11 @@ class Request final: public Body {
802802
// that the cancel machinery is not used but the request.signal accessor will still
803803
// do the right thing.
804804
if (s->getNeverAborts()) {
805-
this->thisSignal = s.addRef();
805+
this->thisSignal = kj::mv(s);
806806
} else {
807-
this->signal = s.addRef();
807+
this->signal = kj::mv(s);
808808
}
809809
}
810-
811-
KJ_IF_SOME(s, thisSignal) {
812-
this->thisSignal = s.addRef();
813-
}
814810
}
815811
// TODO(conform): Technically, the request's URL should be parsed immediately upon Request
816812
// construction, and any errors encountered should be thrown. Instead, we defer parsing until
@@ -862,12 +858,8 @@ class Request final: public Body {
862858
// request.signal to always return an AbortSignal even if one is not actively
863859
// used on this request.
864860
kj::Maybe<jsg::Ref<AbortSignal>> getSignal();
865-
jsg::Ref<AbortSignal> getThisSignal();
866861

867-
// Clear the request's signal if the 'ignoreForSubrequests' flag is set. This happens when
868-
// a request from an incoming fetch is passed-through to another fetch. We want to avoid
869-
// aborting the subrequest in that case.
870-
void clearSignalIfIgnoredForSubrequest();
862+
jsg::Ref<AbortSignal> getThisSignal(jsg::Lock& js);
871863

872864
// Returns the `cf` field containing Cloudflare feature flags.
873865
jsg::Optional<jsg::JsObject> getCf(jsg::Lock& js);

src/workerd/api/tests/request-client-disconnect.js

Lines changed: 0 additions & 187 deletions
This file was deleted.

0 commit comments

Comments
 (0)