This commit is contained in:
Tobe O 2018-11-08 19:27:50 -05:00
parent dbb483b953
commit 327b3996c1
6 changed files with 27 additions and 33 deletions

View file

@ -1,6 +1,9 @@
# 2.1.0 # 2.1.0
- Use `Uri` instead of archaic `host`, `port`, and `mapTo`. Also cleaner + safer + easier. - Use `Uri` instead of archaic `host`, `port`, and `mapTo`. Also cleaner + safer + easier.
* Enable WebSocket proxying.
# 2.0.0 # 2.0.0
- Updates for Angel 2. Big thanks to @denkuy! - Updates for Angel 2. Big thanks to @denkuy!

View file

@ -3,6 +3,7 @@
[![build status](https://travis-ci.org/angel-dart/proxy.svg)](https://travis-ci.org/angel-dart/proxy) [![build status](https://travis-ci.org/angel-dart/proxy.svg)](https://travis-ci.org/angel-dart/proxy)
Angel middleware to forward requests to another server (i.e. `webdev serve`). Angel middleware to forward requests to another server (i.e. `webdev serve`).
Also supports WebSockets.
```dart ```dart
import 'package:angel_proxy/angel_proxy.dart'; import 'package:angel_proxy/angel_proxy.dart';
@ -14,22 +15,21 @@ main() async {
var client = http.Client(); var client = http.Client();
// Forward requests instead of serving statically // Forward requests instead of serving statically
var proxy1 = Proxy(client, 'http://localhost:3000'); var proxy1 = Proxy(client, Uri.parse('http://localhost:3000'));
// or split: Proxy(client, 'localhost', port: 8080, protocol: 'http');
// handle all methods (GET, POST, ...) // handle all methods (GET, POST, ...)
app.all('*', proxy.handleRequest); app.fallback(proxy.handleRequest);
} }
``` ```
You can also restrict the proxy to serving only from a specific root: You can also restrict the proxy to serving only from a specific root:
```dart ```dart
Proxy(client, '<host>', publicPath: '/remote'); Proxy(client, baseUrl, publicPath: '/remote');
``` ```
Also, you can map requests to a root path on the remote server Also, you can map requests to a root path on the remote server:
```dart ```dart
Proxy(client, '<host>', mapTo: '/path'); Proxy(client, baseUrl.replace(path: '/path'));
``` ```
If your app's `keepRawRequestBuffers` is `true`, then request bodies will be forwarded If your app's `keepRawRequestBuffers` is `true`, then request bodies will be forwarded

View file

@ -29,8 +29,6 @@ main() async {
Uri.parse('http://echo.websocket.org'), Uri.parse('http://echo.websocket.org'),
publicPath: '/echo', publicPath: '/echo',
timeout: timeout, timeout: timeout,
recoverFromDead: false,
recoverFrom404: false,
); );
app.get('/echo', echoProxy.handleRequest); app.get('/echo', echoProxy.handleRequest);

View file

@ -32,10 +32,13 @@ class Proxy {
this.recoverFrom404: true, this.recoverFrom404: true,
this.timeout, this.timeout,
}) { }) {
if (!baseUrl.hasScheme || !baseUrl.hasAuthority)
throw new ArgumentError(
'Invalid `baseUrl`. URI must have both a scheme and authority.');
if (this.recoverFromDead == null) if (this.recoverFromDead == null)
throw ArgumentError.notNull("recoverFromDead"); throw new ArgumentError.notNull("recoverFromDead");
if (this.recoverFrom404 == null) if (this.recoverFrom404 == null)
throw ArgumentError.notNull("recoverFrom404"); throw new ArgumentError.notNull("recoverFrom404");
_prefix = publicPath?.replaceAll(_straySlashes, '') ?? ''; _prefix = publicPath?.replaceAll(_straySlashes, '') ?? '';
} }
@ -64,35 +67,18 @@ class Proxy {
var uri = baseUrl.replace(path: p.join(baseUrl.path, path)); var uri = baseUrl.replace(path: p.join(baseUrl.path, path));
print('a $uri');
try { try {
print(req is HttpRequestContext &&
WebSocketTransformer.isUpgradeRequest(req.rawRequest));
if (req is HttpRequestContext && if (req is HttpRequestContext &&
WebSocketTransformer.isUpgradeRequest(req.rawRequest)) { WebSocketTransformer.isUpgradeRequest(req.rawRequest)) {
print('ws!!!');
res.detach(); res.detach();
print('detached');
uri = uri.replace(scheme: uri.scheme == 'https' ? 'wss' : 'ws'); uri = uri.replace(scheme: uri.scheme == 'https' ? 'wss' : 'ws');
print(uri);
try { try {
var local = await WebSocketTransformer.upgrade(req.rawRequest); var local = await WebSocketTransformer.upgrade(req.rawRequest);
print('local!');
var remote = await WebSocket.connect(uri.toString()); var remote = await WebSocket.connect(uri.toString());
print('remote!');
dynamic Function(dynamic) log(String type) { local.pipe(remote);
return (x) { remote.pipe(local);
print('$type: $x');
return x;
};
}
local.map(log('local->remote')).pipe(remote);
remote.map(log('local->remote')).pipe(local);
return false; return false;
} catch (e, st) { } catch (e, st) {
throw new AngelHttpException(e, throw new AngelHttpException(e,
@ -126,7 +112,7 @@ class Proxy {
var rq = new http.Request(req.method, uri); var rq = new http.Request(req.method, uri);
rq.headers.addAll(headers); rq.headers.addAll(headers);
rq.headers['host'] = rq.url.host; rq.headers['host'] = rq.url.host;
rq.encoding = Utf8Codec(allowMalformed: true); rq.encoding = new Utf8Codec(allowMalformed: true);
if (body != null) rq.bodyBytes = body; if (body != null) rq.bodyBytes = body;
@ -157,7 +143,8 @@ class Proxy {
MediaType mediaType; MediaType mediaType;
if (rs.headers.containsKey(HttpHeaders.contentTypeHeader)) { if (rs.headers.containsKey(HttpHeaders.contentTypeHeader)) {
try { try {
mediaType = MediaType.parse(rs.headers[HttpHeaders.contentTypeHeader]); mediaType =
new MediaType.parse(rs.headers[HttpHeaders.contentTypeHeader]);
} on FormatException catch (e, st) { } on FormatException catch (e, st) {
if (recoverFromDead) return true; if (recoverFromDead) return true;

View file

@ -23,10 +23,16 @@ main() {
var proxy1 = new Proxy( var proxy1 = new Proxy(
httpClient, httpClient,
new Uri(host: testServer.address.address, port: testServer.port), new Uri(
scheme: 'http',
host: testServer.address.address,
port: testServer.port),
publicPath: '/proxy', publicPath: '/proxy',
); );
var proxy2 = new Proxy(httpClient, proxy1.baseUrl.replace(path: '/foo')); var proxy2 = new Proxy(httpClient, proxy1.baseUrl.replace(path: '/foo'));
print('Proxy 1 on: ${proxy1.baseUrl}');
print('Proxy 2 on: ${proxy2.baseUrl}');
app.all("/proxy/*", proxy1.handleRequest); app.all("/proxy/*", proxy1.handleRequest);
app.all("*", proxy2.handleRequest); app.all("*", proxy2.handleRequest);

View file

@ -41,7 +41,7 @@ main() {
layer = new Proxy( layer = new Proxy(
httpClient, httpClient,
new Uri(host: server.address.address, port: server.port), new Uri(scheme: 'http', host: server.address.address, port: server.port),
publicPath: '/proxy', publicPath: '/proxy',
); );