1499a30cd5
Fix failures https://dart-ci.appspot.com/log/vm-linux-release-x64/vm-linux-release-x64/6082/samples/ffi/httpIG/test/http_test
Lift .status-file constraints on where http and httpIG samples can run.
Follow-up to b759d096cb
TEST=ci
Change-Id: Icc71d6407e910d30f6ff028830550a05b179f1da
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/444927
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
146 lines
4.2 KiB
Dart
146 lines
4.2 KiB
Dart
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:ffi';
|
|
import 'dart:isolate';
|
|
import 'dart:io';
|
|
|
|
import 'package:ffi/ffi.dart';
|
|
|
|
import 'dylib_utils.dart';
|
|
|
|
Function (Pointer<Utf8>) createGetSender(final SendPort sendPort) {
|
|
return (Pointer<Utf8> responsePointer) {
|
|
final typedList = responsePointer.cast<Uint8>().asTypedList(
|
|
responsePointer.length,
|
|
);
|
|
sendPort.send(utf8.decode(typedList));
|
|
};
|
|
}
|
|
|
|
// Runs a simple HTTP GET request using a native HTTP library that runs
|
|
// the request on a background thread.
|
|
Future<String> httpGet(String uri) async {
|
|
// Create the NativeCallable.listener.
|
|
final completer = Completer<String>();
|
|
final ReceivePort rp = ReceivePort()
|
|
..listen(
|
|
(string) {
|
|
completer.complete(string);
|
|
},
|
|
onError: (e, st) {
|
|
print('httpGet receiver get error $e $st');
|
|
},
|
|
);
|
|
final callback = NativeCallable<HttpCallback>.isolateGroupBound(
|
|
createGetSender(rp.sendPort));
|
|
|
|
// Invoke the native HTTP API. Our example HTTP library runs our GET
|
|
// request on a background thread, and calls the callback on that same
|
|
// thread when it receives the response.
|
|
final uriPointer = uri.toNativeUtf8();
|
|
nativeHttpGet(uriPointer, callback.nativeFunction);
|
|
calloc.free(uriPointer);
|
|
|
|
// Wait for the response.
|
|
final response = await completer.future;
|
|
|
|
rp.close();
|
|
callback.close();
|
|
|
|
return response;
|
|
}
|
|
|
|
@pragma('vm:shared')
|
|
late int counter;
|
|
|
|
Function (Pointer<Utf8>) createServeSender(final SendPort sendPort) {
|
|
return (Pointer<Utf8> requestPointer) {
|
|
counter++;
|
|
final typedList = requestPointer.cast<Uint8>().asTypedList(
|
|
requestPointer.length,
|
|
);
|
|
sendPort.send(utf8.decode(typedList));
|
|
};
|
|
}
|
|
|
|
// Start a HTTP server on a background thread.
|
|
ReceivePort httpServe(void Function(String) onRequest) {
|
|
counter = 0;
|
|
final rp = ReceivePort();
|
|
final callback = NativeCallable<HttpCallback>.isolateGroupBound(
|
|
createServeSender(rp.sendPort));
|
|
rp.listen(
|
|
(s) {
|
|
print('httpServe counter: $counter');
|
|
onRequest(s);
|
|
},
|
|
onError: (e, st) {
|
|
print('httpServe receiver get error $e $st');
|
|
},
|
|
onDone: () {
|
|
nativeHttpStopServing();
|
|
callback.close();
|
|
},
|
|
);
|
|
|
|
// Invoke the native function to start the HTTP server. Our example
|
|
// HTTP library will start a server on a background thread, and pass
|
|
// any requests it receives to out callback.
|
|
nativeHttpStartServing(callback.nativeFunction);
|
|
|
|
return rp;
|
|
}
|
|
|
|
// Load the native functions from a DynamicLibrary.
|
|
late final DynamicLibrary dylib = dlopenPlatformSpecific(
|
|
'fake_httpIG',
|
|
paths: [
|
|
Platform.script.resolve('../lib/'),
|
|
Uri.file(Platform.resolvedExecutable),
|
|
],
|
|
);
|
|
typedef HttpCallback = Void Function(Pointer<Utf8>);
|
|
|
|
typedef HttpGetFunction = void Function(
|
|
Pointer<Utf8>, Pointer<NativeFunction<HttpCallback>>);
|
|
typedef HttpGetNativeFunction = Void Function(
|
|
Pointer<Utf8>, Pointer<NativeFunction<HttpCallback>>);
|
|
final nativeHttpGet =
|
|
dylib.lookupFunction<HttpGetNativeFunction, HttpGetFunction>('http_get');
|
|
|
|
typedef HttpStartServingFunction = bool Function(
|
|
Pointer<NativeFunction<HttpCallback>>);
|
|
typedef HttpStartServingNativeFunction = Bool Function(
|
|
Pointer<NativeFunction<HttpCallback>>);
|
|
final nativeHttpStartServing = dylib
|
|
.lookupFunction<HttpStartServingNativeFunction, HttpStartServingFunction>(
|
|
'http_start_serving',
|
|
);
|
|
|
|
typedef HttpStopServingFunction = void Function();
|
|
typedef HttpStopServingNativeFunction = Void Function();
|
|
final nativeHttpStopServing = dylib
|
|
.lookupFunction<HttpStopServingNativeFunction, HttpStopServingFunction>(
|
|
'http_stop_serving',
|
|
);
|
|
|
|
Future<void> main() async {
|
|
print('Sending GET request...');
|
|
final response = await httpGet('http://example.com');
|
|
print('Received a response: $response');
|
|
|
|
print('Starting HTTP server...');
|
|
final rpServer = httpServe((String request) {
|
|
print('Received a request: $request');
|
|
});
|
|
|
|
await Future.delayed(Duration(seconds: 10));
|
|
print('All done');
|
|
|
|
rpServer.close();
|
|
}
|