Merge pull request #1 from denkuy/master

Pull in from denkuy
This commit is contained in:
Tobe Osakwe 2018-11-08 16:44:31 -05:00 committed by GitHub
commit 9ff915a105
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 23 deletions

View file

@ -2,7 +2,7 @@
[![Pub](https://img.shields.io/pub/v/angel_proxy.svg)](https://pub.dartlang.org/packages/angel_proxy) [![Pub](https://img.shields.io/pub/v/angel_proxy.svg)](https://pub.dartlang.org/packages/angel_proxy)
[![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. `pub serve`). Angel middleware to forward requests to another server (i.e. `webdev serve`).
```dart ```dart
import 'package:angel_proxy/angel_proxy.dart'; import 'package:angel_proxy/angel_proxy.dart';
@ -11,23 +11,26 @@ import 'package:http/http.dart' as http;
main() async { main() async {
// ... // ...
var client = new http.Client(); var client = http.Client();
var proxy = new Proxy(app, client, 'http://localhost:3000');
// Forward requests instead of serving statically // Forward requests instead of serving statically
app.use(proxy.handleRequest); var proxy1 = Proxy(client, 'http://localhost:3000');
// or split: Proxy(client, 'localhost', port: 8080, protocol: 'http');
// handle all methods (GET, POST, ...)
app.all('*', 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
new Proxy(app, client, '<host>', publicPath: '/remote'); Proxy(client, '<host>', 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
new Proxy(app, client, '<host>', mapTo: '/path'); Proxy(client, '<host>', mapTo: '/path');
``` ```
If your app's `storeOriginalBuffer` is `true`, then request bodies will be forwarded If your app's `keepRawRequestBuffers` is `true`, then request bodies will be forwarded
as well, if they are not empty. This allows things like POST requests to function. as well, if they are not empty. This allows things like POST requests to function.

View file

@ -14,7 +14,6 @@ main() async {
// Forward any /api requests to pub. // Forward any /api requests to pub.
// By default, if the host throws a 404, the request will fall through to the next handler. // By default, if the host throws a 404, the request will fall through to the next handler.
var pubProxy = new Proxy( var pubProxy = new Proxy(
app,
client, client,
'https://pub.dartlang.org', 'https://pub.dartlang.org',
publicPath: '/pub', publicPath: '/pub',
@ -30,7 +29,6 @@ main() async {
// Anything else should fall through to dartlang.org. // Anything else should fall through to dartlang.org.
var dartlangProxy = new Proxy( var dartlangProxy = new Proxy(
app,
client, client,
'https://dartlang.org', 'https://dartlang.org',
timeout: timeout, timeout: timeout,

View file

@ -11,7 +11,6 @@ final MediaType _fallbackMediaType = MediaType('application', 'octet-stream');
class Proxy { class Proxy {
String _prefix; String _prefix;
final Angel app;
final http.Client httpClient; final http.Client httpClient;
/// If `true` (default), then the plug-in will ignore failures to connect to the proxy, and allow other handlers to run. /// If `true` (default), then the plug-in will ignore failures to connect to the proxy, and allow other handlers to run.
@ -25,7 +24,6 @@ class Proxy {
final Duration timeout; final Duration timeout;
Proxy( Proxy(
this.app,
this.httpClient, this.httpClient,
this.host, { this.host, {
this.port, this.port,
@ -69,7 +67,7 @@ class Proxy {
url = url.replaceAll(_straySlashes, ''); url = url.replaceAll(_straySlashes, '');
url = '$url/$mapping'; url = '$url/$mapping';
if (!url.startsWith('http')) url = 'http://$url'; if (!url.startsWith(protocol)) url = '$protocol://$url';
url = url.replaceAll(_straySlashes, ''); url = url.replaceAll(_straySlashes, '');
var headers = <String, String>{ var headers = <String, String>{
@ -88,7 +86,7 @@ class Proxy {
var body; var body;
if (req.method != 'GET' && app.keepRawRequestBuffers == true) { if (req.method != 'GET' && req.app.keepRawRequestBuffers == true) {
body = (await req.parse()).originalBuffer; body = (await req.parse()).originalBuffer;
} }
@ -140,19 +138,24 @@ class Proxy {
mediaType = _fallbackMediaType; mediaType = _fallbackMediaType;
} }
var proxiedHeaders = new Map<String, String>.from(rs.headers); /// if [http.Client] does not provide us with a content length
/// OR [http.Client] is about to decode the response (bytecount returned by [http.Response].stream != known length)
/// then we can not provide a value downstream => set to '-1' for 'unspecified length'
var isContentLengthUnknown = rs.contentLength == null ||
rs.headers[HttpHeaders.contentEncodingHeader]?.isNotEmpty == true ||
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}";
res res
..contentType = mediaType ..contentType = mediaType
..statusCode = rs.statusCode ..statusCode = rs.statusCode
..headers.addAll(proxiedHeaders); ..headers.addAll(proxiedHeaders);
var stream = rs.stream; await rs.stream.pipe(res);
// [upgrading to dart2] Keeping this workaround as a reference. It's not properly typed for dart2
//if (rs.headers[HttpHeaders.contentEncodingHeader] == 'gzip') stream = stream.transform(gzip.encoder);
await stream.pipe(res);
return false; return false;
} }

View file

@ -22,14 +22,12 @@ main() {
testServer = await startTestServer(); testServer = await startTestServer();
var proxy1 = new Proxy( var proxy1 = new Proxy(
app,
httpClient, httpClient,
testServer.address.address, testServer.address.address,
port: testServer.port, port: testServer.port,
publicPath: '/proxy', publicPath: '/proxy',
); );
var proxy2 = new Proxy( var proxy2 = new Proxy(
app,
httpClient, httpClient,
testServer.address.address, testServer.address.address,
port: testServer.port, port: testServer.port,

View file

@ -34,7 +34,6 @@ main() {
var httpClient = new http.Client(); var httpClient = new http.Client();
layer = new Proxy( layer = new Proxy(
app,
httpClient, httpClient,
server.address.address, server.address.address,
port: server.port, port: server.port,