2.0.0
This commit is contained in:
parent
9ff915a105
commit
8291b3b280
7 changed files with 71 additions and 36 deletions
|
@ -1,3 +1,5 @@
|
|||
# 2.0.0
|
||||
* Updates for Angel 2. Big thanks to @denkuy!
|
||||
|
||||
# 1.1.1
|
||||
Removed reference to `io`; now works with HTTP/2.
|
||||
Thanks to @daniel-v!
|
||||
* Removed reference to `io`; now works with HTTP/2. Thanks to @daniel-v!
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
analyzer:
|
||||
strong-mode: true
|
||||
strong-mode:
|
||||
implicit-casts: false
|
|
@ -2,14 +2,14 @@ import 'dart:io';
|
|||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_framework/http.dart';
|
||||
import 'package:angel_proxy/angel_proxy.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/io_client.dart' as http;
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
final Duration timeout = new Duration(seconds: 5);
|
||||
|
||||
main() async {
|
||||
var app = new Angel();
|
||||
var client = new http.Client();
|
||||
var client = new http.IOClient();
|
||||
|
||||
// Forward any /api requests to pub.
|
||||
// By default, if the host throws a 404, the request will fall through to the next handler.
|
||||
|
@ -37,7 +37,8 @@ main() async {
|
|||
app.all('*', dartlangProxy.handleRequest);
|
||||
|
||||
// In case we can't connect to dartlang.org, show an error.
|
||||
app.fallback((req, res) => res.write('Couldn\'t connect to Pub or dartlang.'));
|
||||
app.fallback(
|
||||
(req, res) => res.write('Couldn\'t connect to Pub or dartlang.'));
|
||||
|
||||
app.logger = new Logger('angel')
|
||||
..onRecord.listen(
|
||||
|
@ -48,7 +49,9 @@ main() async {
|
|||
},
|
||||
);
|
||||
|
||||
var server = await AngelHttp(app).startServer(InternetAddress.loopbackIPv4, 8080);
|
||||
var server =
|
||||
await AngelHttp(app).startServer(InternetAddress.loopbackIPv4, 8080);
|
||||
print('Listening at http://${server.address.address}:${server.port}');
|
||||
print('Check this out! http://${server.address.address}:${server.port}/pub/packages/angel_framework');
|
||||
print(
|
||||
'Check this out! http://${server.address.address}:${server.port}/pub/packages/angel_framework');
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ final MediaType _fallbackMediaType = MediaType('application', 'octet-stream');
|
|||
class Proxy {
|
||||
String _prefix;
|
||||
|
||||
final http.Client httpClient;
|
||||
final http.BaseClient httpClient;
|
||||
|
||||
/// If `true` (default), then the plug-in will ignore failures to connect to the proxy, and allow other handlers to run.
|
||||
final bool recoverFromDead;
|
||||
|
@ -34,8 +34,10 @@ class Proxy {
|
|||
this.recoverFrom404: true,
|
||||
this.timeout,
|
||||
}) {
|
||||
if (this.recoverFromDead == null) throw ArgumentError.notNull("recoverFromDead");
|
||||
if (this.recoverFrom404 == null) throw ArgumentError.notNull("recoverFrom404");
|
||||
if (this.recoverFromDead == null)
|
||||
throw ArgumentError.notNull("recoverFromDead");
|
||||
if (this.recoverFrom404 == null)
|
||||
throw ArgumentError.notNull("recoverFrom404");
|
||||
|
||||
_prefix = publicPath?.replaceAll(_straySlashes, '') ?? '';
|
||||
}
|
||||
|
@ -56,7 +58,8 @@ class Proxy {
|
|||
}
|
||||
|
||||
/// Proxies a request to the given path on the remote server.
|
||||
Future<bool> servePath(String path, RequestContext req, ResponseContext res) async {
|
||||
Future<bool> servePath(
|
||||
String path, RequestContext req, ResponseContext res) async {
|
||||
http.StreamedResponse rs;
|
||||
|
||||
final mapping = '$mapTo/$path'.replaceAll(_straySlashes, '');
|
||||
|
@ -74,7 +77,8 @@ class Proxy {
|
|||
'host': port == null ? host : '$host:$port',
|
||||
'x-forwarded-for': req.remoteAddress.address,
|
||||
'x-forwarded-port': req.uri.port.toString(),
|
||||
'x-forwarded-host': req.headers.host ?? req.headers.value('host') ?? 'none',
|
||||
'x-forwarded-host':
|
||||
req.headers.host ?? req.headers.value('host') ?? 'none',
|
||||
'x-forwarded-proto': protocol,
|
||||
};
|
||||
|
||||
|
@ -82,9 +86,10 @@ class Proxy {
|
|||
headers[name] = values.join(',');
|
||||
});
|
||||
|
||||
headers[HttpHeaders.cookieHeader] = req.cookies.map<String>((c) => '${c.name}=${c.value}').join('; ');
|
||||
headers[HttpHeaders.cookieHeader] =
|
||||
req.cookies.map<String>((c) => '${c.name}=${c.value}').join('; ');
|
||||
|
||||
var body;
|
||||
List<int> body;
|
||||
|
||||
if (req.method != 'GET' && req.app.keepRawRequestBuffers == true) {
|
||||
body = (await req.parse()).originalBuffer;
|
||||
|
@ -110,7 +115,8 @@ class Proxy {
|
|||
e,
|
||||
stackTrace: st,
|
||||
statusCode: 504,
|
||||
message: 'Connection to remote host "$host" timed out after ${timeout.inMilliseconds}ms.',
|
||||
message:
|
||||
'Connection to remote host "$host" timed out after ${timeout.inMilliseconds}ms.',
|
||||
);
|
||||
} catch (e) {
|
||||
if (recoverFromDead) return true;
|
||||
|
@ -146,9 +152,12 @@ class Proxy {
|
|||
rs.headers[HttpHeaders.transferEncodingHeader]?.isNotEmpty == true;
|
||||
|
||||
var proxiedHeaders = new Map<String, String>.from(rs.headers)
|
||||
..remove(HttpHeaders.contentEncodingHeader) // drop, http.Client has decoded
|
||||
..remove(HttpHeaders.transferEncodingHeader) // drop, http.Client has decoded
|
||||
..[HttpHeaders.contentLengthHeader] = "${isContentLengthUnknown ? '-1' : rs.contentLength}";
|
||||
..remove(
|
||||
HttpHeaders.contentEncodingHeader) // drop, http.Client has decoded
|
||||
..remove(
|
||||
HttpHeaders.transferEncodingHeader) // drop, http.Client has decoded
|
||||
..[HttpHeaders.contentLengthHeader] =
|
||||
"${isContentLengthUnknown ? '-1' : rs.contentLength}";
|
||||
|
||||
res
|
||||
..contentType = mediaType
|
||||
|
|
10
pubspec.yaml
10
pubspec.yaml
|
@ -1,15 +1,15 @@
|
|||
name: angel_proxy
|
||||
description: Angel middleware to forward requests to another server (i.e. pub serve).
|
||||
version: 1.1.1
|
||||
version: 2.0.0
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/proxy
|
||||
environment:
|
||||
sdk: ">=2.0.0 <3.0.0"
|
||||
dependencies:
|
||||
angel_framework: ^2.0.0-alpha # The core server library.
|
||||
http: ^0.11.3
|
||||
|
||||
angel_framework: ^2.0.0-alpha
|
||||
http: ^0.12.0
|
||||
dev_dependencies:
|
||||
angel_test: 2.0.0-alpha
|
||||
angel_test: ^2.0.0-alpha
|
||||
logging:
|
||||
test: ^1.0.0
|
||||
|
||||
|
|
|
@ -3,21 +3,21 @@ import 'dart:io';
|
|||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_framework/http.dart';
|
||||
import 'package:angel_proxy/angel_proxy.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/io_client.dart' as http;
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'common.dart';
|
||||
|
||||
main() {
|
||||
Angel app;
|
||||
http.Client client = new http.Client();
|
||||
var client = new http.IOClient();
|
||||
HttpServer server, testServer;
|
||||
String url;
|
||||
|
||||
setUp(() async {
|
||||
app = new Angel()..keepRawRequestBuffers = true;
|
||||
var appHttp = AngelHttp(app);
|
||||
var httpClient = new http.Client();
|
||||
var httpClient = new http.IOClient();
|
||||
|
||||
testServer = await startTestServer();
|
||||
|
||||
|
@ -86,8 +86,9 @@ main() {
|
|||
});
|
||||
|
||||
test('original buffer', () async {
|
||||
var response = await client
|
||||
.post('$url/proxy/body', body: json.encode({'foo': 'bar'}), headers: {'content-type': 'application/json'});
|
||||
var response = await client.post('$url/proxy/body',
|
||||
body: json.encode({'foo': 'bar'}),
|
||||
headers: {'content-type': 'application/json'});
|
||||
print('Response: ${response.body}');
|
||||
expect(response.body, isNotEmpty);
|
||||
expect(response.body, isNot('intercept empty'));
|
||||
|
|
|
@ -4,7 +4,8 @@ import 'package:angel_framework/angel_framework.dart';
|
|||
import 'package:angel_framework/http.dart';
|
||||
import 'package:angel_proxy/angel_proxy.dart';
|
||||
import 'package:angel_test/angel_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/io_client.dart' as http;
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:mock_request/mock_request.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
|
@ -16,6 +17,7 @@ main() {
|
|||
setUp(() async {
|
||||
testApp = new Angel();
|
||||
testApp.get('/foo', (req, res) async {
|
||||
res.useBuffer();
|
||||
res.write('pub serve');
|
||||
});
|
||||
testApp.get('/empty', (req, res) => res.close());
|
||||
|
@ -29,9 +31,13 @@ main() {
|
|||
var server = await AngelHttp(testApp).startServer();
|
||||
|
||||
app = new Angel();
|
||||
app.fallback((req, res) {
|
||||
res.useBuffer();
|
||||
return true;
|
||||
});
|
||||
app.get('/bar', (req, res) => res.write('normal'));
|
||||
|
||||
var httpClient = new http.Client();
|
||||
var httpClient = new http.IOClient();
|
||||
|
||||
layer = new Proxy(
|
||||
httpClient,
|
||||
|
@ -39,15 +45,25 @@ main() {
|
|||
port: server.port,
|
||||
publicPath: '/proxy',
|
||||
);
|
||||
app.all("*", layer.handleRequest);
|
||||
|
||||
app.responseFinalizers.add((req, ResponseContext res) async {
|
||||
print('Normal. Buf: ' + new String.fromCharCodes(res.buffer.toBytes()) + ', headers: ${res.headers}');
|
||||
app.fallback(layer.handleRequest);
|
||||
|
||||
app.responseFinalizers.add((req, res) async {
|
||||
print('Normal. Buf: ' +
|
||||
new String.fromCharCodes(res.buffer.toBytes()) +
|
||||
', headers: ${res.headers}');
|
||||
});
|
||||
|
||||
app.encoders.addAll({'gzip': gzip.encoder});
|
||||
|
||||
client = await connectTo(app);
|
||||
|
||||
app.logger = testApp.logger = new Logger('proxy')
|
||||
..onRecord.listen((rec) {
|
||||
print(rec);
|
||||
if (rec.error != null) print(rec.error);
|
||||
if (rec.stackTrace != null) print(rec.stackTrace);
|
||||
});
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
@ -62,8 +78,11 @@ main() {
|
|||
var rq = new MockHttpRequest('GET', Uri.parse('/proxy/foo'))..close();
|
||||
var rqc = await HttpRequestContext.from(rq, app, '/proxy/foo');
|
||||
var rsc = HttpResponseContext(rq.response, app);
|
||||
await app.executeHandler(layer, rqc, rsc);
|
||||
var response = await rq.response.transform(gzip.decoder).transform(utf8.decoder).join();
|
||||
await app.executeHandler(layer.handleRequest, rqc, rsc);
|
||||
var response = await rq.response
|
||||
//.transform(gzip.decoder)
|
||||
.transform(utf8.decoder)
|
||||
.join();
|
||||
expect(response, 'pub serve');
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue