Deprecated ResponseContext.io
, added HTTP equivalent
This commit is contained in:
parent
cf02582d1b
commit
9b7bf84acf
5 changed files with 272 additions and 197 deletions
|
@ -2,8 +2,11 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<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="NEW" beforePath="" afterPath="$PROJECT_DIR$/lib/src/http/http_response_context.dart" />
|
||||||
<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$/lib/src/http/angel_http.dart" afterPath="$PROJECT_DIR$/lib/src/http/angel_http.dart" />
|
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/angel_http.dart" afterPath="$PROJECT_DIR$/lib/src/http/angel_http.dart" />
|
||||||
|
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/response_context.dart" afterPath="$PROJECT_DIR$/lib/src/http/response_context.dart" />
|
||||||
|
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/server.dart" afterPath="$PROJECT_DIR$/lib/src/http/server.dart" />
|
||||||
</list>
|
</list>
|
||||||
<ignored path="$PROJECT_DIR$/.tmp/" />
|
<ignored path="$PROJECT_DIR$/.tmp/" />
|
||||||
<ignored path="$PROJECT_DIR$/temp/" />
|
<ignored path="$PROJECT_DIR$/temp/" />
|
||||||
|
@ -25,16 +28,26 @@
|
||||||
<favorites_list name="framework" />
|
<favorites_list name="framework" />
|
||||||
</component>
|
</component>
|
||||||
<component name="FileEditorManager">
|
<component name="FileEditorManager">
|
||||||
<splitter split-orientation="horizontal" split-proportion="0.53945374">
|
<splitter split-orientation="horizontal" split-proportion="0.5">
|
||||||
<split-first>
|
<split-first>
|
||||||
<leaf>
|
<leaf>
|
||||||
<file leaf-file-name="angel_http.dart" pinned="false" current-in-tab="true">
|
<file leaf-file-name="response_context.dart" pinned="false" current-in-tab="true">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_http.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="212">
|
<state relative-caret-position="402">
|
||||||
<caret line="278" column="31" lean-forward="false" selection-start-line="278" selection-start-column="31" selection-end-line="278" selection-end-column="31" />
|
<caret line="151" column="5" lean-forward="true" selection-start-line="151" selection-start-column="5" selection-end-line="151" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="metric_server.dart" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/stats/metric_server.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="135">
|
||||||
|
<caret line="12" column="43" lean-forward="true" selection-start-line="12" selection-start-column="43" selection-end-line="12" selection-end-column="43" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<marker date="1512571506000" expanded="true" signature="675:868" ph="..." />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
|
@ -44,11 +57,11 @@
|
||||||
</split-first>
|
</split-first>
|
||||||
<split-second>
|
<split-second>
|
||||||
<leaf>
|
<leaf>
|
||||||
<file leaf-file-name="http_request_context.dart" pinned="false" current-in-tab="true">
|
<file leaf-file-name="http_response_context.dart" pinned="false" current-in-tab="true">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/http_request_context.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/http/http_response_context.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="90">
|
<state relative-caret-position="437">
|
||||||
<caret line="6" column="69" lean-forward="false" selection-start-line="6" selection-start-column="69" selection-end-line="6" selection-end-column="69" />
|
<caret line="108" column="0" lean-forward="true" selection-start-line="108" selection-start-column="0" selection-end-line="108" selection-end-column="0" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -70,12 +83,6 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="FindInProjectRecents">
|
<component name="FindInProjectRecents">
|
||||||
<findStrings>
|
<findStrings>
|
||||||
<find>handleRequest</find>
|
|
||||||
<find>flatten</find>
|
|
||||||
<find>pipeline</find>
|
|
||||||
<find>pat</find>
|
|
||||||
<find>createR</find>
|
|
||||||
<find>print</find>
|
|
||||||
<find>dispos</find>
|
<find>dispos</find>
|
||||||
<find>xhr</find>
|
<find>xhr</find>
|
||||||
<find>accepts</find>
|
<find>accepts</find>
|
||||||
|
@ -100,6 +107,12 @@
|
||||||
<find>handleRe</find>
|
<find>handleRe</find>
|
||||||
<find>instead.</find>
|
<find>instead.</find>
|
||||||
<find>io\b</find>
|
<find>io\b</find>
|
||||||
|
<find>_isOpen</find>
|
||||||
|
<find>_isClosed</find>
|
||||||
|
<find>end</find>
|
||||||
|
<find>isOpen</find>
|
||||||
|
<find>_useStream</find>
|
||||||
|
<find>isClosed</find>
|
||||||
</findStrings>
|
</findStrings>
|
||||||
<replaceStrings>
|
<replaceStrings>
|
||||||
<replace>_isClosed</replace>
|
<replace>_isClosed</replace>
|
||||||
|
@ -123,6 +136,10 @@
|
||||||
<replace>autoSnakeCaseNames == false ? $0 : '$1ated_at'</replace>
|
<replace>autoSnakeCaseNames == false ? $0 : '$1ated_at'</replace>
|
||||||
<replace>'content-type'</replace>
|
<replace>'content-type'</replace>
|
||||||
<replace>appa</replace>
|
<replace>appa</replace>
|
||||||
|
<replace>isClosed</replace>
|
||||||
|
<replace>useStream</replace>
|
||||||
|
<replace>streaming</replace>
|
||||||
|
<replace>!isOpen</replace>
|
||||||
</replaceStrings>
|
</replaceStrings>
|
||||||
<dirStrings>
|
<dirStrings>
|
||||||
<dir>C:\Users\thosa\Source\Angel\framework\lib</dir>
|
<dir>C:\Users\thosa\Source\Angel\framework\lib</dir>
|
||||||
|
@ -149,7 +166,6 @@
|
||||||
<component name="IdeDocumentHistory">
|
<component name="IdeDocumentHistory">
|
||||||
<option name="CHANGED_PATHS">
|
<option name="CHANGED_PATHS">
|
||||||
<list>
|
<list>
|
||||||
<option value="$PROJECT_DIR$/performance/hello/raw.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/performance/hello/angel.md" />
|
<option value="$PROJECT_DIR$/performance/hello/angel.md" />
|
||||||
<option value="$PROJECT_DIR$/performance/hello/raw.md" />
|
<option value="$PROJECT_DIR$/performance/hello/raw.md" />
|
||||||
<option value="$PROJECT_DIR$/tool/travis.sh" />
|
<option value="$PROJECT_DIR$/tool/travis.sh" />
|
||||||
|
@ -183,7 +199,6 @@
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/service.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http/service.dart" />
|
||||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/map_service.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http/map_service.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/response_context.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/http.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http/http.dart" />
|
||||||
<option value="$PROJECT_DIR$/test/extension_test.dart" />
|
<option value="$PROJECT_DIR$/test/extension_test.dart" />
|
||||||
|
@ -193,13 +208,15 @@
|
||||||
<option value="$PROJECT_DIR$/test/routing_test.dart" />
|
<option value="$PROJECT_DIR$/test/routing_test.dart" />
|
||||||
<option value="$PROJECT_DIR$/test/parameter_meta_test.dart" />
|
<option value="$PROJECT_DIR$/test/parameter_meta_test.dart" />
|
||||||
<option value="$PROJECT_DIR$/test/primitives_test.dart" />
|
<option value="$PROJECT_DIR$/test/primitives_test.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/server.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/test/server_test.dart" />
|
<option value="$PROJECT_DIR$/test/server_test.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/json.dart" />
|
<option value="$PROJECT_DIR$/example/json.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/main.dart" />
|
<option value="$PROJECT_DIR$/example/main.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/request_context.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http/request_context.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/http_request_context.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http/http_request_context.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/http/angel_http.dart" />
|
<option value="$PROJECT_DIR$/lib/src/http/angel_http.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/http/server.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/http/response_context.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/http/http_response_context.dart" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
@ -613,14 +630,7 @@
|
||||||
<workItem from="1513103483207" duration="18000" />
|
<workItem from="1513103483207" duration="18000" />
|
||||||
<workItem from="1513103506825" duration="139000" />
|
<workItem from="1513103506825" duration="139000" />
|
||||||
<workItem from="1517332581856" duration="858000" />
|
<workItem from="1517332581856" duration="858000" />
|
||||||
<workItem from="1517973177718" duration="6361000" />
|
<workItem from="1517973177718" duration="7635000" />
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00014" summary="1.0.3">
|
|
||||||
<created>1497200046584</created>
|
|
||||||
<option name="number" value="00014" />
|
|
||||||
<option name="presentableId" value="LOCAL-00014" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1497200046584</updated>
|
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00015" summary="+1">
|
<task id="LOCAL-00015" summary="+1">
|
||||||
<created>1497200256280</created>
|
<created>1497200256280</created>
|
||||||
|
@ -958,7 +968,14 @@
|
||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1517979545063</updated>
|
<updated>1517979545063</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="63" />
|
<task id="LOCAL-00063" summary="Change return type of `AngelHttp.createRequestContext`">
|
||||||
|
<created>1517979599468</created>
|
||||||
|
<option name="number" value="00063" />
|
||||||
|
<option name="presentableId" value="LOCAL-00063" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1517979599468</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="64" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TestHistory">
|
<component name="TestHistory">
|
||||||
|
@ -994,7 +1011,7 @@
|
||||||
</history-entry>
|
</history-entry>
|
||||||
</component>
|
</component>
|
||||||
<component name="TimeTrackingManager">
|
<component name="TimeTrackingManager">
|
||||||
<option name="totallyTimeSpent" value="124397000" />
|
<option name="totallyTimeSpent" value="125671000" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TodoView">
|
<component name="TodoView">
|
||||||
<todo-panel id="selected-file">
|
<todo-panel id="selected-file">
|
||||||
|
@ -1053,7 +1070,6 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="VcsManagerConfiguration">
|
<component name="VcsManagerConfiguration">
|
||||||
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
|
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
|
||||||
<MESSAGE value="+4" />
|
|
||||||
<MESSAGE value="+6" />
|
<MESSAGE value="+6" />
|
||||||
<MESSAGE value="autoIdAndDateFields in MapService" />
|
<MESSAGE value="autoIdAndDateFields in MapService" />
|
||||||
<MESSAGE value="+8" />
|
<MESSAGE value="+8" />
|
||||||
|
@ -1078,22 +1094,16 @@
|
||||||
<MESSAGE value="Updated tests to use `AngelHttp` API" />
|
<MESSAGE value="Updated tests to use `AngelHttp` API" />
|
||||||
<MESSAGE value="Added example/main.dart" />
|
<MESSAGE value="Added example/main.dart" />
|
||||||
<MESSAGE value="Create HttpRequestContextImpl" />
|
<MESSAGE value="Create HttpRequestContextImpl" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Create HttpRequestContextImpl" />
|
<MESSAGE value="Change return type of `AngelHttp.createRequestContext`" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="Change return type of `AngelHttp.createRequestContext`" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
<option name="time" value="4" />
|
<option name="time" value="5" />
|
||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
<watches-manager />
|
<watches-manager />
|
||||||
</component>
|
</component>
|
||||||
<component name="editorHistoryManager">
|
<component name="editorHistoryManager">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_base.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="107">
|
|
||||||
<caret line="10" column="30" lean-forward="false" selection-start-line="10" selection-start-column="30" selection-end-line="10" selection-end-column="30" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/performance/hello/angel.md">
|
<entry file="file://$PROJECT_DIR$/performance/hello/angel.md">
|
||||||
<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">
|
||||||
|
@ -1277,14 +1287,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="1005">
|
|
||||||
<caret line="76" column="26" lean-forward="false" selection-start-line="76" selection-start-column="26" selection-end-line="76" selection-end-column="26" />
|
|
||||||
<folding />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/angel_route-2.0.3+1/lib/src/router.dart">
|
<entry file="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/angel_route-2.0.3+1/lib/src/router.dart">
|
||||||
<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">
|
||||||
|
@ -1312,16 +1314,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/stats/metric_server.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="461">
|
|
||||||
<caret line="65" column="61" lean-forward="false" selection-start-line="65" selection-start-column="61" selection-end-line="65" selection-end-column="61" />
|
|
||||||
<folding>
|
|
||||||
<marker date="1512571506000" expanded="true" signature="675:868" ph="..." />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/http.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/http/http.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="263">
|
<state relative-caret-position="263">
|
||||||
|
@ -1443,16 +1435,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/server.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="6330">
|
|
||||||
<caret line="422" column="22" lean-forward="true" selection-start-line="422" selection-start-column="22" selection-end-line="422" selection-end-column="22" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#38#58#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.1.2/lib/meta.dart">
|
<entry file="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.1.2/lib/meta.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="224">
|
<state relative-caret-position="224">
|
||||||
|
@ -1477,16 +1459,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/http_request_context.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="90">
|
|
||||||
<caret line="6" column="69" lean-forward="false" selection-start-line="6" selection-start-column="69" selection-end-line="6" selection-end-column="69" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/request_context.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/http/request_context.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="227">
|
<state relative-caret-position="227">
|
||||||
|
@ -1497,16 +1469,64 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_http.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/http/http_request_context.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="212">
|
<state relative-caret-position="-910">
|
||||||
<caret line="278" column="31" lean-forward="false" selection-start-line="278" selection-start-column="31" selection-end-line="278" selection-end-column="31" />
|
<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>
|
<folding>
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_http.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="188">
|
||||||
|
<caret line="292" column="38" lean-forward="false" selection-start-line="292" selection-start-column="38" selection-end-line="292" selection-end-column="38" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</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="137">
|
||||||
|
<caret line="41" column="16" lean-forward="false" selection-start-line="41" selection-start-column="16" selection-end-line="41" selection-end-column="16" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#38#58#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/stats/metric_server.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="135">
|
||||||
|
<caret line="12" column="43" lean-forward="true" selection-start-line="12" selection-start-column="43" selection-end-line="12" selection-end-column="43" />
|
||||||
|
<folding>
|
||||||
|
<marker date="1512571506000" expanded="true" signature="675:868" ph="..." />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/http/http_response_context.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="437">
|
||||||
|
<caret line="108" column="0" lean-forward="true" selection-start-line="108" selection-start-column="0" selection-end-line="108" 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/response_context.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="402">
|
||||||
|
<caret line="151" column="5" lean-forward="true" selection-start-line="151" selection-start-column="5" selection-end-line="151" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
</component>
|
</component>
|
||||||
<component name="masterDetails">
|
<component name="masterDetails">
|
||||||
<states>
|
<states>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:json_god/json_god.dart' as god;
|
||||||
import 'package:pool/pool.dart';
|
import 'package:pool/pool.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'http_request_context.dart';
|
import 'http_request_context.dart';
|
||||||
|
import 'http_response_context.dart';
|
||||||
import 'request_context.dart';
|
import 'request_context.dart';
|
||||||
import 'response_context.dart';
|
import 'response_context.dart';
|
||||||
import 'server.dart';
|
import 'server.dart';
|
||||||
|
@ -289,7 +290,7 @@ class AngelHttp {
|
||||||
Future<ResponseContext> createResponseContext(HttpResponse response,
|
Future<ResponseContext> createResponseContext(HttpResponse response,
|
||||||
[RequestContext correspondingRequest]) =>
|
[RequestContext correspondingRequest]) =>
|
||||||
new Future<ResponseContext>.value(
|
new Future<ResponseContext>.value(
|
||||||
new ResponseContext(response, app, correspondingRequest)
|
new HttpResponseContextImpl(response, app, correspondingRequest)
|
||||||
..serializer = (app.serializer ?? god.serialize)
|
..serializer = (app.serializer ?? god.serialize)
|
||||||
..encoders.addAll(app.encoders ?? {}));
|
..encoders.addAll(app.encoders ?? {}));
|
||||||
|
|
||||||
|
|
120
lib/src/http/http_response_context.dart
Normal file
120
lib/src/http/http_response_context.dart
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'http_request_context.dart';
|
||||||
|
import 'request_context.dart';
|
||||||
|
import 'response_context.dart';
|
||||||
|
import 'server.dart';
|
||||||
|
|
||||||
|
class HttpResponseContextImpl extends ResponseContext {
|
||||||
|
/// The underlying [HttpResponse] under this instance.
|
||||||
|
@override
|
||||||
|
final HttpResponse io;
|
||||||
|
Angel app;
|
||||||
|
|
||||||
|
final HttpRequestContextImpl _correspondingRequest;
|
||||||
|
bool _isClosed = false, _useStream = false;
|
||||||
|
|
||||||
|
HttpResponseContextImpl(this.io, this.app, [this._correspondingRequest]);
|
||||||
|
|
||||||
|
@override
|
||||||
|
RequestContext get correspondingRequest {
|
||||||
|
return _correspondingRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get streaming {
|
||||||
|
return _useStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addError(Object error, [StackTrace stackTrace]) {
|
||||||
|
io.addError(error, stackTrace);
|
||||||
|
super.addError(error, stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool useStream() {
|
||||||
|
if (!_useStream) {
|
||||||
|
// If this is the first stream added to this response,
|
||||||
|
// then add headers, status code, etc.
|
||||||
|
io
|
||||||
|
..statusCode = statusCode
|
||||||
|
..cookies.addAll(cookies);
|
||||||
|
headers.forEach(io.headers.set);
|
||||||
|
willCloseItself = _useStream = _isClosed = true;
|
||||||
|
releaseCorrespondingRequest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void end() {
|
||||||
|
_isClosed = true;
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future addStream(Stream<List<int>> stream) {
|
||||||
|
if (_isClosed && !_useStream) throw ResponseContext.closed();
|
||||||
|
var firstStream = useStream();
|
||||||
|
|
||||||
|
Stream<List<int>> output = stream;
|
||||||
|
|
||||||
|
if (encoders.isNotEmpty && correspondingRequest != null) {
|
||||||
|
var allowedEncodings =
|
||||||
|
(correspondingRequest.headers[HttpHeaders.ACCEPT_ENCODING] ?? [])
|
||||||
|
.map((str) {
|
||||||
|
// Ignore quality specifications in accept-encoding
|
||||||
|
// ex. gzip;q=0.8
|
||||||
|
if (!str.contains(';')) return str;
|
||||||
|
return str.split(';')[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var encodingName in allowedEncodings) {
|
||||||
|
Converter<List<int>, List<int>> encoder;
|
||||||
|
String key = encodingName;
|
||||||
|
|
||||||
|
if (encoders.containsKey(encodingName))
|
||||||
|
encoder = encoders[encodingName];
|
||||||
|
else if (encodingName == '*') {
|
||||||
|
encoder = encoders[key = encoders.keys.first];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoder != null) {
|
||||||
|
if (firstStream) {
|
||||||
|
io.headers.set(HttpHeaders.CONTENT_ENCODING, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
output = encoders[key].bind(output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return io.addStream(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void add(List<int> data) {
|
||||||
|
if (_isClosed && !_useStream)
|
||||||
|
throw ResponseContext.closed();
|
||||||
|
else if (_useStream)
|
||||||
|
io.add(data);
|
||||||
|
else
|
||||||
|
buffer.add(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future close() async {
|
||||||
|
if (_useStream) {
|
||||||
|
await io.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
_isClosed = true;
|
||||||
|
await super.close();
|
||||||
|
_useStream = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,14 +23,12 @@ final RegExp _straySlashes = new RegExp(r'(^/+)|(/+$)');
|
||||||
typedef String ResponseSerializer(data);
|
typedef String ResponseSerializer(data);
|
||||||
|
|
||||||
/// A convenience wrapper around an outgoing HTTP request.
|
/// A convenience wrapper around an outgoing HTTP request.
|
||||||
class ResponseContext implements StreamSink<List<int>>, StringSink {
|
abstract class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
final Map properties = {};
|
final Map properties = {};
|
||||||
final BytesBuilder _buffer = new _LockableBytesBuilder();
|
final BytesBuilder _buffer = new _LockableBytesBuilder();
|
||||||
final Map<String, String> _headers = {HttpHeaders.SERVER: 'angel'};
|
final Map<String, String> _headers = {HttpHeaders.SERVER: 'angel'};
|
||||||
final RequestContext _correspondingRequest;
|
|
||||||
|
|
||||||
Completer _done;
|
Completer _done;
|
||||||
bool _isOpen = true, _isClosed = false, _useStream = false;
|
|
||||||
int _statusCode = 200;
|
int _statusCode = 200;
|
||||||
|
|
||||||
/// The [Angel] instance that is sending a response.
|
/// The [Angel] instance that is sending a response.
|
||||||
|
@ -48,7 +46,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
final Map<String, Converter<List<int>, List<int>>> encoders = {};
|
final Map<String, Converter<List<int>, List<int>>> encoders = {};
|
||||||
|
|
||||||
/// Points to the [RequestContext] corresponding to this response.
|
/// Points to the [RequestContext] corresponding to this response.
|
||||||
RequestContext get correspondingRequest => _correspondingRequest;
|
RequestContext get correspondingRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future get done => (_done ?? new Completer()).future;
|
Future get done => (_done ?? new Completer()).future;
|
||||||
|
@ -56,7 +54,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
/// Headers that will be sent to the user.
|
/// Headers that will be sent to the user.
|
||||||
Map<String, String> get headers {
|
Map<String, String> get headers {
|
||||||
/// If the response is closed, then this getter will return an immutable `Map`.
|
/// If the response is closed, then this getter will return an immutable `Map`.
|
||||||
if (_isClosed)
|
if (!isOpen)
|
||||||
return new Map<String, String>.unmodifiable(_headers);
|
return new Map<String, String>.unmodifiable(_headers);
|
||||||
else
|
else
|
||||||
return _headers;
|
return _headers;
|
||||||
|
@ -80,20 +78,23 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
int get statusCode => _statusCode;
|
int get statusCode => _statusCode;
|
||||||
|
|
||||||
void set statusCode(int value) {
|
void set statusCode(int value) {
|
||||||
if (_isClosed)
|
if (!isOpen)
|
||||||
throw _closed();
|
throw closed();
|
||||||
else
|
else
|
||||||
_statusCode = value ?? 200;
|
_statusCode = value ?? 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can we still write to this response?
|
/// Can we still write to this response?
|
||||||
bool get isOpen => _isOpen && !_isClosed;
|
bool get isOpen => !!isOpen;
|
||||||
|
|
||||||
|
/// Returns `true` if a [Stream] is being written directly.
|
||||||
|
bool get streaming;
|
||||||
|
|
||||||
/// A set of UTF-8 encoded bytes that will be written to the response.
|
/// A set of UTF-8 encoded bytes that will be written to the response.
|
||||||
BytesBuilder get buffer => _buffer;
|
BytesBuilder get buffer => _buffer;
|
||||||
|
|
||||||
/// The underlying [HttpResponse] under this instance.
|
/// The underlying [HttpResponse] under this instance.
|
||||||
final HttpResponse io;
|
HttpResponse get io;
|
||||||
|
|
||||||
/// Gets the Content-Type header.
|
/// Gets the Content-Type header.
|
||||||
ContentType get contentType {
|
ContentType get contentType {
|
||||||
|
@ -116,25 +117,23 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
headers[HttpHeaders.CONTENT_TYPE] = contentType.toString();
|
headers[HttpHeaders.CONTENT_TYPE] = contentType.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseContext(this.io, this.app, [this._correspondingRequest]);
|
|
||||||
|
|
||||||
/// Set this to true if you will manually close the response.
|
/// Set this to true if you will manually close the response.
|
||||||
///
|
///
|
||||||
/// If `true`, all response finalizers will be skipped.
|
/// If `true`, all response finalizers will be skipped.
|
||||||
bool willCloseItself = false;
|
bool willCloseItself = false;
|
||||||
|
|
||||||
StateError _closed() => new StateError('Cannot modify a closed response.');
|
static StateError closed() => new StateError('Cannot modify a closed response.');
|
||||||
|
|
||||||
/// Sends a download as a response.
|
/// Sends a download as a response.
|
||||||
Future download(File file, {String filename}) async {
|
Future download(File file, {String filename}) async {
|
||||||
if (!_isOpen) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
|
|
||||||
headers["Content-Disposition"] =
|
headers["Content-Disposition"] =
|
||||||
'attachment; filename="${filename ?? file.path}"';
|
'attachment; filename="${filename ?? file.path}"';
|
||||||
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
||||||
headers[HttpHeaders.CONTENT_LENGTH] = file.lengthSync().toString();
|
headers[HttpHeaders.CONTENT_LENGTH] = file.lengthSync().toString();
|
||||||
|
|
||||||
if (_useStream) {
|
if (streaming) {
|
||||||
await file.openRead().pipe(this);
|
await file.openRead().pipe(this);
|
||||||
} else {
|
} else {
|
||||||
buffer.add(await file.readAsBytes());
|
buffer.add(await file.readAsBytes());
|
||||||
|
@ -143,22 +142,17 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
|
///
|
||||||
|
/// This method should be overwritten, setting [streaming] to `false`, **after** a `super` call.
|
||||||
Future close() {
|
Future close() {
|
||||||
var f = new Future.value();
|
if (streaming) {
|
||||||
|
|
||||||
if (_useStream) {
|
|
||||||
_useStream = false;
|
|
||||||
_buffer?.clear();
|
_buffer?.clear();
|
||||||
f = io.close();
|
|
||||||
} else if (_buffer is _LockableBytesBuilder) {
|
} else if (_buffer is _LockableBytesBuilder) {
|
||||||
(_buffer as _LockableBytesBuilder)._lock();
|
(_buffer as _LockableBytesBuilder)._lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
_isOpen = _useStream = false;
|
|
||||||
_isClosed = true;
|
|
||||||
|
|
||||||
if (_done?.isCompleted == false) _done.complete();
|
if (_done?.isCompleted == false) _done.complete();
|
||||||
return f;
|
return new Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disposes of all resources.
|
/// Disposes of all resources.
|
||||||
|
@ -176,8 +170,9 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
/// Prevents further request handlers from running on the response, except for response finalizers.
|
/// Prevents further request handlers from running on the response, except for response finalizers.
|
||||||
///
|
///
|
||||||
/// To disable response finalizers, see [willCloseItself].
|
/// To disable response finalizers, see [willCloseItself].
|
||||||
|
///
|
||||||
|
/// This method should also set [!isOpen] to true.
|
||||||
void end() {
|
void end() {
|
||||||
_isOpen = false;
|
|
||||||
if (_done?.isCompleted == false) _done.complete();
|
if (_done?.isCompleted == false) _done.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +181,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
|
|
||||||
/// Returns a JSONP response.
|
/// Returns a JSONP response.
|
||||||
void jsonp(value, {String callbackName: "callback", contentType}) {
|
void jsonp(value, {String callbackName: "callback", contentType}) {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
write("$callbackName(${serializer(value)})");
|
write("$callbackName(${serializer(value)})");
|
||||||
|
|
||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
|
@ -202,7 +197,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
|
|
||||||
/// 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 {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
write(await app.viewGenerator(view, data));
|
write(await app.viewGenerator(view, data));
|
||||||
headers[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString();
|
headers[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString();
|
||||||
end();
|
end();
|
||||||
|
@ -216,7 +211,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
///
|
///
|
||||||
/// See [Router]#navigate for more. :)
|
/// See [Router]#navigate for more. :)
|
||||||
void redirect(url, {bool absolute: true, int code: 302}) {
|
void redirect(url, {bool absolute: true, int code: 302}) {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
headers
|
headers
|
||||||
..[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString()
|
..[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString()
|
||||||
..[HttpHeaders.LOCATION] =
|
..[HttpHeaders.LOCATION] =
|
||||||
|
@ -244,7 +239,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
|
|
||||||
/// Redirects to the given named [Route].
|
/// Redirects to the given named [Route].
|
||||||
void redirectTo(String name, [Map params, int code]) {
|
void redirectTo(String name, [Map params, int code]) {
|
||||||
if (_isClosed) 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) {
|
||||||
if (route is SymlinkRoute) {
|
if (route is SymlinkRoute) {
|
||||||
|
@ -269,7 +264,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
|
|
||||||
/// Redirects to the given [Controller] action.
|
/// Redirects to the given [Controller] action.
|
||||||
void redirectToAction(String action, [Map params, int code]) {
|
void redirectToAction(String action, [Map params, int code]) {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
// UserController@show
|
// UserController@show
|
||||||
List<String> split = action.split("@");
|
List<String> split = action.split("@");
|
||||||
|
|
||||||
|
@ -298,7 +293,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
|
|
||||||
/// Copies a file's contents into the response buffer.
|
/// Copies a file's contents into the response buffer.
|
||||||
Future sendFile(File file) async {
|
Future sendFile(File file) async {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
|
|
||||||
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
||||||
buffer.add(await file.readAsBytes());
|
buffer.add(await file.readAsBytes());
|
||||||
|
@ -309,7 +304,7 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
///
|
///
|
||||||
/// [contentType] can be either a [String], or a [ContentType].
|
/// [contentType] can be either a [String], or a [ContentType].
|
||||||
void serialize(value, {contentType}) {
|
void serialize(value, {contentType}) {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
|
|
||||||
var text = serializer(value);
|
var text = serializer(value);
|
||||||
|
|
||||||
|
@ -329,99 +324,39 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
///
|
///
|
||||||
/// You can optionally transform the file stream with a [codec].
|
/// You can optionally transform the file stream with a [codec].
|
||||||
Future streamFile(File file) {
|
Future streamFile(File file) {
|
||||||
if (_isClosed) throw _closed();
|
if (!isOpen) throw closed();
|
||||||
|
|
||||||
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
||||||
return file.openRead().pipe(this);
|
return file.openRead().pipe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
/// Releases critical resources from the [correspondingRequest].
|
||||||
void add(List<int> data) {
|
void releaseCorrespondingRequest() {
|
||||||
if (_isClosed && !_useStream)
|
if (correspondingRequest?.injections?.containsKey(Stopwatch) == true) {
|
||||||
throw _closed();
|
(correspondingRequest.injections[Stopwatch] as Stopwatch).stop();
|
||||||
else if (_useStream)
|
}
|
||||||
io.add(data);
|
|
||||||
else
|
if (correspondingRequest?.injections?.containsKey(PoolResource) ==
|
||||||
buffer.add(data);
|
true) {
|
||||||
|
(correspondingRequest.injections[PoolResource] as PoolResource)
|
||||||
|
.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure the response to write directly to the output stream, instead of buffering.
|
/// Configure the response to write directly to the output stream, instead of buffering.
|
||||||
bool useStream() {
|
bool useStream();
|
||||||
if (!_useStream) {
|
|
||||||
// If this is the first stream added to this response,
|
|
||||||
// then add headers, status code, etc.
|
|
||||||
io
|
|
||||||
..statusCode = statusCode
|
|
||||||
..cookies.addAll(cookies);
|
|
||||||
headers.forEach(io.headers.set);
|
|
||||||
willCloseItself = _useStream = _isClosed = true;
|
|
||||||
|
|
||||||
if (_correspondingRequest?.injections?.containsKey(Stopwatch) == true) {
|
/// Adds a stream directly the underlying response.
|
||||||
(_correspondingRequest.injections[Stopwatch] as Stopwatch).stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_correspondingRequest?.injections?.containsKey(PoolResource) ==
|
|
||||||
true) {
|
|
||||||
(_correspondingRequest.injections[PoolResource] as PoolResource)
|
|
||||||
.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a stream directly the underlying dart:[io] response.
|
|
||||||
///
|
///
|
||||||
/// This will also set [willCloseItself] to `true`, thus canceling out response finalizers.
|
/// This will also set [willCloseItself] to `true`, thus canceling out response finalizers.
|
||||||
///
|
///
|
||||||
/// If this instance has access to a [correspondingRequest], then it will attempt to transform
|
/// If this instance has access to a [correspondingRequest], then it will attempt to transform
|
||||||
/// the content using at most one of the response [encoders].
|
/// the content using at most one of the response [encoders].
|
||||||
@override
|
@override
|
||||||
Future addStream(Stream<List<int>> stream) {
|
Future addStream(Stream<List<int>> stream);
|
||||||
if (_isClosed && !_useStream) throw _closed();
|
|
||||||
var firstStream = useStream();
|
|
||||||
|
|
||||||
Stream<List<int>> output = stream;
|
|
||||||
|
|
||||||
if (encoders.isNotEmpty && correspondingRequest != null) {
|
|
||||||
var allowedEncodings =
|
|
||||||
(correspondingRequest.headers[HttpHeaders.ACCEPT_ENCODING] ?? [])
|
|
||||||
.map((str) {
|
|
||||||
// Ignore quality specifications in accept-encoding
|
|
||||||
// ex. gzip;q=0.8
|
|
||||||
if (!str.contains(';')) return str;
|
|
||||||
return str.split(';')[0];
|
|
||||||
});
|
|
||||||
|
|
||||||
for (var encodingName in allowedEncodings) {
|
|
||||||
Converter<List<int>, List<int>> encoder;
|
|
||||||
String key = encodingName;
|
|
||||||
|
|
||||||
if (encoders.containsKey(encodingName))
|
|
||||||
encoder = encoders[encodingName];
|
|
||||||
else if (encodingName == '*') {
|
|
||||||
encoder = encoders[key = encoders.keys.first];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encoder != null) {
|
|
||||||
if (firstStream) {
|
|
||||||
io.headers.set(HttpHeaders.CONTENT_ENCODING, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
output = encoders[key].bind(output);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return io.addStream(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void addError(Object error, [StackTrace stackTrace]) {
|
void addError(Object error, [StackTrace stackTrace]) {
|
||||||
io.addError(error, stackTrace);
|
|
||||||
if (_done?.isCompleted == false) _done.completeError(error, stackTrace);
|
if (_done?.isCompleted == false) _done.completeError(error, stackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,13 +364,13 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
void write(value, {Encoding encoding}) {
|
void write(value, {Encoding encoding}) {
|
||||||
encoding ??= UTF8;
|
encoding ??= UTF8;
|
||||||
|
|
||||||
if (_isClosed && !_useStream)
|
if (!isOpen && !streaming)
|
||||||
throw _closed();
|
throw closed();
|
||||||
else if (_useStream) {
|
else if (streaming) {
|
||||||
if (value is List<int>)
|
if (value is List<int>)
|
||||||
io.add(value);
|
add(value);
|
||||||
else
|
else
|
||||||
io.add(encoding.encode(value.toString()));
|
add(encoding.encode(value.toString()));
|
||||||
} else {
|
} else {
|
||||||
if (value is List<int>)
|
if (value is List<int>)
|
||||||
buffer.add(value);
|
buffer.add(value);
|
||||||
|
@ -446,10 +381,10 @@ class ResponseContext implements StreamSink<List<int>>, StringSink {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void writeCharCode(int charCode) {
|
void writeCharCode(int charCode) {
|
||||||
if (_isClosed && !_useStream)
|
if (!isOpen && !streaming)
|
||||||
throw _closed();
|
throw closed();
|
||||||
else if (_useStream)
|
else if (streaming)
|
||||||
io.add([charCode]);
|
add([charCode]);
|
||||||
else
|
else
|
||||||
buffer.addByte(charCode);
|
buffer.addByte(charCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ class Angel extends AngelBase {
|
||||||
AngelHttp _http;
|
AngelHttp _http;
|
||||||
bool _isProduction;
|
bool _isProduction;
|
||||||
Angel _parent;
|
Angel _parent;
|
||||||
Future<HttpServer> Function(dynamic, int) _serverGenerator = HttpServer.bind;
|
|
||||||
|
|
||||||
/// A global Map of converters that can transform responses bodies.
|
/// A global Map of converters that can transform responses bodies.
|
||||||
final Map<String, Converter<List<int>, List<int>>> encoders = {};
|
final Map<String, Converter<List<int>, List<int>>> encoders = {};
|
||||||
|
|
Loading…
Reference in a new issue