This commit is contained in:
thosakwe 2017-04-01 22:06:27 -04:00
parent acb8745890
commit 4509b88bbb
6 changed files with 50 additions and 24 deletions

View file

@ -1,7 +1,7 @@
# angel_proxy
[![version 1.0.0](https://img.shields.io/badge/version-1.0.0-brightgreen.svg)](https://pub.dartlang.org/packages/angel_proxy)
[![build status](https://travis-ci.org/angel-dart/proxy.svg?branch=master)](https://travis-ci.org/angel-dart/proxy)
[![version 1.0.1](https://img.shields.io/badge/version-1.0.1-brightgreen.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)
Angel middleware to forward requests to another server (i.e. pub serve).
Based on [this repo](https://github.com/agilord/http_request_proxy).
@ -21,4 +21,7 @@ main() async {
// in production.
await app.configure(new PubServeLayer());
}
```
```
If your app's `storeOriginalBuffer` is `true`, then request bodies will be forwarded
as well, if they are not empty. This allows things like POST requests to function.

View file

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
@ -39,6 +40,7 @@ void copyHeaders(HttpHeaders from, HttpHeaders to) {
}
class ProxyLayer {
Angel app;
HttpClient _client;
String _prefix;
final bool debug;
@ -56,7 +58,7 @@ class ProxyLayer {
_prefix = publicPath.replaceAll(_straySlashes, '');
}
call(Angel app) async => serve(app);
call(Angel app) async => serve(this.app = app);
_printDebug(msg) {
if (debug == true) print(msg);
@ -69,11 +71,10 @@ class ProxyLayer {
handler(RequestContext req, ResponseContext res) async {
var path = req.path.replaceAll(_straySlashes, '');
return serveFile(path, req, res);
}
router.get('$publicPath/*', handler);
router.all('$publicPath/*', handler);
}
serveFile(String path, RequestContext req, ResponseContext res) async {
@ -83,10 +84,6 @@ class ProxyLayer {
_path = path.replaceAll(new RegExp('^' + _pathify(_prefix)), '');
}
res
..willCloseItself = true
..end();
// Create mapping
_printDebug('Serving path $_path via proxy');
final mapping = '$mapTo/$_path'.replaceAll(_straySlashes, '');
@ -107,16 +104,26 @@ class ProxyLayer {
..set('X-Forwarded-Proto', protocol);
_printDebug('Added X-Forwarded headers');
await rq.addStream(req.io);
if (app.storeOriginalBuffer == true) {
await req.parse();
if (req.originalBuffer?.isNotEmpty == true) rq.add(req.originalBuffer);
}
await rq.flush();
final HttpClientResponse rs = await rq.close();
final HttpResponse r = res.io;
_printDebug(
'Proxy responded to $mapping with status code ${rs.statusCode}');
r.statusCode = rs.statusCode;
r.headers.contentType = rs.headers.contentType;
copyHeaders(rs.headers, r.headers);
await r.addStream(rs);
await r.flush();
await r.close();
res
..statusCode = rs.statusCode
..contentType = rs.headers.contentType;
rs.headers.forEach((k, v) {
res.headers[k] = v.join(',');
});
await rs.forEach(res.buffer.add);
res.end();
return false;
}
}

View file

@ -18,7 +18,7 @@ class PubServeLayer extends ProxyLayer {
@override
void serve(Router router) {
if (Platform.environment['ANGEL_ENV'] == 'production') {
if (app?.isProduction == true) {
// Auto-deactivate in production ;)
return;
}

View file

@ -1,10 +1,10 @@
name: angel_proxy
description: Angel middleware to forward requests to another server (i.e. pub serve).
version: 1.0.0
version: 1.0.1
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/proxy
environment:
sdk: ">=1.18.0"
sdk: ">=1.19.0"
dependencies:
angel_framework: ^1.0.0-dev
dev_dependencies:

View file

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_proxy/angel_proxy.dart';
@ -12,7 +13,7 @@ main() {
String url;
setUp(() async {
app = new Angel();
app = new Angel()..storeOriginalBuffer = true;
testServer = await testApp().startServer();
@ -45,4 +46,13 @@ main() {
print('Response: ${response.body}');
expect(response.body, equals('"baz"'));
});
test('original buffer', () async {
var response = await client.post('$url/proxy/body',
body: {'foo': 'bar'},
headers: {'content-type': 'application/x-www-form-urlencoded'});
print('Response: ${response.body}');
expect(response.body, isNotEmpty);
expect(JSON.decode(response.body), {'foo': 'bar'});
});
}

View file

@ -5,6 +5,12 @@ Angel testApp() {
app.get('/hello', 'world');
app.get('/foo/bar', 'baz');
app.post('/body', (req, res) => req.lazyBody());
return app;
}
app.fatalErrorStream.listen((e) {
print('FATAL IN TEST APP: ${e.error}');
print(e.stack);
});
return app..dumpTree();
}