Make redirects + download async
This commit is contained in:
parent
1c07aa5243
commit
2004877696
5 changed files with 26 additions and 16 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
# 2.0.0-rc.6
|
||||||
|
* Make `redirect` and `download` methods asynchronous.
|
||||||
|
|
||||||
# 2.0.0-rc.5
|
# 2.0.0-rc.5
|
||||||
* Make `serializer` `FutureOr<String> Function(Object)`.
|
* Make `serializer` `FutureOr<String> Function(Object)`.
|
||||||
* Make `ResponseContext.serialize` return `Future<bool>`.
|
* Make `ResponseContext.serialize` return `Future<bool>`.
|
||||||
|
|
|
@ -139,7 +139,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
new StateError('Cannot modify a closed response.');
|
new StateError('Cannot modify a closed response.');
|
||||||
|
|
||||||
/// Sends a download as a response.
|
/// Sends a download as a response.
|
||||||
void download(File file, {String filename}) {
|
Future<void> download(File file, {String filename}) async {
|
||||||
if (!isOpen) throw closed();
|
if (!isOpen) throw closed();
|
||||||
|
|
||||||
headers["Content-Disposition"] =
|
headers["Content-Disposition"] =
|
||||||
|
@ -148,15 +148,15 @@ abstract class ResponseContext<RawResponse>
|
||||||
headers['content-length'] = file.lengthSync().toString();
|
headers['content-length'] = file.lengthSync().toString();
|
||||||
|
|
||||||
if (!isBuffered) {
|
if (!isBuffered) {
|
||||||
file.openRead().pipe(this);
|
await file.openRead().pipe(this);
|
||||||
} else {
|
} else {
|
||||||
buffer.add(file.readAsBytesSync());
|
buffer.add(file.readAsBytesSync());
|
||||||
close();
|
await close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prevents more data from being written to the response, and locks it entire from further editing.
|
/// Prevents more data from being written to the response, and locks it entire from further editing.
|
||||||
Future close() {
|
Future<void> close() {
|
||||||
if (buffer is LockableBytesBuilder) {
|
if (buffer is LockableBytesBuilder) {
|
||||||
(buffer as LockableBytesBuilder).lock();
|
(buffer as LockableBytesBuilder).lock();
|
||||||
}
|
}
|
||||||
|
@ -173,16 +173,17 @@ abstract class ResponseContext<RawResponse>
|
||||||
/// Returns a JSONP response.
|
/// Returns a JSONP response.
|
||||||
///
|
///
|
||||||
/// You can override the [contentType] sent; by default it is `application/javascript`.
|
/// You can override the [contentType] sent; by default it is `application/javascript`.
|
||||||
void jsonp(value, {String callbackName = "callback", MediaType contentType}) {
|
Future<void> jsonp(value,
|
||||||
|
{String callbackName = "callback", MediaType contentType}) {
|
||||||
if (!isOpen) throw closed();
|
if (!isOpen) throw closed();
|
||||||
this.contentType =
|
this.contentType =
|
||||||
contentType ?? new MediaType('application', 'javascript');
|
contentType ?? new MediaType('application', 'javascript');
|
||||||
write("$callbackName(${serializer(value)})");
|
write("$callbackName(${serializer(value)})");
|
||||||
close();
|
return close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders a view to the response stream, and closes the response.
|
/// Renders a view to the response stream, and closes the response.
|
||||||
Future render(String view, [Map<String, dynamic> data]) {
|
Future<void> render(String view, [Map<String, dynamic> data]) {
|
||||||
if (!isOpen) throw closed();
|
if (!isOpen) throw closed();
|
||||||
contentType = new MediaType('text', 'html', {'charset': 'utf-8'});
|
contentType = new MediaType('text', 'html', {'charset': 'utf-8'});
|
||||||
return Future<String>.sync(() => app.viewGenerator(
|
return Future<String>.sync(() => app.viewGenerator(
|
||||||
|
@ -190,7 +191,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
new Map<String, dynamic>.from(renderParams)
|
new Map<String, dynamic>.from(renderParams)
|
||||||
..addAll(data ?? <String, dynamic>{}))).then((content) {
|
..addAll(data ?? <String, dynamic>{}))).then((content) {
|
||||||
write(content);
|
write(content);
|
||||||
close();
|
return close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +202,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
/// based on the provided params.
|
/// based on the provided params.
|
||||||
///
|
///
|
||||||
/// See [Router]#navigate for more. :)
|
/// See [Router]#navigate for more. :)
|
||||||
void redirect(url, {bool absolute = true, int code = 302}) {
|
Future<void> redirect(url, {bool absolute = true, int code = 302}) {
|
||||||
if (!isOpen) throw closed();
|
if (!isOpen) throw closed();
|
||||||
headers
|
headers
|
||||||
..['content-type'] = 'text/html'
|
..['content-type'] = 'text/html'
|
||||||
|
@ -226,11 +227,11 @@ abstract class ResponseContext<RawResponse>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
''');
|
''');
|
||||||
close();
|
return close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Redirects to the given named [Route].
|
/// Redirects to the given named [Route].
|
||||||
void redirectTo(String name, [Map params, int code]) {
|
Future<void> redirectTo(String name, [Map params, int code]) async {
|
||||||
if (!isOpen) throw closed();
|
if (!isOpen) throw closed();
|
||||||
Route _findRoute(Router r) {
|
Route _findRoute(Router r) {
|
||||||
for (Route route in r.routes) {
|
for (Route route in r.routes) {
|
||||||
|
@ -247,7 +248,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
Route matched = _findRoute(app);
|
Route matched = _findRoute(app);
|
||||||
|
|
||||||
if (matched != null) {
|
if (matched != null) {
|
||||||
redirect(
|
await redirect(
|
||||||
matched.makeUri(params.keys.fold<Map<String, dynamic>>({}, (out, k) {
|
matched.makeUri(params.keys.fold<Map<String, dynamic>>({}, (out, k) {
|
||||||
return out..[k.toString()] = params[k];
|
return out..[k.toString()] = params[k];
|
||||||
})),
|
})),
|
||||||
|
@ -259,7 +260,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Redirects to the given [Controller] action.
|
/// Redirects to the given [Controller] action.
|
||||||
void redirectToAction(String action, [Map params, int code]) {
|
Future<void> redirectToAction(String action, [Map params, int code]) {
|
||||||
if (!isOpen) throw closed();
|
if (!isOpen) throw closed();
|
||||||
// UserController@show
|
// UserController@show
|
||||||
List<String> split = action.split("@");
|
List<String> split = action.split("@");
|
||||||
|
@ -291,7 +292,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
}))
|
}))
|
||||||
.replaceAll(_straySlashes, '');
|
.replaceAll(_straySlashes, '');
|
||||||
|
|
||||||
redirect('$head/$tail'.replaceAll(_straySlashes, ''), code: code);
|
return redirect('$head/$tail'.replaceAll(_straySlashes, ''), code: code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes data to the response.
|
/// Serializes data to the response.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_framework
|
name: angel_framework
|
||||||
version: 2.0.0-rc.5
|
version: 2.0.0-rc.6
|
||||||
description: A high-powered HTTP server with dependency injection, routing and much more.
|
description: A high-powered HTTP server with dependency injection, routing and much more.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/angel_framework
|
homepage: https://github.com/angel-dart/angel_framework
|
||||||
|
|
|
@ -99,6 +99,12 @@ main() {
|
||||||
expect(result[0]["angel"], equals("framework"));
|
expect(result[0]["angel"], equals("framework"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('asStream() fires', () async {
|
||||||
|
var stream = todoService.afterCreated.asStream();
|
||||||
|
await todoService.create({'angel': 'framework'});
|
||||||
|
expect(await stream.first.then((e) => e.result['angel']), 'framework');
|
||||||
|
});
|
||||||
|
|
||||||
test('metadata', () async {
|
test('metadata', () async {
|
||||||
final service = new HookedService(new IncrementService())..addHooks(app);
|
final service = new HookedService(new IncrementService())..addHooks(app);
|
||||||
expect(service.inner, isNot(const IsInstanceOf<MapService>()));
|
expect(service.inner, isNot(const IsInstanceOf<MapService>()));
|
||||||
|
|
|
@ -85,7 +85,7 @@ main() {
|
||||||
(RequestContext req, res) async => "Hello ${req.params['name']}")
|
(RequestContext req, res) async => "Hello ${req.params['name']}")
|
||||||
.name = 'Named routes';
|
.name = 'Named routes';
|
||||||
app.get('/named', (req, ResponseContext res) async {
|
app.get('/named', (req, ResponseContext res) async {
|
||||||
res.redirectTo('Named routes', {'name': 'tests'});
|
await res.redirectTo('Named routes', {'name': 'tests'});
|
||||||
});
|
});
|
||||||
app.get('/log', (RequestContext req, res) async {
|
app.get('/log', (RequestContext req, res) async {
|
||||||
print("Query: ${req.queryParameters}");
|
print("Query: ${req.queryParameters}");
|
||||||
|
|
Loading…
Reference in a new issue