Add 'packages/body_parser/' from commit 'b4cc359637f6bc510097e97c92f17db072e6e09b'
git-subtree-dir: packages/body_parser git-subtree-mainline:9c36a7e981
git-subtree-split:b4cc359637
This commit is contained in:
commit
a13d02069e
23 changed files with 1271 additions and 0 deletions
64
packages/body_parser/.gitignore
vendored
Normal file
64
packages/body_parser/.gitignore
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
### Dart template
|
||||
# See https://www.dartlang.org/tools/private-files.html
|
||||
|
||||
# Files and directories created by pub
|
||||
.packages
|
||||
.pub/
|
||||
build/
|
||||
# If you're building an application, you may want to check-in your pubspec.lock
|
||||
pubspec.lock
|
||||
|
||||
# Directory created by dartdoc
|
||||
# If you don't generate documentation locally you can remove this line.
|
||||
doc/api/
|
15
packages/body_parser/.idea/body_parser.iml
Normal file
15
packages/body_parser/.idea/body_parser.iml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
421
packages/body_parser/.idea/libraries/Dart_Packages.xml
Normal file
421
packages/body_parser/.idea/libraries/Dart_Packages.xml
Normal file
|
@ -0,0 +1,421 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Dart Packages" type="DartPackagesLibraryType">
|
||||
<properties>
|
||||
<option name="packageNameToDirsMap">
|
||||
<entry key="analyzer">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.32.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="args">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/args-1.5.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="async">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-2.0.8/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="boolean_selector">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="charcode">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="collection">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="convert">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/convert-2.0.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="crypto">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-2.0.6/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="csslib">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/csslib-0.14.4+1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="dart2_constant">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/dart2_constant-1.0.2+dart2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="front_end">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/front_end-0.1.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="glob">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/glob-1.1.7/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="html">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/html-0.13.3+2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="http">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http-0.11.3+17/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="http_multi_server">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_multi_server-2.0.5/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="http_parser">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_parser-3.1.3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="http_server">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_server-0.9.8/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="io">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/io-0.3.3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="js">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/js-0.6.1+1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="json_rpc_2">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/json_rpc_2-2.0.9/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="kernel">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/kernel-0.3.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="logging">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/logging-0.11.3+2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="matcher">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.3+1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="meta">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.1.6/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="mime">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mime-0.9.6+2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="multi_server_socket">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/multi_server_socket-1.0.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="node_preamble">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/node_preamble-1.4.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="package_config">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.5/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="package_resolver">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.6.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="plugin">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin-0.2.0+3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="pool">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pool-1.3.6/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="pub_semver">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pub_semver-1.4.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="shelf">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf-0.7.3+3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="shelf_packages_handler">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-1.0.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="shelf_static">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_static-0.2.8/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="shelf_web_socket">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-0.2.2+4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="source_map_stack_trace">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-1.1.5/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="source_maps">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.7/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="source_span">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.4.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="stack_trace">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="stream_channel">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_channel-1.6.8/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="string_scanner">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="term_glyph">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.0.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="test">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test-1.3.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="typed_data">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="utf">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/utf-0.9.0+5/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="vm_service_client">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vm_service_client-0.2.6/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="watcher">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/watcher-0.9.7+10/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="web_socket_channel">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-1.0.9/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="yaml">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/yaml-2.1.15/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
</option>
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.32.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/args-1.5.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-2.0.8/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/convert-2.0.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-2.0.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/csslib-0.14.4+1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/dart2_constant-1.0.2+dart2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/front_end-0.1.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/glob-1.1.7/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/html-0.13.3+2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http-0.11.3+17/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_multi_server-2.0.5/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_parser-3.1.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_server-0.9.8/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/io-0.3.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/js-0.6.1+1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/json_rpc_2-2.0.9/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/kernel-0.3.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/logging-0.11.3+2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.3+1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.1.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mime-0.9.6+2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/multi_server_socket-1.0.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/node_preamble-1.4.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.5/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.6.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin-0.2.0+3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pool-1.3.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pub_semver-1.4.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf-0.7.3+3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-1.0.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_static-0.2.8/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-0.2.2+4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-1.1.5/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.7/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.4.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_channel-1.6.8/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test-1.3.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/utf-0.9.0+5/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vm_service_client-0.2.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/watcher-0.9.7+10/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-1.0.9/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/yaml-2.1.15/lib" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<LIBRARY_FILE />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
8
packages/body_parser/.idea/modules.xml
Normal file
8
packages/body_parser/.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/body_parser.iml" filepath="$PROJECT_DIR$/.idea/body_parser.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,7 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="main.dart" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true" nameIsGenerated="true">
|
||||
<option name="filePath" value="$PROJECT_DIR$/example/main.dart" />
|
||||
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
6
packages/body_parser/.idea/vcs.xml
Normal file
6
packages/body_parser/.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
4
packages/body_parser/.travis.yml
Normal file
4
packages/body_parser/.travis.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: dart
|
||||
dart:
|
||||
- dev
|
||||
- stable
|
5
packages/body_parser/CHANGELOG.md
Normal file
5
packages/body_parser/CHANGELOG.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# 1.1.1
|
||||
* Dart 2 updates; should fix Angel in Travis.
|
||||
|
||||
# 1.1.0
|
||||
* Add `parseBodyFromStream`
|
21
packages/body_parser/LICENSE
Normal file
21
packages/body_parser/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Tobe O
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
82
packages/body_parser/README.md
Normal file
82
packages/body_parser/README.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
# body_parser
|
||||
[![Pub](https://img.shields.io/pub/v/body_parser.svg)](https://pub.dartlang.org/packages/body_parser)
|
||||
[![build status](https://travis-ci.org/angel-dart/body_parser.svg)](https://travis-ci.org/angel-dart/body_parser)
|
||||
|
||||
Parse request bodies and query strings in Dart, as well multipart/form-data uploads. No external
|
||||
dependencies required.
|
||||
|
||||
This is the request body parser powering the
|
||||
[Angel](https://angel-dart.github.io)
|
||||
framework. If you are looking for a server-side solution with dependency injection,
|
||||
WebSockets, and more, then I highly recommend it as your first choice. Bam!
|
||||
|
||||
### Contents
|
||||
|
||||
* [Body Parser](#body-parser)
|
||||
* [About](#about)
|
||||
* [Installation](#installation)
|
||||
* [Usage](#usage)
|
||||
* [Thanks](#thank-you-for-using-body-parser)
|
||||
|
||||
# About
|
||||
|
||||
I needed something like Express.js's `body-parser` module, so I made it here. It fully supports JSON requests.
|
||||
x-www-form-urlencoded fully supported, as well as query strings. You can also include arrays in your query,
|
||||
in the same way you would for a PHP application. Full file upload support will also be present by the production 1.0.0 release.
|
||||
|
||||
A benefit of this is that primitive types are automatically deserialized correctly. As in, if you have a `hello=1.5` request, then
|
||||
`body['hello']` will equal `1.5` and not `'1.5'`. A very semantic difference, yes, but it relieves stress in my head.
|
||||
|
||||
# Installation
|
||||
|
||||
To install Body Parser for your Dart project, simply add body_parser to your
|
||||
pub dependencies.
|
||||
|
||||
dependencies:
|
||||
body_parser: any
|
||||
|
||||
# Usage
|
||||
|
||||
Body Parser exposes a simple class called `BodyParseResult`.
|
||||
You can easily parse the query string and request body for a request by calling `Future<BodyParseResult> parseBody`.
|
||||
|
||||
```dart
|
||||
import 'dart:convert';
|
||||
import 'package:body_parser/body_parser.dart';
|
||||
|
||||
main() async {
|
||||
// ...
|
||||
await for (HttpRequest request in server) {
|
||||
request.response.write(JSON.encode(await parseBody(request).body));
|
||||
await request.response.close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also use `buildMapFromUri(Map, String)` to populate a map from a URL encoded string.
|
||||
|
||||
This can easily be used with a library like [JSON God](https://github.com/thosakwe/json_god)
|
||||
to build structured JSON/REST APIs. Add validation and you've got an instant backend.
|
||||
|
||||
```dart
|
||||
MyClass create(HttpRequest request) async {
|
||||
return god.deserialize(await parseBody(request).body, MyClass);
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Body Parsing
|
||||
In cases where you need to parse unrecognized content types, `body_parser` won't be of any help to you
|
||||
on its own. However, you can use the `originalBuffer` property of a `BodyParseResult` to see the original
|
||||
request buffer. To get this functionality, pass `storeOriginalBuffer` as `true` when calling `parseBody`.
|
||||
|
||||
For example, if you wanted to
|
||||
[parse GraphQL queries within your server](https://github.com/angel-dart/graphql)...
|
||||
|
||||
```dart
|
||||
app.get('/graphql', (req, res) async {
|
||||
if (req.headers.contentType.mimeType == 'application/graphql') {
|
||||
var graphQlString = new String.fromCharCodes(req.originalBuffer);
|
||||
// ...
|
||||
}
|
||||
});
|
||||
```
|
3
packages/body_parser/analysis_options.yaml
Normal file
3
packages/body_parser/analysis_options.yaml
Normal file
|
@ -0,0 +1,3 @@
|
|||
analyzer:
|
||||
strong-mode:
|
||||
implicit-casts: false
|
41
packages/body_parser/example/main.dart
Normal file
41
packages/body_parser/example/main.dart
Normal file
|
@ -0,0 +1,41 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'package:body_parser/body_parser.dart';
|
||||
|
||||
main() async {
|
||||
var address = '127.0.0.1';
|
||||
var port = 3000;
|
||||
var futures = <Future>[];
|
||||
|
||||
for (int i = 1; i < Platform.numberOfProcessors; i++) {
|
||||
futures.add(Isolate.spawn(start, [address, port, i]));
|
||||
}
|
||||
|
||||
Future.wait(futures).then((_) {
|
||||
print('All instances started.');
|
||||
print(
|
||||
'Test with "wrk -t12 -c400 -d30s -s ./example/post.lua http://localhost:3000" or similar');
|
||||
start([address, port, 0]);
|
||||
});
|
||||
}
|
||||
|
||||
void start(List args) {
|
||||
var address = new InternetAddress(args[0] as String);
|
||||
int port = args[1], id = args[2];
|
||||
|
||||
HttpServer.bind(address, port, shared: true).then((server) {
|
||||
server.listen((request) async {
|
||||
// ignore: deprecated_member_use
|
||||
var body = await parseBody(request);
|
||||
request.response
|
||||
..headers.contentType = new ContentType('application', 'json')
|
||||
..write(json.encode(body.body))
|
||||
..close();
|
||||
});
|
||||
|
||||
print(
|
||||
'Server #$id listening at http://${server.address.address}:${server.port}');
|
||||
});
|
||||
}
|
6
packages/body_parser/example/post.lua
Normal file
6
packages/body_parser/example/post.lua
Normal file
|
@ -0,0 +1,6 @@
|
|||
-- example HTTP POST script which demonstrates setting the
|
||||
-- HTTP method, body, and adding a header
|
||||
|
||||
wrk.method = "POST"
|
||||
wrk.body = "foo=bar&baz=quux"
|
||||
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
|
6
packages/body_parser/lib/body_parser.dart
Normal file
6
packages/body_parser/lib/body_parser.dart
Normal file
|
@ -0,0 +1,6 @@
|
|||
/// A library for parsing HTTP request bodies and queries.
|
||||
library body_parser;
|
||||
|
||||
export 'src/body_parse_result.dart';
|
||||
export 'src/file_upload_info.dart';
|
||||
export 'src/parse_body.dart';
|
28
packages/body_parser/lib/src/body_parse_result.dart
Normal file
28
packages/body_parser/lib/src/body_parse_result.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
import 'file_upload_info.dart';
|
||||
|
||||
/// A representation of data from an incoming request.
|
||||
abstract class BodyParseResult {
|
||||
/// The parsed body.
|
||||
Map<String, dynamic> get body;
|
||||
|
||||
/// The parsed query string.
|
||||
Map<String, dynamic> get query;
|
||||
|
||||
/// All files uploaded within this request.
|
||||
List<FileUploadInfo> get files;
|
||||
|
||||
/// The original body bytes sent with this request.
|
||||
///
|
||||
/// You must set [storeOriginalBuffer] to `true` to see this.
|
||||
List<int> get originalBuffer;
|
||||
|
||||
/// If an error was encountered while parsing the body, it will appear here.
|
||||
///
|
||||
/// Otherwise, this is `null`.
|
||||
dynamic get error;
|
||||
|
||||
/// If an error was encountered while parsing the body, the call stack will appear here.
|
||||
///
|
||||
/// Otherwise, this is `null`.
|
||||
StackTrace get stack;
|
||||
}
|
7
packages/body_parser/lib/src/chunk.dart
Normal file
7
packages/body_parser/lib/src/chunk.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
import 'file_upload_info.dart';
|
||||
|
||||
List<FileUploadInfo> getFileDataFromChunk(
|
||||
String chunk, String boundary, String fileUploadName, Map body) {
|
||||
List<FileUploadInfo> result = [];
|
||||
return result;
|
||||
}
|
17
packages/body_parser/lib/src/file_upload_info.dart
Normal file
17
packages/body_parser/lib/src/file_upload_info.dart
Normal file
|
@ -0,0 +1,17 @@
|
|||
/// Represents a file uploaded to the server.
|
||||
class FileUploadInfo {
|
||||
/// The MIME type of the uploaded file.
|
||||
String mimeType;
|
||||
|
||||
/// The name of the file field from the request.
|
||||
String name;
|
||||
|
||||
/// The filename of the file.
|
||||
String filename;
|
||||
|
||||
/// The bytes that make up this file.
|
||||
List<int> data;
|
||||
|
||||
FileUploadInfo(
|
||||
{this.mimeType, this.name, this.filename, this.data: const []}) {}
|
||||
}
|
20
packages/body_parser/lib/src/get_value.dart
Normal file
20
packages/body_parser/lib/src/get_value.dart
Normal file
|
@ -0,0 +1,20 @@
|
|||
import 'package:dart2_constant/convert.dart';
|
||||
|
||||
getValue(String value) {
|
||||
try {
|
||||
num numValue = num.parse(value);
|
||||
if (!numValue.isNaN)
|
||||
return numValue;
|
||||
else
|
||||
return value;
|
||||
} on FormatException {
|
||||
if (value.startsWith('[') && value.endsWith(']'))
|
||||
return json.decode(value);
|
||||
else if (value.startsWith('{') && value.endsWith('}'))
|
||||
return json.decode(value);
|
||||
else if (value.trim().toLowerCase() == 'null')
|
||||
return null;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
}
|
43
packages/body_parser/lib/src/map_from_uri.dart
Normal file
43
packages/body_parser/lib/src/map_from_uri.dart
Normal file
|
@ -0,0 +1,43 @@
|
|||
import 'get_value.dart';
|
||||
|
||||
/// Parses a URI-encoded string into real data! **Wow!**
|
||||
///
|
||||
/// Whichever map you provide will be automatically populated from the urlencoded body string you provide.
|
||||
buildMapFromUri(Map map, String body) {
|
||||
RegExp parseArrayRgx = new RegExp(r'^(.+)\[\]$');
|
||||
|
||||
for (String keyValuePair in body.split('&')) {
|
||||
if (keyValuePair.contains('=')) {
|
||||
var equals = keyValuePair.indexOf('=');
|
||||
String key = Uri.decodeQueryComponent(keyValuePair.substring(0, equals));
|
||||
String value =
|
||||
Uri.decodeQueryComponent(keyValuePair.substring(equals + 1));
|
||||
|
||||
if (parseArrayRgx.hasMatch(key)) {
|
||||
Match queryMatch = parseArrayRgx.firstMatch(key);
|
||||
key = queryMatch.group(1);
|
||||
if (!(map[key] is List)) {
|
||||
map[key] = [];
|
||||
}
|
||||
|
||||
map[key].add(getValue(value));
|
||||
} else if (key.contains('.')) {
|
||||
// i.e. map.foo.bar => [map, foo, bar]
|
||||
List<String> keys = key.split('.');
|
||||
|
||||
Map targetMap = map[keys[0]] != null ? map[keys[0]] as Map : {};
|
||||
map[keys[0]] = targetMap;
|
||||
for (int i = 1; i < keys.length; i++) {
|
||||
if (i < keys.length - 1) {
|
||||
targetMap[keys[i]] = targetMap[keys[i]] ?? {};
|
||||
targetMap = targetMap[keys[i]] as Map;
|
||||
} else {
|
||||
targetMap[keys[i]] = getValue(value);
|
||||
}
|
||||
}
|
||||
} else
|
||||
map[key] = getValue(value);
|
||||
} else
|
||||
map[Uri.decodeQueryComponent(keyValuePair)] = true;
|
||||
}
|
||||
}
|
151
packages/body_parser/lib/src/parse_body.dart
Normal file
151
packages/body_parser/lib/src/parse_body.dart
Normal file
|
@ -0,0 +1,151 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dart2_constant/convert.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:http_server/http_server.dart';
|
||||
import 'package:mime/mime.dart';
|
||||
|
||||
import 'body_parse_result.dart';
|
||||
import 'file_upload_info.dart';
|
||||
import 'map_from_uri.dart';
|
||||
|
||||
/// Forwards to [parseBodyFromStream].
|
||||
@deprecated
|
||||
Future<BodyParseResult> parseBody(HttpRequest request,
|
||||
{bool storeOriginalBuffer: false}) {
|
||||
return parseBodyFromStream(
|
||||
request,
|
||||
request.headers.contentType != null
|
||||
? new MediaType.parse(request.headers.contentType.toString())
|
||||
: null,
|
||||
request.uri,
|
||||
storeOriginalBuffer: storeOriginalBuffer);
|
||||
}
|
||||
|
||||
/// Grabs data from an incoming request.
|
||||
///
|
||||
/// Supports URL-encoded and JSON, as well as multipart/* forms.
|
||||
/// On a file upload request, only fields with the name **'file'** are processed
|
||||
/// as files. Anything else is put in the body. You can change the upload file name
|
||||
/// via the *fileUploadName* parameter. :)
|
||||
///
|
||||
/// Use [storeOriginalBuffer] to add the original request bytes to the result.
|
||||
Future<BodyParseResult> parseBodyFromStream(
|
||||
Stream<Uint8List> data, MediaType contentType, Uri requestUri,
|
||||
{bool storeOriginalBuffer: false}) async {
|
||||
var result = new _BodyParseResultImpl();
|
||||
|
||||
Future<Uint8List> getBytes() {
|
||||
return data
|
||||
.fold<BytesBuilder>(new BytesBuilder(copy: false), (a, b) => a..add(b))
|
||||
.then((b) => b.takeBytes());
|
||||
}
|
||||
|
||||
Future<String> getBody() {
|
||||
if (storeOriginalBuffer) {
|
||||
return getBytes().then((bytes) {
|
||||
result.originalBuffer = bytes;
|
||||
return utf8.decode(bytes);
|
||||
});
|
||||
} else {
|
||||
return utf8.decoder.bind(data).join();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (contentType != null) {
|
||||
if (contentType.type == 'multipart' &&
|
||||
contentType.parameters.containsKey('boundary')) {
|
||||
Stream<Uint8List> stream;
|
||||
|
||||
if (storeOriginalBuffer) {
|
||||
var bytes = result.originalBuffer = await getBytes();
|
||||
var ctrl = new StreamController<Uint8List>()
|
||||
..add(bytes)
|
||||
..close();
|
||||
stream = ctrl.stream;
|
||||
} else {
|
||||
stream = data;
|
||||
}
|
||||
|
||||
var parts = MimeMultipartTransformer(
|
||||
contentType.parameters['boundary']).bind(stream)
|
||||
.map((part) =>
|
||||
HttpMultipartFormData.parse(part, defaultEncoding: utf8));
|
||||
|
||||
await for (HttpMultipartFormData part in parts) {
|
||||
if (part.isBinary ||
|
||||
part.contentDisposition.parameters.containsKey("filename")) {
|
||||
BytesBuilder builder = await part.fold(
|
||||
new BytesBuilder(copy: false),
|
||||
(BytesBuilder b, d) => b
|
||||
..add(d is! String
|
||||
? (d as List<int>)
|
||||
: (d as String).codeUnits));
|
||||
var upload = new FileUploadInfo(
|
||||
mimeType: part.contentType.mimeType,
|
||||
name: part.contentDisposition.parameters['name'],
|
||||
filename:
|
||||
part.contentDisposition.parameters['filename'] ?? 'file',
|
||||
data: builder.takeBytes());
|
||||
result.files.add(upload);
|
||||
} else if (part.isText) {
|
||||
var text = await part.join();
|
||||
buildMapFromUri(result.body,
|
||||
'${part.contentDisposition.parameters["name"]}=$text');
|
||||
}
|
||||
}
|
||||
} else if (contentType.mimeType == 'application/json') {
|
||||
result.body
|
||||
.addAll(_foldToStringDynamic(json.decode(await getBody()) as Map));
|
||||
} else if (contentType.mimeType == 'application/x-www-form-urlencoded') {
|
||||
String body = await getBody();
|
||||
buildMapFromUri(result.body, body);
|
||||
} else if (storeOriginalBuffer == true) {
|
||||
result.originalBuffer = await getBytes();
|
||||
}
|
||||
} else {
|
||||
if (requestUri.hasQuery) {
|
||||
buildMapFromUri(result.query, requestUri.query);
|
||||
}
|
||||
|
||||
if (storeOriginalBuffer == true) {
|
||||
result.originalBuffer = await getBytes();
|
||||
}
|
||||
}
|
||||
} catch (e, st) {
|
||||
result.error = e;
|
||||
result.stack = st;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
class _BodyParseResultImpl implements BodyParseResult {
|
||||
@override
|
||||
Map<String, dynamic> body = {};
|
||||
|
||||
@override
|
||||
List<FileUploadInfo> files = [];
|
||||
|
||||
@override
|
||||
List<int> originalBuffer;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> query = {};
|
||||
|
||||
@override
|
||||
var error = null;
|
||||
|
||||
@override
|
||||
StackTrace stack = null;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _foldToStringDynamic(Map map) {
|
||||
return map == null
|
||||
? null
|
||||
: map.keys.fold<Map<String, dynamic>>(
|
||||
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
|
||||
}
|
15
packages/body_parser/pubspec.yaml
Normal file
15
packages/body_parser/pubspec.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
name: body_parser
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
version: 1.1.1
|
||||
description: Parse request bodies and query strings in Dart. Supports JSON, URL-encoded, and multi-part bodies.
|
||||
homepage: https://github.com/angel-dart/body_parser
|
||||
environment:
|
||||
sdk: ">=1.8.0 <3.0.0"
|
||||
dependencies:
|
||||
dart2_constant: ^1.0.0
|
||||
http_parser: ">=3.1.1 <4.0.0"
|
||||
http_server: ">=0.9.6 <1.0.0"
|
||||
mime: ">=0.9.3 <1.0.0"
|
||||
dev_dependencies:
|
||||
http: ">=0.11.3 <0.12.0"
|
||||
test: ">=0.12.15"
|
142
packages/body_parser/test/form_data_test.dart
Normal file
142
packages/body_parser/test/form_data_test.dart
Normal file
|
@ -0,0 +1,142 @@
|
|||
import 'dart:io';
|
||||
import 'package:body_parser/body_parser.dart';
|
||||
import 'package:dart2_constant/convert.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:test/test.dart';
|
||||
import 'server_test.dart';
|
||||
|
||||
main() {
|
||||
HttpServer server;
|
||||
String url;
|
||||
http.Client client;
|
||||
|
||||
setUp(() async {
|
||||
server = await HttpServer.bind('127.0.0.1', 0);
|
||||
server.listen((HttpRequest request) async {
|
||||
//Server will simply return a JSON representation of the parsed body
|
||||
// ignore: deprecated_member_use
|
||||
request.response.write(jsonEncodeBody(await parseBody(request)));
|
||||
await request.response.close();
|
||||
});
|
||||
url = 'http://localhost:${server.port}';
|
||||
print('Test server listening on $url');
|
||||
client = new http.Client();
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await server.close(force: true);
|
||||
client.close();
|
||||
server = null;
|
||||
url = null;
|
||||
client = null;
|
||||
});
|
||||
|
||||
test('No upload', () async {
|
||||
String boundary = 'myBoundary';
|
||||
Map<String, String> headers = {
|
||||
'content-type': 'multipart/form-data; boundary=$boundary'
|
||||
};
|
||||
String postData = '''
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="hello"
|
||||
|
||||
world
|
||||
--$boundary--
|
||||
'''
|
||||
.replaceAll("\n", "\r\n");
|
||||
|
||||
print(
|
||||
'Form Data: \n${postData.replaceAll("\r", "\\r").replaceAll("\n", "\\n")}');
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
print('Response: ${response.body}');
|
||||
Map jsons = json.decode(response.body);
|
||||
var files = jsons['files'].map((map) {
|
||||
return map == null
|
||||
? null
|
||||
: map.keys.fold<Map<String, dynamic>>(
|
||||
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
|
||||
});
|
||||
expect(files.length, equals(0));
|
||||
expect(jsons['body']['hello'], equals('world'));
|
||||
});
|
||||
|
||||
test('Single upload', () async {
|
||||
String boundary = 'myBoundary';
|
||||
Map<String, String> headers = {
|
||||
'content-type': new ContentType("multipart", "form-data",
|
||||
parameters: {"boundary": boundary}).toString()
|
||||
};
|
||||
String postData = '''
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="hello"
|
||||
|
||||
world
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="file"; filename="app.dart"
|
||||
Content-Type: application/dart
|
||||
|
||||
Hello world
|
||||
--$boundary--
|
||||
'''
|
||||
.replaceAll("\n", "\r\n");
|
||||
|
||||
print(
|
||||
'Form Data: \n${postData.replaceAll("\r", "\\r").replaceAll("\n", "\\n")}');
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
print('Response: ${response.body}');
|
||||
Map jsons = json.decode(response.body);
|
||||
var files = jsons['files'];
|
||||
expect(files.length, equals(1));
|
||||
expect(files[0]['name'], equals('file'));
|
||||
expect(files[0]['mimeType'], equals('application/dart'));
|
||||
expect(files[0]['data'].length, equals(11));
|
||||
expect(files[0]['filename'], equals('app.dart'));
|
||||
expect(jsons['body']['hello'], equals('world'));
|
||||
});
|
||||
|
||||
test('Multiple upload', () async {
|
||||
String boundary = 'myBoundary';
|
||||
Map<String, String> headers = {
|
||||
'content-type': 'multipart/form-data; boundary=$boundary'
|
||||
};
|
||||
String postData = '''
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="json"
|
||||
|
||||
god
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="num"
|
||||
|
||||
14.50000
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="file"; filename="app.dart"
|
||||
Content-Type: text/plain
|
||||
|
||||
Hello world
|
||||
--$boundary
|
||||
Content-Disposition: form-data; name="entry-point"; filename="main.js"
|
||||
Content-Type: text/javascript
|
||||
|
||||
function main() {
|
||||
console.log("Hello, world!");
|
||||
}
|
||||
--$boundary--
|
||||
'''
|
||||
.replaceAll("\n", "\r\n");
|
||||
|
||||
print(
|
||||
'Form Data: \n${postData.replaceAll("\r", "\\r").replaceAll("\n", "\\n")}');
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
print('Response: ${response.body}');
|
||||
Map jsons = json.decode(response.body);
|
||||
var files = jsons['files'];
|
||||
expect(files.length, equals(2));
|
||||
expect(files[0]['name'], equals('file'));
|
||||
expect(files[0]['mimeType'], equals('text/plain'));
|
||||
expect(files[0]['data'].length, equals(11));
|
||||
expect(files[1]['name'], equals('entry-point'));
|
||||
expect(files[1]['mimeType'], equals('text/javascript'));
|
||||
expect(jsons['body']['json'], equals('god'));
|
||||
expect(jsons['body']['num'], equals(14.5));
|
||||
});
|
||||
}
|
159
packages/body_parser/test/server_test.dart
Normal file
159
packages/body_parser/test/server_test.dart
Normal file
|
@ -0,0 +1,159 @@
|
|||
import 'dart:io' show HttpRequest, HttpServer;
|
||||
|
||||
import 'package:body_parser/body_parser.dart';
|
||||
import 'package:dart2_constant/convert.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
const TOKEN =
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIxMjcuMC4wLjEiLCJleHAiOi0xLCJpYXQiOiIyMDE2LTEyLTIyVDEyOjQ5OjUwLjM2MTQ0NiIsImlzcyI6ImFuZ2VsX2F1dGgiLCJzdWIiOiIxMDY2OTQ4Mzk2MDIwMjg5ODM2NTYifQ==.PYw7yUb-cFWD7N0sSLztP7eeRvO44nu1J2OgDNyT060=';
|
||||
|
||||
String jsonEncodeBody(BodyParseResult result) {
|
||||
return json.encode({
|
||||
'query': result.query,
|
||||
'body': result.body,
|
||||
'error': result.error?.toString(),
|
||||
'files': result.files.map((f) {
|
||||
return {
|
||||
'name': f.name,
|
||||
'mimeType': f.mimeType,
|
||||
'filename': f.filename,
|
||||
'data': f.data,
|
||||
};
|
||||
}).toList(),
|
||||
'originalBuffer': result.originalBuffer,
|
||||
'stack': null, //result.stack.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
main() {
|
||||
HttpServer server;
|
||||
String url;
|
||||
http.Client client;
|
||||
|
||||
setUp(() async {
|
||||
server = await HttpServer.bind('127.0.0.1', 0);
|
||||
server.listen((HttpRequest request) async {
|
||||
//Server will simply return a JSON representation of the parsed body
|
||||
request.response.write(
|
||||
// ignore: deprecated_member_use
|
||||
jsonEncodeBody(await parseBody(request, storeOriginalBuffer: true)));
|
||||
await request.response.close();
|
||||
});
|
||||
url = 'http://localhost:${server.port}';
|
||||
print('Test server listening on $url');
|
||||
client = new http.Client();
|
||||
});
|
||||
tearDown(() async {
|
||||
await server.close(force: true);
|
||||
client.close();
|
||||
server = null;
|
||||
url = null;
|
||||
client = null;
|
||||
});
|
||||
|
||||
group('query string', () {
|
||||
test('GET Simple', () async {
|
||||
print('GET $url/?hello=world');
|
||||
var response = await client.get('$url/?hello=world');
|
||||
print('Response: ${response.body}');
|
||||
var result = json.decode(response.body);
|
||||
expect(result['body'], equals({}));
|
||||
expect(result['query'], equals({'hello': 'world'}));
|
||||
expect(result['files'], equals([]));
|
||||
//expect(result['originalBuffer'], isNull);
|
||||
});
|
||||
|
||||
test('GET Complex', () async {
|
||||
var postData =
|
||||
'hello=world&nums%5B%5D=1&nums%5B%5D=2.0&nums%5B%5D=${3 - 1}&map.foo.bar=baz';
|
||||
print('Body: $postData');
|
||||
var response = await client.get('$url/?$postData');
|
||||
print('Response: ${response.body}');
|
||||
var query = json.decode(response.body)['query'];
|
||||
expect(query['hello'], equals('world'));
|
||||
expect(query['nums'][2], equals(2));
|
||||
expect(query['map'] is Map, equals(true));
|
||||
expect(query['map']['foo'], equals({'bar': 'baz'}));
|
||||
});
|
||||
|
||||
test('JWT', () async {
|
||||
var postData = 'token=$TOKEN';
|
||||
print('Body: $postData');
|
||||
var response = await client.get('$url/?$postData');
|
||||
print('Response: ${response.body}');
|
||||
var query = json.decode(response.body)['query'];
|
||||
expect(query['token'], equals(TOKEN));
|
||||
});
|
||||
});
|
||||
|
||||
group('urlencoded', () {
|
||||
Map<String, String> headers = {
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
};
|
||||
test('POST Simple', () async {
|
||||
print('Body: hello=world');
|
||||
var response =
|
||||
await client.post(url, headers: headers, body: 'hello=world');
|
||||
print('Response: ${response.body}');
|
||||
var result = json.decode(response.body);
|
||||
expect(result['query'], equals({}));
|
||||
expect(result['body'], equals({'hello': 'world'}));
|
||||
expect(result['files'], equals([]));
|
||||
expect(result['originalBuffer'], isList);
|
||||
expect(result['originalBuffer'], isNotEmpty);
|
||||
});
|
||||
|
||||
test('Post Complex', () async {
|
||||
var postData =
|
||||
'hello=world&nums%5B%5D=1&nums%5B%5D=2.0&nums%5B%5D=${3 - 1}&map.foo.bar=baz';
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
print('Response: ${response.body}');
|
||||
var body = json.decode(response.body)['body'];
|
||||
expect(body['hello'], equals('world'));
|
||||
expect(body['nums'][2], equals(2));
|
||||
expect(body['map'] is Map, equals(true));
|
||||
expect(body['map']['foo'], equals({'bar': 'baz'}));
|
||||
});
|
||||
|
||||
test('JWT', () async {
|
||||
var postData = 'token=$TOKEN';
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
var body = json.decode(response.body)['body'];
|
||||
expect(body['token'], equals(TOKEN));
|
||||
});
|
||||
});
|
||||
|
||||
group('json', () {
|
||||
Map<String, String> headers = {'content-type': 'application/json'};
|
||||
test('Post Simple', () async {
|
||||
var postData = json.encode({'hello': 'world'});
|
||||
print('Body: $postData');
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
print('Response: ${response.body}');
|
||||
var result = json.decode(response.body);
|
||||
expect(result['body'], equals({'hello': 'world'}));
|
||||
expect(result['query'], equals({}));
|
||||
expect(result['files'], equals([]));
|
||||
expect(result['originalBuffer'], allOf(isList, isNotEmpty));
|
||||
});
|
||||
|
||||
test('Post Complex', () async {
|
||||
var postData = json.encode({
|
||||
'hello': 'world',
|
||||
'nums': [1, 2.0, 3 - 1],
|
||||
'map': {
|
||||
'foo': {'bar': 'baz'}
|
||||
}
|
||||
});
|
||||
print('Body: $postData');
|
||||
var response = await client.post(url, headers: headers, body: postData);
|
||||
print('Response: ${response.body}');
|
||||
var body = json.decode(response.body)['body'];
|
||||
expect(body['hello'], equals('world'));
|
||||
expect(body['nums'][2], equals(2));
|
||||
expect(body['map'] is Map, equals(true));
|
||||
expect(body['map']['foo'], equals({'bar': 'baz'}));
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue