-
Notifications
You must be signed in to change notification settings - Fork 348
Use service extension in networking integration test #9323
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
Changes from all commits
aa3d173
6f78d05
4873931
6a31a4b
d5cde19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,14 +6,69 @@ | |
|
||
import 'dart:async'; | ||
import 'dart:convert' show json; | ||
import 'dart:developer'; | ||
import 'dart:io' as io; | ||
|
||
import 'package:dio/dio.dart'; | ||
import 'package:http/http.dart' as http; | ||
|
||
void main() async { | ||
final testServer = await _bindTestServer(); | ||
await _bindControlServer(testServer); | ||
_registerMakeRequestExtension(testServer); | ||
} | ||
|
||
void _registerMakeRequestExtension(io.HttpServer testServer) { | ||
final client = _HttpClient(testServer.port); | ||
registerExtension('ext.networking_app.makeRequest', (_, parameters) async { | ||
final hasBody = bool.tryParse(parameters['hasBody'] ?? 'false') ?? false; | ||
final requestType = parameters['requestType']; | ||
if (requestType == null) { | ||
return ServiceExtensionResponse.error( | ||
ServiceExtensionResponse.invalidParams, | ||
json.encode({'error': 'Missing "requestType" field'}), | ||
); | ||
} | ||
switch (requestType) { | ||
case 'get': | ||
client.get(); | ||
case 'post': | ||
client.post(hasBody: hasBody); | ||
case 'put': | ||
client.put(hasBody: hasBody); | ||
case 'delete': | ||
client.delete(hasBody: hasBody); | ||
case 'dioGet': | ||
client.dioGet(); | ||
case 'dioPost': | ||
client.dioPost(hasBody: hasBody); | ||
case 'packageHttpGet': | ||
client.packageHttpGet(); | ||
case 'packageHttpPost': | ||
client.packageHttpPost(hasBody: hasBody); | ||
case 'packageHttpPostStreamed': | ||
client.packageHttpPostStreamed(); | ||
default: | ||
return ServiceExtensionResponse.error( | ||
ServiceExtensionResponse.invalidParams, | ||
json.encode({'error': 'Unknown requestType: "$requestType"'}), | ||
); | ||
} | ||
return ServiceExtensionResponse.result(json.encode({'type': 'success'})); | ||
}); | ||
|
||
registerExtension('ext.networking_app.exit', (_, parameters) async { | ||
// This service extension needs to trigger `io.exit(0)`, and also return a | ||
// value. (You might expect `Future.microtask(() => io.exit(0))` to be | ||
// sufficient, but that results in DevTools erroring, saying that the | ||
// connected app unxexpectedly disconnected; it seems that returning a value | ||
// needs to work through some microtasks.) A 200 ms delay seems to work, so | ||
// that the following `ServiceExtensionResponse` makes it all the way to | ||
// DevTools, and _then_ we can exit. | ||
unawaited( | ||
Future.delayed(const Duration(milliseconds: 200)).then((_) => io.exit(0)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question about delayed here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I'll add a comment here. The issue is that this service extension triggers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thanks! |
||
); | ||
return ServiceExtensionResponse.result(json.encode({'type': 'success'})); | ||
}); | ||
} | ||
|
||
/// Binds a "test" HTTP server to an available port. | ||
|
@@ -30,50 +85,6 @@ Future<io.HttpServer> _bindTestServer() async { | |
return server; | ||
} | ||
|
||
/// Binds a "control" HTTP server to an available port. | ||
/// | ||
/// This server has an HTTP client, and can receive commands for that client to | ||
/// send requests to the "test" HTTP server. | ||
Future<io.HttpServer> _bindControlServer(io.HttpServer testServer) async { | ||
final client = _HttpClient(testServer.port); | ||
|
||
final server = await io.HttpServer.bind(io.InternetAddress.loopbackIPv4, 0); | ||
print(json.encode({'controlPort': server.port})); | ||
server.listen((request) async { | ||
request.response.headers | ||
..add('Access-Control-Allow-Origin', '*') | ||
..add('Access-Control-Allow-Methods', 'POST,GET,DELETE,PUT,OPTIONS'); | ||
final path = request.uri.path; | ||
final hasBody = path.contains('/body/'); | ||
request.response | ||
..statusCode = 200 | ||
..write('received request at: "$path"'); | ||
|
||
if (path.startsWith('/get/')) { | ||
client.get(); | ||
} else if (path.startsWith('/post/')) { | ||
client.post(hasBody: hasBody); | ||
} else if (path.startsWith('/put/')) { | ||
client.put(hasBody: hasBody); | ||
} else if (path.startsWith('/delete/')) { | ||
client.delete(hasBody: hasBody); | ||
} else if (path.startsWith('/dio/get/')) { | ||
client.dioGet(); | ||
} else if (path.startsWith('/dio/post/')) { | ||
client.dioPost(hasBody: hasBody); | ||
} else if (path.startsWith('/packageHttp/post/')) { | ||
client.packageHttpPost(hasBody: hasBody); | ||
} else if (path.startsWith('/packageHttp/postStreamed/')) { | ||
client.packageHttpPostStreamed(); | ||
} else if (path.startsWith('/exit/')) { | ||
client.close(); | ||
io.exit(0); | ||
} | ||
await request.response.close(); | ||
}); | ||
return server; | ||
} | ||
|
||
// TODO(https://github.com/flutter/devtools/issues/8223): Test support for | ||
// WebSockets. | ||
// TODO(https://github.com/flutter/devtools/issues/4829): Test support for the | ||
|
@@ -136,6 +147,13 @@ class _HttpClient { | |
print('Received DELETE response: $response'); | ||
} | ||
|
||
void packageHttpGet() async { | ||
print('Sending package:http GET...'); | ||
// No body. | ||
final response = await http.get(_uri); | ||
print('Received package:http GET response: $response'); | ||
} | ||
|
||
void packageHttpPost({bool hasBody = false}) async { | ||
print('Sending package:http POST...'); | ||
final response = await http.post( | ||
|
Uh oh!
There was an error while loading. Please reload this page.