Beta ready :)

This commit is contained in:
thosakwe 2016-12-18 20:38:23 -05:00
parent 2b7ad93883
commit 1c9c5c7eca
7 changed files with 178 additions and 81 deletions

View file

@ -3,10 +3,6 @@
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="7b89ff1e-1260-4dcf-9c3d-345de0471ea1" name="Default" comment=""> <list default="true" id="7b89ff1e-1260-4dcf-9c3d-345de0471ea1" name="Default" comment="">
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/README.md" afterPath="$PROJECT_DIR$/README.md" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/fatal_error.dart" afterPath="$PROJECT_DIR$/lib/src/http/fatal_error.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/server.dart" afterPath="$PROJECT_DIR$/lib/src/http/server.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/pubspec.yaml" afterPath="$PROJECT_DIR$/pubspec.yaml" />
</list> </list>
<ignored path="$PROJECT_DIR$/.tmp/" /> <ignored path="$PROJECT_DIR$/.tmp/" />
<ignored path="$PROJECT_DIR$/temp/" /> <ignored path="$PROJECT_DIR$/temp/" />
@ -52,7 +48,7 @@
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]"> <provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT"> <state split_layout="SPLIT">
<first_editor relative-caret-position="75"> <first_editor relative-caret-position="75">
<caret line="5" column="39" lean-forward="true" selection-start-line="5" selection-start-column="39" selection-end-line="5" selection-end-column="39" /> <caret line="5" column="39" lean-forward="false" selection-start-line="5" selection-start-column="39" selection-end-line="5" selection-end-column="39" />
<folding /> <folding />
</first_editor> </first_editor>
<second_editor /> <second_editor />
@ -73,8 +69,8 @@
<file leaf-file-name="server.dart" pinned="false" current-in-tab="false"> <file leaf-file-name="server.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/src/http/server.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/server.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="174"> <state relative-caret-position="3555">
<caret line="237" column="49" lean-forward="true" selection-start-line="237" selection-start-column="49" selection-end-line="237" selection-end-column="49" /> <caret line="237" column="49" lean-forward="false" selection-start-line="237" selection-start-column="49" selection-end-line="237" selection-end-column="49" />
<folding> <folding>
<element signature="e#38#58#0" expanded="true" /> <element signature="e#38#58#0" expanded="true" />
</folding> </folding>
@ -96,7 +92,7 @@
<entry file="file://$PROJECT_DIR$/test/hooked_test.dart"> <entry file="file://$PROJECT_DIR$/test/hooked_test.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1275"> <state relative-caret-position="1275">
<caret line="90" column="29" lean-forward="true" selection-start-line="90" selection-start-column="29" selection-end-line="90" selection-end-column="29" /> <caret line="90" column="29" lean-forward="false" selection-start-line="90" selection-start-column="29" selection-end-line="90" selection-end-column="29" />
<folding /> <folding />
</state> </state>
</provider> </provider>
@ -106,7 +102,7 @@
<entry file="file://$PROJECT_DIR$/test/common.dart"> <entry file="file://$PROJECT_DIR$/test/common.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="195"> <state relative-caret-position="195">
<caret line="13" column="1" lean-forward="true" selection-start-line="13" selection-start-column="1" selection-end-line="13" selection-end-column="1" /> <caret line="13" column="1" lean-forward="false" selection-start-line="13" selection-start-column="1" selection-end-line="13" selection-end-column="1" />
<folding /> <folding />
</state> </state>
</provider> </provider>
@ -124,16 +120,6 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="controller.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/src/http/controller.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="90">
<caret line="14" column="23" lean-forward="false" selection-start-line="14" selection-start-column="23" selection-end-line="14" selection-end-column="23" />
<folding />
</state>
</provider>
</entry>
</file>
</leaf> </leaf>
</component> </component>
<component name="FindInProjectRecents"> <component name="FindInProjectRecents">
@ -193,8 +179,8 @@
<foldersAlwaysOnTop value="true" /> <foldersAlwaysOnTop value="true" />
</navigator> </navigator>
<panes> <panes>
<pane id="Scope" />
<pane id="Scratches" /> <pane id="Scratches" />
<pane id="Scope" />
<pane id="ProjectPane"> <pane id="ProjectPane">
<subPane> <subPane>
<PATH> <PATH>
@ -372,7 +358,8 @@
<workItem from="1481236073268" duration="1150000" /> <workItem from="1481236073268" duration="1150000" />
<workItem from="1481238230885" duration="38000" /> <workItem from="1481238230885" duration="38000" />
<workItem from="1481377809918" duration="1319000" /> <workItem from="1481377809918" duration="1319000" />
<workItem from="1481389675241" duration="139000" /> <workItem from="1481389675241" duration="158000" />
<workItem from="1481390924053" duration="19000" />
</task> </task>
<task id="LOCAL-00001" summary="Re-designed exception"> <task id="LOCAL-00001" summary="Re-designed exception">
<created>1481237183504</created> <created>1481237183504</created>
@ -395,7 +382,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1481379127310</updated> <updated>1481379127310</updated>
</task> </task>
<option name="localTasksCounter" value="4" /> <task id="LOCAL-00004" summary="Done???">
<created>1481389821679</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1481389821679</updated>
</task>
<option name="localTasksCounter" value="5" />
<servers /> <servers />
</component> </component>
<component name="TestHistory"> <component name="TestHistory">
@ -431,7 +425,7 @@
</history-entry> </history-entry>
</component> </component>
<component name="TimeTrackingManager"> <component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="2646000" /> <option name="totallyTimeSpent" value="2684000" />
</component> </component>
<component name="TodoView"> <component name="TodoView">
<todo-panel id="selected-file"> <todo-panel id="selected-file">
@ -478,13 +472,101 @@
<MESSAGE value="Re-designed exception" /> <MESSAGE value="Re-designed exception" />
<MESSAGE value="Core done?" /> <MESSAGE value="Core done?" />
<MESSAGE value="Fixed todo" /> <MESSAGE value="Fixed todo" />
<option name="LAST_COMMIT_MESSAGE" value="Fixed todo" /> <MESSAGE value="Done???" />
<option name="LAST_COMMIT_MESSAGE" value="Done???" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager /> <breakpoint-manager />
<watches-manager /> <watches-manager />
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/lib/src/http/hooked_service.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="675">
<caret line="49" column="5" lean-forward="false" selection-start-line="49" selection-start-column="5" selection-end-line="49" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT">
<first_editor relative-caret-position="75">
<caret line="5" column="39" lean-forward="true" selection-start-line="5" selection-start-column="39" selection-end-line="5" selection-end-column="39" />
<folding />
</first_editor>
<second_editor />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2175">
<caret line="153" column="25" lean-forward="false" selection-start-line="153" selection-start-column="25" selection-end-line="153" selection-end-column="25" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/server.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3555">
<caret line="237" column="49" lean-forward="true" selection-start-line="237" selection-start-column="49" selection-end-line="237" selection-end-column="49" />
<folding>
<element signature="e#38#58#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/routable.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1260">
<caret line="94" column="26" lean-forward="false" selection-start-line="94" selection-start-column="26" selection-end-line="94" selection-end-column="26" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/test/hooked_test.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1275">
<caret line="90" column="29" lean-forward="true" selection-start-line="90" selection-start-column="29" selection-end-line="90" selection-end-column="29" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/test/common.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="195">
<caret line="13" column="1" lean-forward="true" selection-start-line="13" selection-start-column="1" selection-end-line="13" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/test/controller_test.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#20#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/controller.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="90">
<caret line="14" column="23" lean-forward="false" selection-start-line="14" selection-start-column="23" selection-end-line="14" selection-end-column="23" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/hooked_service.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/hooked_service.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="675"> <state relative-caret-position="675">
@ -557,7 +639,6 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -573,7 +654,6 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -589,7 +669,6 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="799"> <state relative-caret-position="799">
<caret line="47" column="39" lean-forward="false" selection-start-line="47" selection-start-column="39" selection-end-line="47" selection-end-column="39" /> <caret line="47" column="39" lean-forward="false" selection-start-line="47" selection-start-column="39" selection-end-line="47" selection-end-column="39" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -597,7 +676,6 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -621,7 +699,6 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -637,14 +714,13 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="15"> <state relative-caret-position="15">
<caret line="1" column="0" lean-forward="false" selection-start-line="1" selection-start-column="0" selection-end-line="1" selection-end-column="0" /> <caret line="1" column="0" lean-forward="false" selection-start-line="1" selection-start-column="0" selection-end-line="1" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/test/hooked_test.dart"> <entry file="file://$PROJECT_DIR$/test/hooked_test.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1275"> <state relative-caret-position="1275">
<caret line="90" column="29" lean-forward="true" selection-start-line="90" selection-start-column="29" selection-end-line="90" selection-end-column="29" /> <caret line="90" column="29" lean-forward="false" selection-start-line="90" selection-start-column="29" selection-end-line="90" selection-end-column="29" />
<folding /> <folding />
</state> </state>
</provider> </provider>
@ -677,7 +753,7 @@
<entry file="file://$PROJECT_DIR$/test/common.dart"> <entry file="file://$PROJECT_DIR$/test/common.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="195"> <state relative-caret-position="195">
<caret line="13" column="1" lean-forward="true" selection-start-line="13" selection-start-column="1" selection-end-line="13" selection-end-column="1" /> <caret line="13" column="1" lean-forward="false" selection-start-line="13" selection-start-column="1" selection-end-line="13" selection-end-column="1" />
<folding /> <folding />
</state> </state>
</provider> </provider>
@ -696,14 +772,13 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
<caret line="0" column="17" lean-forward="false" selection-start-line="0" selection-start-column="17" selection-end-line="0" selection-end-column="17" /> <caret line="0" column="17" lean-forward="false" selection-start-line="0" selection-start-column="17" selection-end-line="0" selection-end-column="17" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/server.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/server.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="174"> <state relative-caret-position="3555">
<caret line="237" column="49" lean-forward="true" selection-start-line="237" selection-start-column="49" selection-end-line="237" selection-end-column="49" /> <caret line="237" column="49" lean-forward="false" selection-start-line="237" selection-start-column="49" selection-end-line="237" selection-end-column="49" />
<folding> <folding>
<element signature="e#38#58#0" expanded="true" /> <element signature="e#38#58#0" expanded="true" />
</folding> </folding>
@ -714,13 +789,23 @@
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]"> <provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT"> <state split_layout="SPLIT">
<first_editor relative-caret-position="75"> <first_editor relative-caret-position="75">
<caret line="5" column="39" lean-forward="true" selection-start-line="5" selection-start-column="39" selection-end-line="5" selection-end-column="39" /> <caret line="5" column="39" lean-forward="false" selection-start-line="5" selection-start-column="39" selection-end-line="5" selection-end-column="39" />
<folding /> <folding />
</first_editor> </first_editor>
<second_editor /> <second_editor />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/test/services_test.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1374">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#47#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pubspec.yaml"> <entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="15"> <state relative-caret-position="15">

