This commit is contained in:
thosakwe 2017-04-22 14:46:00 -04:00
parent be2060e2fd
commit 84f2fd07f5
10 changed files with 138 additions and 11 deletions

2
.analysis-options Normal file
View file

@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View file

@ -12,7 +12,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="application" />
<orderEntry type="library" name="Dart Packages" level="project" />
<orderEntry type="library" name="Dart SDK" level="project" />
</component>
</module>

View file

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="$PROJECT_DIR$" />
<option name="scope" value="FOLDER" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Pub Serve Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/pub_serve_test.dart" />
<method />
</configuration>
</component>

View file

@ -1,6 +1,6 @@
# angel_proxy
[![version 1.0.2](https://img.shields.io/badge/version-1.0.2-brightgreen.svg)](https://pub.dartlang.org/packages/angel_proxy)
[![version 1.0.3](https://img.shields.io/badge/version-1.0.3-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).

View file

@ -1,4 +1,3 @@
import 'dart:convert';
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
@ -43,7 +42,7 @@ class ProxyLayer {
Angel app;
HttpClient _client;
String _prefix;
final bool debug;
final bool debug, streamToIO;
final String host, mapTo, publicPath;
final int port;
final String protocol;
@ -53,6 +52,7 @@ class ProxyLayer {
this.mapTo: '/',
this.publicPath: '/',
this.protocol: 'http',
this.streamToIO: false,
SecurityContext securityContext}) {
_client = new HttpClient(context: securityContext);
_prefix = publicPath.replaceAll(_straySlashes, '');
@ -118,11 +118,29 @@ class ProxyLayer {
..statusCode = rs.statusCode
..contentType = rs.headers.contentType;
_printDebug('Proxy response headers:\n${rs.headers}');
if (streamToIO == true) {
res
..willCloseItself = true
..end();
copyHeaders(rs.headers, res.io.headers);
if (rs.headers[HttpHeaders.CONTENT_ENCODING] != null)
res.io.headers.set(HttpHeaders.CONTENT_ENCODING,
rs.headers[HttpHeaders.CONTENT_ENCODING]);
await rs.pipe(res.io);
} else {
rs.headers.forEach((k, v) {
if (k != HttpHeaders.CONTENT_ENCODING || !v.contains('gzip'))
res.headers[k] = v.join(',');
});
await rs.forEach(res.buffer.add);
return false;
}
return res.buffer.isEmpty;
}
}

View file

@ -4,6 +4,7 @@ import 'proxy_layer.dart';
class PubServeLayer extends ProxyLayer {
PubServeLayer(
{bool debug: false,
bool streamToIO: true,
String host: 'localhost',
String mapTo: '/',
int port: 8080,
@ -13,7 +14,8 @@ class PubServeLayer extends ProxyLayer {
debug: debug,
mapTo: mapTo,
protocol: protocol,
publicPath: publicPath);
publicPath: publicPath,
streamToIO: streamToIO != false);
@override
void serve(Router router) {

View file

@ -1,6 +1,6 @@
name: angel_proxy
description: Angel middleware to forward requests to another server (i.e. pub serve).
version: 1.0.2
version: 1.0.3
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/proxy
environment:
@ -8,5 +8,7 @@ environment:
dependencies:
angel_framework: ^1.0.0-dev
dev_dependencies:
angel_compress: ^1.0.0
angel_test: ^1.0.0
http: ^0.11.3
test: ^0.12.15

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_proxy/angel_proxy.dart';
import 'package:angel_test/angel_test.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
import 'common.dart';
@ -24,6 +25,8 @@ main() {
testServer.address.address, testServer.port,
mapTo: '/foo'));
app.after.add((req, res) async => res.write('intercept empty'));
server = await app.startServer();
url = 'http://${server.address.address}:${server.port}';
});
@ -41,6 +44,17 @@ main() {
expect(response.body, equals('"world"'));
});
test('empty', () async {
var response = await client.get('$url/proxy/empty');
print('Response: ${response.body}');
// Shouldn't say it is gzipped...
expect(response, isNot(hasHeader('content-encoding')));
// Should have gzipped body
expect(response.body, 'intercept empty');
});
test('mapTo', () async {
final response = await client.get('$url/bar');
print('Response: ${response.body}');

76
test/pub_serve_test.dart Normal file
View file

@ -0,0 +1,76 @@
import 'dart:convert';
import 'dart:io';
import 'package:angel_compress/angel_compress.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_proxy/angel_proxy.dart';
import 'package:angel_test/angel_test.dart';
import 'package:test/test.dart';
main() {
Angel app, testApp;
TestClient client;
setUp(() async {
testApp = new Angel();
testApp.get('/foo', (req, res) => res.write('pub serve'));
testApp.get('/empty', (req, res) => res.end());
testApp.responseFinalizers.add(gzip());
var server = await testApp.startServer();
app = new Angel();
app.get('/bar', (req, res) => res.write('normal'));
var layer = new PubServeLayer(
publicPath: '/proxy', host: server.address.address, port: server.port);
print('streamToIO: ${layer.streamToIO}');
await app.configure(layer);
app.responseFinalizers.add((req, ResponseContext res) async {
print('Normal. Buf: ' +
new String.fromCharCodes(res.buffer.toBytes()) +
', headers: ${res.headers}');
});
app.responseFinalizers.add(gzip());
client = await connectTo(app);
});
tearDown(() async {
await client.close();
await app.close();
await testApp.close();
app = null;
testApp = null;
});
test('proxied', () async {
var response = await client.get('/proxy/foo');
// Should say it is gzipped...
expect(response, hasHeader('content-encoding', 'gzip'));
// Should have gzipped body
expect(response.body, 'pub serve');
});
test('empty', () async {
var response = await client.get('/proxy/empty');
// Should say it is gzipped...
expect(response, hasHeader('content-encoding', 'gzip'));
// Should have gzipped body
expect(response.bodyBytes, isEmpty);
});
test('normal', () async {
var response = await client.get('/bar');
// Should say it is gzipped...
expect(response, hasHeader('content-encoding', 'gzip'));
// Should have normal body
//
// We have to decode it, because `mock_request` does not auto-decode.
expect(UTF8.decode(GZIP.decode(response.bodyBytes)), 'normal');
});
}