blob: 04baf4151957addca960e5c5172e555eadfbb03e [file] [log] [blame]
library shelf_proxy;
import 'dart:io';
import 'package:shelf/shelf.dart';
///
///
/// Imagine that rootUri is specified as `http://example.com/files`
///
/// A request for `/test/sample.html` would result is a request for
/// `http://example.com/files/test/sample.html`.
Handler createProxyHandler(Uri rootUri) {
if (rootUri.scheme != 'http' && rootUri.scheme != 'https') {
throw new ArgumentError('rootUri must have a scheme of http or https.');
}
if (!rootUri.isAbsolute) {
throw new ArgumentError('rootUri must be absolute.');
}
if (rootUri.query.isNotEmpty) {
throw new ArgumentError('rootUri cannot contain a query.');
}
return (Request request) {
if (request.method != 'GET') {
return new Response(HttpStatus.METHOD_NOT_ALLOWED);
}
// TODO: really need to tear down the client when this is done...
var client = new HttpClient();
var url = _getProxyUrl(rootUri, request.url);
return client.openUrl(request.method, url).then((ioRequest) {
return ioRequest.close();
}).then((ioResponse) {
var headers = {};
// dart:io - HttpClientResponse.contentLength is -1 if not defined
if (ioResponse.contentLength >= 0) {
headers[HttpHeaders.CONTENT_LENGTH] =
ioResponse.contentLength.toString();
}
return new Response(ioResponse.statusCode, body: ioResponse,
headers: headers);
});
};
}
Uri _getProxyUrl(Uri proxyRoot, Uri requestUrl) {
assert(proxyRoot.scheme == 'http' || proxyRoot.scheme == 'https');
assert(proxyRoot.query == '');
assert(proxyRoot.isAbsolute);
assert(!requestUrl.isAbsolute);
var updatedPath = proxyRoot.pathSegments.toList()
..addAll(requestUrl.pathSegments);
return new Uri(scheme: proxyRoot.scheme,
userInfo: proxyRoot.userInfo,
host: proxyRoot.host,
port: proxyRoot.port,
pathSegments: updatedPath,
query: requestUrl.query);
}