View file

@ -1,6 +1,6 @@
# angel_framework # angel_framework
[![pub 1.0.0-dev.32](https://img.shields.io/badge/pub-1.0.0--dev.32-red.svg)](https://pub.dartlang.org/packages/angel_framework) [![pub 1.0.0-dev.33](https://img.shields.io/badge/pub-1.0.0--dev.33-red.svg)](https://pub.dartlang.org/packages/angel_framework)
![build status](https://travis-ci.org/angel-dart/framework.svg) ![build status](https://travis-ci.org/angel-dart/framework.svg)
Core libraries for the Angel Framework. Core libraries for the Angel Framework.

View file

@ -7,6 +7,7 @@ export 'angel_http_exception.dart';
export 'base_middleware.dart'; export 'base_middleware.dart';
export 'base_plugin.dart'; export 'base_plugin.dart';
export 'controller.dart'; export 'controller.dart';
export 'fatal_error.dart';
export 'hooked_service.dart'; export 'hooked_service.dart';
export 'metadata.dart'; export 'metadata.dart';
export 'memory_service.dart'; export 'memory_service.dart';

View file

@ -19,6 +19,15 @@ class ResponseContext extends Extensible {
/// The [Angel] instance that is sending a response. /// The [Angel] instance that is sending a response.
AngelBase app; AngelBase app;
/// Any and all cookies to be sent to the user.
final List<Cookie> cookies = [];
/// Headers that will be sent to the user.
final Map<String, String> headers = {};
/// This response's status code.
int statusCode = 200;
/// Can we still write to this response? /// Can we still write to this response?
bool get isOpen => _isOpen; bool get isOpen => _isOpen;
@ -26,8 +35,9 @@ class ResponseContext extends Extensible {
final BytesBuilder buffer = new BytesBuilder(); final BytesBuilder buffer = new BytesBuilder();
/// Sets the status code to be sent with this response. /// Sets the status code to be sent with this response.
@Deprecated('Please use `statusCode=` instead.')
void status(int code) { void status(int code) {
io.statusCode = code; statusCode = code;
} }
/// The underlying [HttpResponse] under this instance. /// The underlying [HttpResponse] under this instance.
@ -41,18 +51,15 @@ class ResponseContext extends Extensible {
ResponseContext(this.io, this.app); ResponseContext(this.io, this.app);
/// Any and all cookies to be sent to the user.
List<Cookie> get cookies => io.cookies;
/// Set this to true if you will manually close the response. /// Set this to true if you will manually close the response.
bool willCloseItself = false; bool willCloseItself = false;
/// Sends a download as a response. /// Sends a download as a response.
download(File file, {String filename}) async { download(File file, {String filename}) async {
header("Content-Disposition", headers["Content-Disposition"] =
'attachment; filename="${filename ?? file.path}"'); 'attachment; filename="${filename ?? file.path}"';
header(HttpHeaders.CONTENT_TYPE, lookupMimeType(file.path)); headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
header(HttpHeaders.CONTENT_LENGTH, file.lengthSync().toString()); headers[HttpHeaders.CONTENT_LENGTH] = file.lengthSync().toString();
buffer.add(await file.readAsBytes()); buffer.add(await file.readAsBytes());
end(); end();
} }
@ -63,31 +70,32 @@ class ResponseContext extends Extensible {
} }
/// Sets a response header to the given value, or retrieves its value. /// Sets a response header to the given value, or retrieves its value.
@Deprecated('Please use `headers` instead.')
header(String key, [String value]) { header(String key, [String value]) {
if (value == null) if (value == null)
return io.headers[key]; return headers[key];
else else
io.headers.set(key, value); headers[key] = value;
} }
/// Serializes JSON to the response. /// Serializes JSON to the response.
void json(value) { void json(value) {
write(god.serialize(value)); write(god.serialize(value));
header(HttpHeaders.CONTENT_TYPE, ContentType.JSON.toString()); headers[HttpHeaders.CONTENT_TYPE] = ContentType.JSON.toString();
end(); end();
} }
/// Returns a JSONP response. /// Returns a JSONP response.
void jsonp(value, {String callbackName: "callback"}) { void jsonp(value, {String callbackName: "callback"}) {
write("$callbackName(${god.serialize(value)})"); write("$callbackName(${god.serialize(value)})");
header(HttpHeaders.CONTENT_TYPE, "application/javascript"); headers[HttpHeaders.CONTENT_TYPE] = "application/javascript";
end(); end();
} }
/// 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 data]) async { Future render(String view, [Map data]) async {
write(await app.viewGenerator(view, data)); write(await app.viewGenerator(view, data));
header(HttpHeaders.CONTENT_TYPE, ContentType.HTML.toString()); headers[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString();
end(); end();
} }
@ -99,9 +107,9 @@ class ResponseContext extends Extensible {
/// ///
/// See [Router]#navigate for more. :) /// See [Router]#navigate for more. :)
void redirect(url, {bool absolute: true, int code: 301}) { void redirect(url, {bool absolute: true, int code: 301}) {
header(HttpHeaders.LOCATION, headers[HttpHeaders.LOCATION] =
url is String ? url : app.navigate(url, absolute: absolute)); url is String ? url : app.navigate(url, absolute: absolute);
status(code ?? 301); statusCode = code ?? 301;
write(''' write('''
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -175,15 +183,13 @@ class ResponseContext extends Extensible {
} }
/// Streams a file to this response as chunked data. /// Streams a file to this response as chunked data.
///
/// Useful for video sites.
Future streamFile(File file, Future streamFile(File file,
{int chunkSize, int sleepMs: 0, bool resumable: true}) async { {int chunkSize, int sleepMs: 0, bool resumable: true}) async {
if (!isOpen) return; if (!isOpen) return;
header(HttpHeaders.CONTENT_TYPE, lookupMimeType(file.path)); headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
willCloseItself = true; end();
await file.openRead().pipe(io); buffer.add(await file.readAsBytes());
} }
/// Writes data to the response. /// Writes data to the response.

View file

@ -1,7 +1,6 @@
library angel_framework.http.routable; library angel_framework.http.routable;
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:angel_route/angel_route.dart'; import 'package:angel_route/angel_route.dart';
import '../util.dart'; import '../util.dart';
import 'angel_base.dart'; import 'angel_base.dart';
@ -20,9 +19,6 @@ typedef Future<bool> RequestMiddleware(RequestContext req, ResponseContext res);
/// A function that receives an incoming [RequestContext] and responds to it. /// A function that receives an incoming [RequestContext] and responds to it.
typedef Future RequestHandler(RequestContext req, ResponseContext res); typedef Future RequestHandler(RequestContext req, ResponseContext res);
/// A function that handles an [HttpRequest].
typedef Future RawRequestHandler(HttpRequest request);
/// A routable server that can handle dynamic requests. /// A routable server that can handle dynamic requests.
class Routable extends Router { class Routable extends Router {
final Map<Pattern, Controller> _controllers = {}; final Map<Pattern, Controller> _controllers = {};

View file

@ -56,11 +56,16 @@ class Angel extends AngelBase {
/// **NOTE**: This is a broadcast stream. /// **NOTE**: This is a broadcast stream.
Stream<Controller> get onController => _onController.stream; Stream<Controller> get onController => _onController.stream;
/// Always run before responses are sent.
///
/// These will only not run if an [AngelFatalError] occurs.
final List<RequestHandler> responseFinalizers = [];
/// Default error handler, show HTML error page /// Default error handler, show HTML error page
AngelErrorHandler _errorHandler = AngelErrorHandler _errorHandler =
(AngelHttpException e, req, ResponseContext res) { (AngelHttpException e, req, ResponseContext res) {
res.header(HttpHeaders.CONTENT_TYPE, ContentType.HTML.toString()); res.heades[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString();
res.status(e.statusCode); res.statusCode = e.statusCode;
res.write("<!DOCTYPE html><html><head><title>${e.message}</title>"); res.write("<!DOCTYPE html><html><head><title>${e.message}</title>");
res.write("</head><body><h1>${e.message}</h1><ul>"); res.write("</head><body><h1>${e.message}</h1><ul>");
for (String error in e.errors) { for (String error in e.errors) {
@ -137,17 +142,6 @@ class Angel extends AngelBase {
return res.isOpen; return res.isOpen;
} }
if (handler is RawRequestHandler) {
var result = await handler(req.io);
if (result is bool)
return result == true;
else if (result != null) {
res.json(result);
return false;
} else
return true;
}
if (handler is Future) { if (handler is Future) {
var result = await handler; var result = await handler;
if (result is bool) if (result is bool)
@ -200,6 +194,8 @@ class Angel extends AngelBase {
} }
final m = new MiddlewarePipeline(resolved); final m = new MiddlewarePipeline(resolved);
req.inject(MiddlewarePipeline, m);
final pipeline = []..addAll(before)..addAll(m.handlers)..addAll(after); final pipeline = []..addAll(before)..addAll(m.handlers)..addAll(after);
_printDebug('Handler sequence on $requestedUrl: $pipeline'); _printDebug('Handler sequence on $requestedUrl: $pipeline');
@ -224,7 +220,7 @@ class Angel extends AngelBase {
if (e is AngelHttpException) { if (e is AngelHttpException) {
// Special handling for AngelHttpExceptions :) // Special handling for AngelHttpExceptions :)
try { try {
res.status(e.statusCode); res.statusCode = e.statusCode;
String accept = request.headers.value(HttpHeaders.ACCEPT); String accept = request.headers.value(HttpHeaders.ACCEPT);
if (accept == "*/*" || if (accept == "*/*" ||
accept.contains(ContentType.JSON.mimeType) || accept.contains(ContentType.JSON.mimeType) ||
@ -233,12 +229,14 @@ class Angel extends AngelBase {
} else { } else {
await _errorHandler(e, req, res); await _errorHandler(e, req, res);
} }
_finalizeResponse(request, res); // _finalizeResponse(request, res);
} catch (e, st) { } catch (e, st) {
_fatalErrorStream.add(new AngelFatalError(request: request, error: e, stack: st)); _fatalErrorStream.add(
new AngelFatalError(request: request, error: e, stack: st));
} }
} else { } else {
_fatalErrorStream.add(new AngelFatalError(request: request, error: e, stack: st)); _fatalErrorStream
.add(new AngelFatalError(request: request, error: e, stack: st));
} }
break; break;
@ -249,7 +247,18 @@ class Angel extends AngelBase {
_afterProcessed.add(request); _afterProcessed.add(request);
if (!res.willCloseItself) { if (!res.willCloseItself) {
request.response.add(res.buffer.takeBytes()); for (var finalizer in responseFinalizers) {
await finalizer(req, res);
}
for (var key in res.headers.keys) {
request.response.headers.set(key, res.headers[key]);
}
request.response
..statusCode = res.statusCode
..cookies.addAll(res.cookies)
..add(res.buffer.takeBytes());
await request.response.close(); await request.response.close();
} }
} catch (e) { } catch (e) {

View file

@ -1,5 +1,5 @@
name: angel_framework name: angel_framework
version: 1.0.0-dev.32 version: 1.0.0-dev.33
description: Core libraries for the Angel framework. description: Core libraries for the Angel framework.
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