New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add response cancellation function #1082
Labels
Comments
glanium
added
package:cronet_http
type-enhancement
A request for a change that isn't a bug
labels
Dec 17, 2023
following might be safer implementation. jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface _urlRequestCallbacks(
BaseRequest request, Completer<StreamedResponse> responseCompleter) {
StreamController<List<int>>? responseStream;
JByteBuffer? jByteBuffer;
var numRedirects = 0;
var cancelled; // <-- flag
// The order of callbacks generated by Cronet is documented here:
// https://developer.android.com/guide/topics/connectivity/cronet/lifecycle
return jb.UrlRequestCallbackProxy_UrlRequestCallbackInterface.implement(
jb.$UrlRequestCallbackProxy_UrlRequestCallbackInterfaceImpl(
onResponseStarted: (urlRequest, responseInfo) {
responseStream = StreamController(onCancel: () => cancelled = true); // <--- set flag
final responseHeaders =
_cronetToClientHeaders(responseInfo.getAllHeaders());
int? contentLength;
switch (responseHeaders['content-length']) {
case final contentLengthHeader?
when !_digitRegex.hasMatch(contentLengthHeader):
responseCompleter.completeError(ClientException(
'Invalid content-length header [$contentLengthHeader].',
request.url,
));
urlRequest.cancel();
return;
case final contentLengthHeader?:
contentLength = int.parse(contentLengthHeader);
}
responseCompleter.complete(StreamedResponse(
responseStream!.stream,
responseInfo.getHttpStatusCode(),
contentLength: contentLength,
reasonPhrase: responseInfo
.getHttpStatusText()
.toDartString(releaseOriginal: true),
request: request,
isRedirect: false,
headers: responseHeaders,
));
jByteBuffer = JByteBuffer.allocateDirect(_bufferSize);
urlRequest.read(jByteBuffer!);
},
onRedirectReceived: (urlRequest, responseInfo, newLocationUrl) {
if (!request.followRedirects) {
urlRequest.cancel();
responseCompleter.complete(StreamedResponse(
const Stream.empty(), // Cronet provides no body for redirects.
responseInfo.getHttpStatusCode(),
contentLength: 0,
reasonPhrase: responseInfo
.getHttpStatusText()
.toDartString(releaseOriginal: true),
request: request,
isRedirect: true,
headers: _cronetToClientHeaders(responseInfo.getAllHeaders())));
return;
}
++numRedirects;
if (numRedirects <= request.maxRedirects) {
urlRequest.followRedirect();
} else {
urlRequest.cancel();
responseCompleter.completeError(
ClientException('Redirect limit exceeded', request.url));
}
},
onReadCompleted: (urlRequest, responseInfo, byteBuffer) {
if (cancelled) {
urlRequest.cancel(); // <-- cancel and cleanup here
//responseStream!.sink.close();
byteBuffer.release();
} else {
byteBuffer.flip();
responseStream!
.add(jByteBuffer!.asUint8List().sublist(0, byteBuffer.remaining));
byteBuffer.clear();
urlRequest.read(byteBuffer);
}
}, |
Any update on this? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I mean Response cancellation than Request cancellation.
i.e. After received response, I wanna cancel response.
following is usecase
In dart' stream, Stream can be cacelled by invoking subscription's cancel method.
Then StreamController will be notifed of cancel.
As long as i look at current crotnet_http implementaion, cancel request is ignored completely.
https://github.com/dart-lang/http/blob/c114aa06c510a28e942e9158711ed052b492c980/pkgs/cronet_http/lib/src/cronet_client.dart#L144C1-L152C26
Add onCancel callback to StreamController then handle cancel request.
This applies to cupertino_http package if it support cancel.
HTTP2 supports multiplexing, and can force the stream to be closed by sending frame
RST_STREAM
In case of HTTP1, Cancel causes connection close?
thx.
The text was updated successfully, but these errors were encountered: