mirror of
https://github.com/dart-lang/sdk
synced 2024-10-02 23:59:16 +00:00
Reland: [dart:io] Moves Http code into a separate library.
This moves Http code into dart:_http. dart:io then imports and re-exports dart:_http. This is the first stage of moving dart:_http into its own pub package. This CL was reverted due to a failure in the Flutter engine build which happened due to an incomplete change in gen_snapshot.cc, and to update sdk/lib/libraries.yaml and sdk/lib/libraries.json Change-Id: Ie90c77ef631aea7a163774b58e8ccbaf71a24d3c Reviewed-on: https://dart-review.googlesource.com/7588 Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
parent
2d2af807f3
commit
2948f8c1b7
|
@ -32,6 +32,8 @@
|
|||
in 'timeout'.
|
||||
* Added `Platform.operatingSystemVersion` that gives a platform-specific
|
||||
String describing the version of the operating system.
|
||||
* Added `RawZLibFilter` for low-level access to compression and
|
||||
decompression.
|
||||
|
||||
* `dart:core`
|
||||
* The `Uri` class now correctly handles paths while running on Node.js on
|
||||
|
|
|
@ -75,6 +75,8 @@ const Map<String, LibraryInfo> libraries = const {
|
|||
categories: "Client",
|
||||
maturity: Maturity.WEB_STABLE,
|
||||
platforms: DART2JS_PLATFORM),
|
||||
"_http":
|
||||
const LibraryInfo("_http/http.dart", categories: "", documented: false),
|
||||
"io": const LibraryInfo("io/io.dart",
|
||||
categories: "Server",
|
||||
dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
|
||||
|
|
|
@ -564,15 +564,21 @@ class _WindowsCodePageEncoder {
|
|||
}
|
||||
|
||||
@patch
|
||||
class _Filter {
|
||||
class RawZLibFilter {
|
||||
@patch
|
||||
static _Filter _newZLibDeflateFilter(bool gzip, int level, int windowBits,
|
||||
int memLevel, int strategy, List<int> dictionary, bool raw) {
|
||||
static RawZLibFilter _makeZLibDeflateFilter(
|
||||
bool gzip,
|
||||
int level,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
List<int> dictionary,
|
||||
bool raw) {
|
||||
throw new UnsupportedError("_newZLibDeflateFilter");
|
||||
}
|
||||
|
||||
@patch
|
||||
static _Filter _newZLibInflateFilter(
|
||||
static RawZLibFilter _makeZLibInflateFilter(
|
||||
int windowBits, List<int> dictionary, bool raw) {
|
||||
throw new UnsupportedError("_newZLibInflateFilter");
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import("../../build/compiled_action.gni")
|
||||
import("../../sdk/lib/_http/http_sources.gni")
|
||||
import("../../sdk/lib/io/io_sources.gni")
|
||||
import("../runtime_args.gni")
|
||||
import("../vm/compiler/compiler_sources.gni")
|
||||
|
@ -105,6 +106,16 @@ gen_library_src_path("generate_io_patch_cc_file") {
|
|||
output = "$target_gen_dir/io_patch_gen.cc"
|
||||
}
|
||||
|
||||
rebased_http_sdk_sources =
|
||||
rebase_path(http_sdk_sources, ".", "../../sdk/lib/_http")
|
||||
|
||||
gen_library_src_path("generate_http_cc_file") {
|
||||
name = "_http"
|
||||
kind = "source"
|
||||
sources = [ "../../sdk/lib/_http/http.dart" ] + rebased_http_sdk_sources
|
||||
output = "$target_gen_dir/http_gen.cc"
|
||||
}
|
||||
|
||||
gen_library_src_path("generate_html_cc_file") {
|
||||
name = "html"
|
||||
kind = "source"
|
||||
|
@ -229,6 +240,7 @@ template("build_libdart_builtin") {
|
|||
":generate_builtin_cc_file",
|
||||
":generate_html_cc_file",
|
||||
":generate_html_common_cc_file",
|
||||
":generate_http_cc_file",
|
||||
":generate_indexed_db_cc_file",
|
||||
":generate_io_cc_file",
|
||||
":generate_io_patch_cc_file",
|
||||
|
@ -283,6 +295,7 @@ template("build_gen_snapshot") {
|
|||
deps = [
|
||||
":gen_resources_cc",
|
||||
":generate_builtin_cc_file",
|
||||
":generate_http_cc_file",
|
||||
":generate_io_cc_file",
|
||||
":generate_io_patch_cc_file",
|
||||
] + extra_deps
|
||||
|
@ -290,6 +303,7 @@ template("build_gen_snapshot") {
|
|||
sources = [
|
||||
# Include generated source files.
|
||||
"$target_gen_dir/builtin_gen.cc",
|
||||
"$target_gen_dir/http_gen.cc",
|
||||
"$target_gen_dir/io_gen.cc",
|
||||
"$target_gen_dir/io_patch_gen.cc",
|
||||
"$target_gen_dir/resources_gen.cc",
|
||||
|
@ -786,6 +800,7 @@ dart_executable("dart_bootstrap") {
|
|||
":generate_builtin_cc_file",
|
||||
":generate_html_cc_file",
|
||||
":generate_html_common_cc_file",
|
||||
":generate_http_cc_file",
|
||||
":generate_indexed_db_cc_file",
|
||||
":generate_io_cc_file",
|
||||
":generate_io_patch_cc_file",
|
||||
|
@ -815,6 +830,7 @@ dart_executable("dart_bootstrap") {
|
|||
"$target_gen_dir/builtin_gen.cc",
|
||||
"$target_gen_dir/html_common_gen.cc",
|
||||
"$target_gen_dir/html_gen.cc",
|
||||
"$target_gen_dir/http_gen.cc",
|
||||
"$target_gen_dir/indexed_db_gen.cc",
|
||||
"$target_gen_dir/io_gen.cc",
|
||||
"$target_gen_dir/io_patch_gen.cc",
|
||||
|
|
|
@ -18,6 +18,7 @@ Builtin::builtin_lib_props Builtin::builtin_libraries_[] = {
|
|||
{DartUtils::kBuiltinLibURL, _builtin_source_paths_, NULL, NULL, true},
|
||||
{DartUtils::kIOLibURL, io_source_paths_, DartUtils::kIOLibPatchURL,
|
||||
io_patch_paths_, true},
|
||||
{DartUtils::kHttpLibURL, _http_source_paths_, NULL, NULL, false},
|
||||
|
||||
#if defined(DART_NO_SNAPSHOT)
|
||||
// Only include these libraries in the dart_bootstrap case for now.
|
||||
|
|
|
@ -28,7 +28,8 @@ class Builtin {
|
|||
enum BuiltinLibraryId {
|
||||
kInvalidLibrary = -1,
|
||||
kBuiltinLibrary = 0,
|
||||
kIOLibrary
|
||||
kIOLibrary,
|
||||
kHttpLibrary,
|
||||
};
|
||||
|
||||
// Get source corresponding to built in library specified in 'id'.
|
||||
|
@ -67,6 +68,7 @@ class Builtin {
|
|||
static const uint8_t* NativeSymbol(Dart_NativeFunction nf);
|
||||
|
||||
static const char* _builtin_source_paths_[];
|
||||
static const char* _http_source_paths_[];
|
||||
static const char* io_source_paths_[];
|
||||
static const char* io_patch_paths_[];
|
||||
static const char* html_source_paths_[];
|
||||
|
|
|
@ -17,7 +17,7 @@ Builtin::builtin_lib_props Builtin::builtin_libraries_[] = {
|
|||
/* { url_, source_, patch_url_, patch_source_, has_natives_ } */
|
||||
{DartUtils::kBuiltinLibURL, NULL, NULL, NULL, true},
|
||||
{DartUtils::kIOLibURL, NULL, NULL, NULL, true},
|
||||
|
||||
{DartUtils::kHttpLibURL, NULL, NULL, NULL, false},
|
||||
// End marker.
|
||||
{NULL, NULL, NULL, NULL, false}};
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ const char* const DartUtils::kBuiltinLibURL = "dart:_builtin";
|
|||
const char* const DartUtils::kCoreLibURL = "dart:core";
|
||||
const char* const DartUtils::kInternalLibURL = "dart:_internal";
|
||||
const char* const DartUtils::kIsolateLibURL = "dart:isolate";
|
||||
const char* const DartUtils::kHttpLibURL = "dart:_http";
|
||||
const char* const DartUtils::kIOLibURL = "dart:io";
|
||||
const char* const DartUtils::kIOLibPatchURL = "dart:io-patch";
|
||||
const char* const DartUtils::kUriLibURL = "dart:uri";
|
||||
|
@ -173,6 +174,10 @@ bool DartUtils::IsDartIOLibURL(const char* url_name) {
|
|||
return (strcmp(url_name, kIOLibURL) == 0);
|
||||
}
|
||||
|
||||
bool DartUtils::IsDartHttpLibURL(const char* url_name) {
|
||||
return (strcmp(url_name, kHttpLibURL) == 0);
|
||||
}
|
||||
|
||||
bool DartUtils::IsDartBuiltinLibURL(const char* url_name) {
|
||||
return (strcmp(url_name, kBuiltinLibURL) == 0);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ class DartUtils {
|
|||
static bool IsDartSchemeURL(const char* url_name);
|
||||
static bool IsDartExtensionSchemeURL(const char* url_name);
|
||||
static bool IsDartIOLibURL(const char* url_name);
|
||||
static bool IsDartHttpLibURL(const char* url_name);
|
||||
static bool IsDartBuiltinLibURL(const char* url_name);
|
||||
static bool IsHttpSchemeURL(const char* url_name);
|
||||
static const char* RemoveScheme(const char* url);
|
||||
|
@ -227,6 +228,7 @@ class DartUtils {
|
|||
static const char* const kCoreLibURL;
|
||||
static const char* const kInternalLibURL;
|
||||
static const char* const kIsolateLibURL;
|
||||
static const char* const kHttpLibURL;
|
||||
static const char* const kIOLibURL;
|
||||
static const char* const kIOLibPatchURL;
|
||||
static const char* const kUriLibURL;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
class _FilterImpl extends NativeFieldWrapperClass1 implements _Filter {
|
||||
class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter {
|
||||
void process(List<int> data, int start, int end) native "Filter_Process";
|
||||
|
||||
List<int> processed({bool flush: true, bool end: false})
|
||||
|
@ -27,14 +27,20 @@ class _ZLibDeflateFilter extends _FilterImpl {
|
|||
}
|
||||
|
||||
@patch
|
||||
class _Filter {
|
||||
class RawZLibFilter {
|
||||
@patch
|
||||
static _Filter _newZLibDeflateFilter(bool gzip, int level, int windowBits,
|
||||
int memLevel, int strategy, List<int> dictionary, bool raw) =>
|
||||
static RawZLibFilter _makeZLibDeflateFilter(
|
||||
bool gzip,
|
||||
int level,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
List<int> dictionary,
|
||||
bool raw) =>
|
||||
new _ZLibDeflateFilter(
|
||||
gzip, level, windowBits, memLevel, strategy, dictionary, raw);
|
||||
@patch
|
||||
static _Filter _newZLibInflateFilter(
|
||||
static RawZLibFilter _makeZLibInflateFilter(
|
||||
int windowBits, List<int> dictionary, bool raw) =>
|
||||
new _ZLibInflateFilter(windowBits, dictionary, raw);
|
||||
}
|
||||
|
|
|
@ -454,6 +454,9 @@ static Builtin::BuiltinLibraryId BuiltinId(const char* url) {
|
|||
if (DartUtils::IsDartIOLibURL(url)) {
|
||||
return Builtin::kIOLibrary;
|
||||
}
|
||||
if (DartUtils::IsDartHttpLibURL(url)) {
|
||||
return Builtin::kHttpLibrary;
|
||||
}
|
||||
return Builtin::kInvalidLibrary;
|
||||
}
|
||||
|
||||
|
|
143
sdk/BUILD.gn
143
sdk/BUILD.gn
|
@ -18,6 +18,7 @@ import("../build/copy_tree.gni")
|
|||
declare_args() {
|
||||
# Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries.
|
||||
dart_platform_sdk = true
|
||||
|
||||
# Path to stripped dart binary relative to build output directory.
|
||||
dart_stripped_binary = "dart"
|
||||
}
|
||||
|
@ -71,6 +72,7 @@ declare_args() {
|
|||
# ......core/
|
||||
# ......front_end/
|
||||
# ......html/
|
||||
# ......_http/
|
||||
# ......internal/
|
||||
# ......io/
|
||||
# ......isolate/
|
||||
|
@ -167,6 +169,7 @@ _platform_sdk_libraries = [
|
|||
"convert",
|
||||
"core",
|
||||
"developer",
|
||||
"_http",
|
||||
"internal",
|
||||
"io",
|
||||
"isolate",
|
||||
|
@ -185,6 +188,7 @@ _full_sdk_libraries = [
|
|||
"core",
|
||||
"developer",
|
||||
"html",
|
||||
"_http",
|
||||
"indexed_db",
|
||||
"internal",
|
||||
"io",
|
||||
|
@ -215,89 +219,90 @@ copy_tree_specs = []
|
|||
|
||||
# This loop generates rules for copying analyzer sources into lib/
|
||||
foreach(analyzer_source_dir, _analyzer_source_dirs) {
|
||||
copy_tree_specs += [{
|
||||
target = "copy_${analyzer_source_dir}_source_dir"
|
||||
visibility = [ ":copy_analyzer_sources" ]
|
||||
source = "../pkg/$analyzer_source_dir"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$analyzer_source_dir"
|
||||
ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore,packages,test,testcases"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_${analyzer_source_dir}_source_dir"
|
||||
visibility = [ ":copy_analyzer_sources" ]
|
||||
source = "../pkg/$analyzer_source_dir"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$analyzer_source_dir"
|
||||
ignore_patterns =
|
||||
"*.svn,doc,*.py,*.gypi,*.sh,.gitignore,packages,test,testcases"
|
||||
} ]
|
||||
}
|
||||
|
||||
# This rule copies dartdoc templates to
|
||||
# bin/snapshots/resources/dartdoc/templates
|
||||
copy_tree_specs += [{
|
||||
target = "copy_dartdoc_templates"
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/templates"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/templates"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_dartdoc_templates"
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/templates"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/templates"
|
||||
ignore_patterns = "{}"
|
||||
} ]
|
||||
|
||||
# This rule copies dartdoc resources to
|
||||
# bin/snapshots/resources/dartdoc/resources
|
||||
copy_tree_specs += [{
|
||||
target = "copy_dartdoc_resources"
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/resources"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/resources"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_dartdoc_resources"
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/resources"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/resources"
|
||||
ignore_patterns = "{}"
|
||||
} ]
|
||||
|
||||
# This rule copies js needed by ddc to lib/dev_compiler
|
||||
copy_tree_specs += [{
|
||||
target = "copy_dev_compiler_js"
|
||||
visibility = [
|
||||
":copy_dev_compiler_sdk",
|
||||
":copy_dev_compiler_require_js",
|
||||
":copy_dev_compiler_tools",
|
||||
]
|
||||
source = "../pkg/dev_compiler/lib/js"
|
||||
dest = "$root_out_dir/dart-sdk/lib/dev_compiler"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_dev_compiler_js"
|
||||
visibility = [
|
||||
":copy_dev_compiler_sdk",
|
||||
":copy_dev_compiler_require_js",
|
||||
":copy_dev_compiler_tools",
|
||||
]
|
||||
source = "../pkg/dev_compiler/lib/js"
|
||||
dest = "$root_out_dir/dart-sdk/lib/dev_compiler"
|
||||
ignore_patterns = "{}"
|
||||
} ]
|
||||
|
||||
# This rule copies pub assets to lib/_internal/pub/asset
|
||||
copy_tree_specs += [{
|
||||
target = "copy_pub_assets"
|
||||
visibility = [
|
||||
":create_common_sdk",
|
||||
":copy_7zip",
|
||||
]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
]
|
||||
source = "../third_party/pkg/pub/lib/src/asset"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_pub_assets"
|
||||
visibility = [
|
||||
":create_common_sdk",
|
||||
":copy_7zip",
|
||||
]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
]
|
||||
source = "../third_party/pkg/pub/lib/src/asset"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset"
|
||||
ignore_patterns = "{}"
|
||||
} ]
|
||||
|
||||
# This loop generates rules to copy libraries to lib/
|
||||
foreach(library, _full_sdk_libraries) {
|
||||
copy_tree_specs += [{
|
||||
target = "copy_${library}_library"
|
||||
visibility = [
|
||||
":copy_platform_sdk_libraries",
|
||||
":copy_full_sdk_libraries",
|
||||
]
|
||||
source = "lib/$library"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$library"
|
||||
ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_${library}_library"
|
||||
visibility = [
|
||||
":copy_platform_sdk_libraries",
|
||||
":copy_full_sdk_libraries",
|
||||
]
|
||||
source = "lib/$library"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$library"
|
||||
ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
|
||||
} ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
copy_tree_specs += [{
|
||||
target = "copy_7zip"
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
":copy_pub_assets",
|
||||
]
|
||||
source = "../third_party/7zip"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
|
||||
ignore_patterns = ".svn"
|
||||
}]
|
||||
copy_tree_specs += [ {
|
||||
target = "copy_7zip"
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
":copy_pub_assets",
|
||||
]
|
||||
source = "../third_party/7zip"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
|
||||
ignore_patterns = ".svn"
|
||||
} ]
|
||||
}
|
||||
|
||||
# This generates targets for everything in copy_tree_specs. The targets have the
|
||||
|
@ -319,7 +324,7 @@ copy("copy_dart") {
|
|||
]
|
||||
} else {
|
||||
sources = [
|
||||
"$dart_out/$dart_stripped_binary"
|
||||
"$dart_out/$dart_stripped_binary",
|
||||
]
|
||||
}
|
||||
if (is_win) {
|
||||
|
@ -778,9 +783,7 @@ group("create_platform_sdk") {
|
|||
|
||||
# Parts specific to the full SDK.
|
||||
group("create_full_sdk") {
|
||||
visibility = [
|
||||
":create_sdk",
|
||||
]
|
||||
visibility = [ ":create_sdk" ]
|
||||
|
||||
deps = [
|
||||
":copy_dart2js_dill_files",
|
||||
|
|
458
sdk/lib/_http/crypto.dart
Normal file
458
sdk/lib/_http/crypto.dart
Normal file
|
@ -0,0 +1,458 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart._http;
|
||||
|
||||
class _CryptoUtils {
|
||||
static const int PAD = 61; // '='
|
||||
static const int CR = 13; // '\r'
|
||||
static const int LF = 10; // '\n'
|
||||
static const int LINE_LENGTH = 76;
|
||||
|
||||
static const String _encodeTable =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static const String _encodeTableUrlSafe =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
|
||||
// Lookup table used for finding Base 64 alphabet index of a given byte.
|
||||
// -2 : Outside Base 64 alphabet.
|
||||
// -1 : '\r' or '\n'
|
||||
// 0 : = (Padding character).
|
||||
// >0 : Base 64 alphabet index of given byte.
|
||||
static const List<int> _decodeTable = const [
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63, //
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, 00, -2, -2, //
|
||||
-2, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, //
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63, //
|
||||
-2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, //
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
|
||||
];
|
||||
|
||||
static Random _rng = new Random.secure();
|
||||
|
||||
static Uint8List getRandomBytes(int count) {
|
||||
final Uint8List result = new Uint8List(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = _rng.nextInt(0xff);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static String bytesToHex(List<int> bytes) {
|
||||
var result = new StringBuffer();
|
||||
for (var part in bytes) {
|
||||
result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
static String bytesToBase64(List<int> bytes,
|
||||
[bool urlSafe = false, bool addLineSeparator = false]) {
|
||||
int len = bytes.length;
|
||||
if (len == 0) {
|
||||
return "";
|
||||
}
|
||||
final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable;
|
||||
// Size of 24 bit chunks.
|
||||
final int remainderLength = len.remainder(3);
|
||||
final int chunkLength = len - remainderLength;
|
||||
// Size of base output.
|
||||
int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0);
|
||||
// Add extra for line separators.
|
||||
if (addLineSeparator) {
|
||||
outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1;
|
||||
}
|
||||
List<int> out = new List<int>(outputLen);
|
||||
|
||||
// Encode 24 bit chunks.
|
||||
int j = 0, i = 0, c = 0;
|
||||
while (i < chunkLength) {
|
||||
int x = ((bytes[i++] << 16) & 0xFFFFFF) |
|
||||
((bytes[i++] << 8) & 0xFFFFFF) |
|
||||
bytes[i++];
|
||||
out[j++] = lookup.codeUnitAt(x >> 18);
|
||||
out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F);
|
||||
out[j++] = lookup.codeUnitAt((x >> 6) & 0x3F);
|
||||
out[j++] = lookup.codeUnitAt(x & 0x3f);
|
||||
// Add optional line separator for each 76 char output.
|
||||
if (addLineSeparator && ++c == 19 && j < outputLen - 2) {
|
||||
out[j++] = CR;
|
||||
out[j++] = LF;
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If input length if not a multiple of 3, encode remaining bytes and
|
||||
// add padding.
|
||||
if (remainderLength == 1) {
|
||||
int x = bytes[i];
|
||||
out[j++] = lookup.codeUnitAt(x >> 2);
|
||||
out[j++] = lookup.codeUnitAt((x << 4) & 0x3F);
|
||||
out[j++] = PAD;
|
||||
out[j++] = PAD;
|
||||
} else if (remainderLength == 2) {
|
||||
int x = bytes[i];
|
||||
int y = bytes[i + 1];
|
||||
out[j++] = lookup.codeUnitAt(x >> 2);
|
||||
out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F);
|
||||
out[j++] = lookup.codeUnitAt((y << 2) & 0x3F);
|
||||
out[j++] = PAD;
|
||||
}
|
||||
|
||||
return new String.fromCharCodes(out);
|
||||
}
|
||||
|
||||
static List<int> base64StringToBytes(String input,
|
||||
[bool ignoreInvalidCharacters = true]) {
|
||||
int len = input.length;
|
||||
if (len == 0) {
|
||||
return new List<int>(0);
|
||||
}
|
||||
|
||||
// Count '\r', '\n' and illegal characters, For illegal characters,
|
||||
// if [ignoreInvalidCharacters] is false, throw an exception.
|
||||
int extrasLen = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = _decodeTable[input.codeUnitAt(i)];
|
||||
if (c < 0) {
|
||||
extrasLen++;
|
||||
if (c == -2 && !ignoreInvalidCharacters) {
|
||||
throw new FormatException('Invalid character: ${input[i]}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((len - extrasLen) % 4 != 0) {
|
||||
throw new FormatException('''Size of Base 64 characters in Input
|
||||
must be a multiple of 4. Input: $input''');
|
||||
}
|
||||
|
||||
// Count pad characters, ignore illegal characters at the end.
|
||||
int padLength = 0;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
int currentCodeUnit = input.codeUnitAt(i);
|
||||
if (_decodeTable[currentCodeUnit] > 0) break;
|
||||
if (currentCodeUnit == PAD) padLength++;
|
||||
}
|
||||
int outputLen = (((len - extrasLen) * 6) >> 3) - padLength;
|
||||
List<int> out = new List<int>(outputLen);
|
||||
|
||||
for (int i = 0, o = 0; o < outputLen;) {
|
||||
// Accumulate 4 valid 6 bit Base 64 characters into an int.
|
||||
int x = 0;
|
||||
for (int j = 4; j > 0;) {
|
||||
int c = _decodeTable[input.codeUnitAt(i++)];
|
||||
if (c >= 0) {
|
||||
x = ((x << 6) & 0xFFFFFF) | c;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
out[o++] = x >> 16;
|
||||
if (o < outputLen) {
|
||||
out[o++] = (x >> 8) & 0xFF;
|
||||
if (o < outputLen) out[o++] = x & 0xFF;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants.
|
||||
const _MASK_8 = 0xff;
|
||||
const _MASK_32 = 0xffffffff;
|
||||
const _BITS_PER_BYTE = 8;
|
||||
const _BYTES_PER_WORD = 4;
|
||||
|
||||
// Base class encapsulating common behavior for cryptographic hash
|
||||
// functions.
|
||||
abstract class _HashBase {
|
||||
// Hasher state.
|
||||
final int _chunkSizeInWords;
|
||||
final int _digestSizeInWords;
|
||||
final bool _bigEndianWords;
|
||||
int _lengthInBytes = 0;
|
||||
List<int> _pendingData;
|
||||
List<int> _currentChunk;
|
||||
List<int> _h;
|
||||
bool _digestCalled = false;
|
||||
|
||||
_HashBase(
|
||||
this._chunkSizeInWords, this._digestSizeInWords, this._bigEndianWords)
|
||||
: _pendingData = [] {
|
||||
_currentChunk = new List(_chunkSizeInWords);
|
||||
_h = new List(_digestSizeInWords);
|
||||
}
|
||||
|
||||
// Update the hasher with more data.
|
||||
add(List<int> data) {
|
||||
if (_digestCalled) {
|
||||
throw new StateError(
|
||||
'Hash update method called after digest was retrieved');
|
||||
}
|
||||
_lengthInBytes += data.length;
|
||||
_pendingData.addAll(data);
|
||||
_iterate();
|
||||
}
|
||||
|
||||
// Finish the hash computation and return the digest string.
|
||||
List<int> close() {
|
||||
if (_digestCalled) {
|
||||
return _resultAsBytes();
|
||||
}
|
||||
_digestCalled = true;
|
||||
_finalizeData();
|
||||
_iterate();
|
||||
assert(_pendingData.length == 0);
|
||||
return _resultAsBytes();
|
||||
}
|
||||
|
||||
// Returns the block size of the hash in bytes.
|
||||
int get blockSize {
|
||||
return _chunkSizeInWords * _BYTES_PER_WORD;
|
||||
}
|
||||
|
||||
// Create a fresh instance of this Hash.
|
||||
newInstance();
|
||||
|
||||
// One round of the hash computation.
|
||||
_updateHash(List<int> m);
|
||||
|
||||
// Helper methods.
|
||||
_add32(x, y) => (x + y) & _MASK_32;
|
||||
_roundUp(val, n) => (val + n - 1) & -n;
|
||||
|
||||
// Rotate left limiting to unsigned 32-bit values.
|
||||
int _rotl32(int val, int shift) {
|
||||
var mod_shift = shift & 31;
|
||||
return ((val << mod_shift) & _MASK_32) |
|
||||
((val & _MASK_32) >> (32 - mod_shift));
|
||||
}
|
||||
|
||||
// Compute the final result as a list of bytes from the hash words.
|
||||
List<int> _resultAsBytes() {
|
||||
var result = <int>[];
|
||||
for (var i = 0; i < _h.length; i++) {
|
||||
result.addAll(_wordToBytes(_h[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Converts a list of bytes to a chunk of 32-bit words.
|
||||
_bytesToChunk(List<int> data, int dataIndex) {
|
||||
assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD));
|
||||
|
||||
for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) {
|
||||
var w3 = _bigEndianWords ? data[dataIndex] : data[dataIndex + 3];
|
||||
var w2 = _bigEndianWords ? data[dataIndex + 1] : data[dataIndex + 2];
|
||||
var w1 = _bigEndianWords ? data[dataIndex + 2] : data[dataIndex + 1];
|
||||
var w0 = _bigEndianWords ? data[dataIndex + 3] : data[dataIndex];
|
||||
dataIndex += 4;
|
||||
var word = (w3 & 0xff) << 24;
|
||||
word |= (w2 & _MASK_8) << 16;
|
||||
word |= (w1 & _MASK_8) << 8;
|
||||
word |= (w0 & _MASK_8);
|
||||
_currentChunk[wordIndex] = word;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a 32-bit word to four bytes.
|
||||
List<int> _wordToBytes(int word) {
|
||||
List<int> bytes = new List(_BYTES_PER_WORD);
|
||||
bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8;
|
||||
bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8;
|
||||
bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8;
|
||||
bytes[3] = (word >> (_bigEndianWords ? 0 : 24)) & _MASK_8;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// Iterate through data updating the hash computation for each
|
||||
// chunk.
|
||||
_iterate() {
|
||||
var len = _pendingData.length;
|
||||
var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
|
||||
if (len >= chunkSizeInBytes) {
|
||||
var index = 0;
|
||||
for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) {
|
||||
_bytesToChunk(_pendingData, index);
|
||||
_updateHash(_currentChunk);
|
||||
}
|
||||
_pendingData = _pendingData.sublist(index, len);
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize the data. Add a 1 bit to the end of the message. Expand with
|
||||
// 0 bits and add the length of the message.
|
||||
_finalizeData() {
|
||||
_pendingData.add(0x80);
|
||||
var contentsLength = _lengthInBytes + 9;
|
||||
var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
|
||||
var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes);
|
||||
var zeroPadding = finalizedLength - contentsLength;
|
||||
for (var i = 0; i < zeroPadding; i++) {
|
||||
_pendingData.add(0);
|
||||
}
|
||||
var lengthInBits = _lengthInBytes * _BITS_PER_BYTE;
|
||||
assert(lengthInBits < pow(2, 32));
|
||||
if (_bigEndianWords) {
|
||||
_pendingData.addAll(_wordToBytes(0));
|
||||
_pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
|
||||
} else {
|
||||
_pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
|
||||
_pendingData.addAll(_wordToBytes(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The MD5 hasher is used to compute an MD5 message digest.
|
||||
class _MD5 extends _HashBase {
|
||||
_MD5() : super(16, 4, false) {
|
||||
_h[0] = 0x67452301;
|
||||
_h[1] = 0xefcdab89;
|
||||
_h[2] = 0x98badcfe;
|
||||
_h[3] = 0x10325476;
|
||||
}
|
||||
|
||||
// Returns a new instance of this Hash.
|
||||
_MD5 newInstance() {
|
||||
return new _MD5();
|
||||
}
|
||||
|
||||
static const _k = const [
|
||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, //
|
||||
0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, //
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, //
|
||||
0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, //
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, //
|
||||
0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, //
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, //
|
||||
0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, //
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, //
|
||||
0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, //
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
|
||||
];
|
||||
|
||||
static const _r = const [
|
||||
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, //
|
||||
20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, //
|
||||
16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, //
|
||||
10, 15, 21, 6, 10, 15, 21
|
||||
];
|
||||
|
||||
// Compute one iteration of the MD5 algorithm with a chunk of
|
||||
// 16 32-bit pieces.
|
||||
void _updateHash(List<int> m) {
|
||||
assert(m.length == 16);
|
||||
|
||||
var a = _h[0];
|
||||
var b = _h[1];
|
||||
var c = _h[2];
|
||||
var d = _h[3];
|
||||
|
||||
var t0;
|
||||
var t1;
|
||||
|
||||
for (var i = 0; i < 64; i++) {
|
||||
if (i < 16) {
|
||||
t0 = (b & c) | ((~b & _MASK_32) & d);
|
||||
t1 = i;
|
||||
} else if (i < 32) {
|
||||
t0 = (d & b) | ((~d & _MASK_32) & c);
|
||||
t1 = ((5 * i) + 1) % 16;
|
||||
} else if (i < 48) {
|
||||
t0 = b ^ c ^ d;
|
||||
t1 = ((3 * i) + 5) % 16;
|
||||
} else {
|
||||
t0 = c ^ (b | (~d & _MASK_32));
|
||||
t1 = (7 * i) % 16;
|
||||
}
|
||||
|
||||
var temp = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = _add32(
|
||||
b, _rotl32(_add32(_add32(a, t0), _add32(_k[i], m[t1])), _r[i]));
|
||||
a = temp;
|
||||
}
|
||||
|
||||
_h[0] = _add32(a, _h[0]);
|
||||
_h[1] = _add32(b, _h[1]);
|
||||
_h[2] = _add32(c, _h[2]);
|
||||
_h[3] = _add32(d, _h[3]);
|
||||
}
|
||||
}
|
||||
|
||||
// The SHA1 hasher is used to compute an SHA1 message digest.
|
||||
class _SHA1 extends _HashBase {
|
||||
// Construct a SHA1 hasher object.
|
||||
_SHA1()
|
||||
: _w = new List(80),
|
||||
super(16, 5, true) {
|
||||
_h[0] = 0x67452301;
|
||||
_h[1] = 0xEFCDAB89;
|
||||
_h[2] = 0x98BADCFE;
|
||||
_h[3] = 0x10325476;
|
||||
_h[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
// Returns a new instance of this Hash.
|
||||
_SHA1 newInstance() {
|
||||
return new _SHA1();
|
||||
}
|
||||
|
||||
// Compute one iteration of the SHA1 algorithm with a chunk of
|
||||
// 16 32-bit pieces.
|
||||
void _updateHash(List<int> m) {
|
||||
assert(m.length == 16);
|
||||
|
||||
var a = _h[0];
|
||||
var b = _h[1];
|
||||
var c = _h[2];
|
||||
var d = _h[3];
|
||||
var e = _h[4];
|
||||
|
||||
for (var i = 0; i < 80; i++) {
|
||||
if (i < 16) {
|
||||
_w[i] = m[i];
|
||||
} else {
|
||||
var n = _w[i - 3] ^ _w[i - 8] ^ _w[i - 14] ^ _w[i - 16];
|
||||
_w[i] = _rotl32(n, 1);
|
||||
}
|
||||
var t = _add32(_add32(_rotl32(a, 5), e), _w[i]);
|
||||
if (i < 20) {
|
||||
t = _add32(_add32(t, (b & c) | (~b & d)), 0x5A827999);
|
||||
} else if (i < 40) {
|
||||
t = _add32(_add32(t, (b ^ c ^ d)), 0x6ED9EBA1);
|
||||
} else if (i < 60) {
|
||||
t = _add32(_add32(t, (b & c) | (b & d) | (c & d)), 0x8F1BBCDC);
|
||||
} else {
|
||||
t = _add32(_add32(t, b ^ c ^ d), 0xCA62C1D6);
|
||||
}
|
||||
|
||||
e = d;
|
||||
d = c;
|
||||
c = _rotl32(b, 30);
|
||||
b = a;
|
||||
a = t & _MASK_32;
|
||||
}
|
||||
|
||||
_h[0] = _add32(a, _h[0]);
|
||||
_h[1] = _add32(b, _h[1]);
|
||||
_h[2] = _add32(c, _h[2]);
|
||||
_h[3] = _add32(d, _h[3]);
|
||||
_h[4] = _add32(e, _h[4]);
|
||||
}
|
||||
|
||||
List<int> _w;
|
||||
}
|
|
@ -2,7 +2,32 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
library dart._http;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection'
|
||||
show
|
||||
HashMap,
|
||||
HashSet,
|
||||
Queue,
|
||||
ListQueue,
|
||||
LinkedList,
|
||||
LinkedListEntry,
|
||||
UnmodifiableMapView;
|
||||
import 'dart:convert';
|
||||
import 'dart:developer' hide log;
|
||||
import 'dart:math';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
part 'crypto.dart';
|
||||
part 'http_date.dart';
|
||||
part 'http_headers.dart';
|
||||
part 'http_impl.dart';
|
||||
part 'http_parser.dart';
|
||||
part 'http_session.dart';
|
||||
part 'websocket.dart';
|
||||
part 'websocket_impl.dart';
|
||||
|
||||
/**
|
||||
* HTTP status codes.
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
/**
|
||||
* Utility functions for working with dates with HTTP specific date
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
class _HttpHeaders implements HttpHeaders {
|
||||
final Map<String, List<String>> _headers;
|
|
@ -2,7 +2,124 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
int _nextServiceId = 1;
|
||||
|
||||
// TODO(ajohnsen): Use other way of getting a unique id.
|
||||
abstract class _ServiceObject {
|
||||
int __serviceId = 0;
|
||||
int get _serviceId {
|
||||
if (__serviceId == 0) __serviceId = _nextServiceId++;
|
||||
return __serviceId;
|
||||
}
|
||||
|
||||
Map _toJSON(bool ref);
|
||||
|
||||
String get _servicePath => "$_serviceTypePath/$_serviceId";
|
||||
|
||||
String get _serviceTypePath;
|
||||
|
||||
String get _serviceTypeName;
|
||||
|
||||
String _serviceType(bool ref) {
|
||||
if (ref) return "@$_serviceTypeName";
|
||||
return _serviceTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
class _CopyingBytesBuilder implements BytesBuilder {
|
||||
// Start with 1024 bytes.
|
||||
static const int _INIT_SIZE = 1024;
|
||||
|
||||
static final _emptyList = new Uint8List(0);
|
||||
|
||||
int _length = 0;
|
||||
Uint8List _buffer;
|
||||
|
||||
_CopyingBytesBuilder([int initialCapacity = 0])
|
||||
: _buffer = (initialCapacity <= 0)
|
||||
? _emptyList
|
||||
: new Uint8List(_pow2roundup(initialCapacity));
|
||||
|
||||
void add(List<int> bytes) {
|
||||
int bytesLength = bytes.length;
|
||||
if (bytesLength == 0) return;
|
||||
int required = _length + bytesLength;
|
||||
if (_buffer.length < required) {
|
||||
_grow(required);
|
||||
}
|
||||
assert(_buffer.length >= required);
|
||||
if (bytes is Uint8List) {
|
||||
_buffer.setRange(_length, required, bytes);
|
||||
} else {
|
||||
for (int i = 0; i < bytesLength; i++) {
|
||||
_buffer[_length + i] = bytes[i];
|
||||
}
|
||||
}
|
||||
_length = required;
|
||||
}
|
||||
|
||||
void addByte(int byte) {
|
||||
if (_buffer.length == _length) {
|
||||
// The grow algorithm always at least doubles.
|
||||
// If we added one to _length it would quadruple unnecessarily.
|
||||
_grow(_length);
|
||||
}
|
||||
assert(_buffer.length > _length);
|
||||
_buffer[_length] = byte;
|
||||
_length++;
|
||||
}
|
||||
|
||||
void _grow(int required) {
|
||||
// We will create a list in the range of 2-4 times larger than
|
||||
// required.
|
||||
int newSize = required * 2;
|
||||
if (newSize < _INIT_SIZE) {
|
||||
newSize = _INIT_SIZE;
|
||||
} else {
|
||||
newSize = _pow2roundup(newSize);
|
||||
}
|
||||
var newBuffer = new Uint8List(newSize);
|
||||
newBuffer.setRange(0, _buffer.length, _buffer);
|
||||
_buffer = newBuffer;
|
||||
}
|
||||
|
||||
List<int> takeBytes() {
|
||||
if (_length == 0) return _emptyList;
|
||||
var buffer = new Uint8List.view(_buffer.buffer, 0, _length);
|
||||
clear();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
List<int> toBytes() {
|
||||
if (_length == 0) return _emptyList;
|
||||
return new Uint8List.fromList(
|
||||
new Uint8List.view(_buffer.buffer, 0, _length));
|
||||
}
|
||||
|
||||
int get length => _length;
|
||||
|
||||
bool get isEmpty => _length == 0;
|
||||
|
||||
bool get isNotEmpty => _length != 0;
|
||||
|
||||
void clear() {
|
||||
_length = 0;
|
||||
_buffer = _emptyList;
|
||||
}
|
||||
|
||||
static int _pow2roundup(int x) {
|
||||
assert(x > 0);
|
||||
--x;
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
return x + 1;
|
||||
}
|
||||
}
|
||||
|
||||
const int _OUTGOING_BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
|
@ -403,6 +520,191 @@ class _HttpClientResponse extends _HttpInboundMessage
|
|||
}
|
||||
}
|
||||
|
||||
class _StreamSinkImpl<T> implements StreamSink<T> {
|
||||
final StreamConsumer<T> _target;
|
||||
final Completer _doneCompleter = new Completer();
|
||||
StreamController<T> _controllerInstance;
|
||||
Completer _controllerCompleter;
|
||||
bool _isClosed = false;
|
||||
bool _isBound = false;
|
||||
bool _hasError = false;
|
||||
|
||||
_StreamSinkImpl(this._target);
|
||||
|
||||
void _reportClosedSink() {
|
||||
stderr.writeln("StreamSink is closed and adding to it is an error.");
|
||||
stderr.writeln(" See http://dartbug.com/29554.");
|
||||
stderr.writeln(StackTrace.current);
|
||||
}
|
||||
|
||||
void add(T data) {
|
||||
if (_isClosed) {
|
||||
_reportClosedSink();
|
||||
return;
|
||||
}
|
||||
_controller.add(data);
|
||||
}
|
||||
|
||||
void addError(error, [StackTrace stackTrace]) {
|
||||
if (_isClosed) {
|
||||
_reportClosedSink();
|
||||
return;
|
||||
}
|
||||
_controller.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
Future addStream(Stream<T> stream) {
|
||||
if (_isBound) {
|
||||
throw new StateError("StreamSink is already bound to a stream");
|
||||
}
|
||||
_isBound = true;
|
||||
if (_hasError) return done;
|
||||
// Wait for any sync operations to complete.
|
||||
Future targetAddStream() {
|
||||
return _target.addStream(stream).whenComplete(() {
|
||||
_isBound = false;
|
||||
});
|
||||
}
|
||||
|
||||
if (_controllerInstance == null) return targetAddStream();
|
||||
var future = _controllerCompleter.future;
|
||||
_controllerInstance.close();
|
||||
return future.then((_) => targetAddStream());
|
||||
}
|
||||
|
||||
Future flush() {
|
||||
if (_isBound) {
|
||||
throw new StateError("StreamSink is bound to a stream");
|
||||
}
|
||||
if (_controllerInstance == null) return new Future.value(this);
|
||||
// Adding an empty stream-controller will return a future that will complete
|
||||
// when all data is done.
|
||||
_isBound = true;
|
||||
var future = _controllerCompleter.future;
|
||||
_controllerInstance.close();
|
||||
return future.whenComplete(() {
|
||||
_isBound = false;
|
||||
});
|
||||
}
|
||||
|
||||
Future close() {
|
||||
if (_isBound) {
|
||||
throw new StateError("StreamSink is bound to a stream");
|
||||
}
|
||||
if (!_isClosed) {
|
||||
_isClosed = true;
|
||||
if (_controllerInstance != null) {
|
||||
_controllerInstance.close();
|
||||
} else {
|
||||
_closeTarget();
|
||||
}
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
void _closeTarget() {
|
||||
_target.close().then(_completeDoneValue, onError: _completeDoneError);
|
||||
}
|
||||
|
||||
Future get done => _doneCompleter.future;
|
||||
|
||||
void _completeDoneValue(value) {
|
||||
if (!_doneCompleter.isCompleted) {
|
||||
_doneCompleter.complete(value);
|
||||
}
|
||||
}
|
||||
|
||||
void _completeDoneError(error, StackTrace stackTrace) {
|
||||
if (!_doneCompleter.isCompleted) {
|
||||
_hasError = true;
|
||||
_doneCompleter.completeError(error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
StreamController<T> get _controller {
|
||||
if (_isBound) {
|
||||
throw new StateError("StreamSink is bound to a stream");
|
||||
}
|
||||
if (_isClosed) {
|
||||
throw new StateError("StreamSink is closed");
|
||||
}
|
||||
if (_controllerInstance == null) {
|
||||
_controllerInstance = new StreamController<T>(sync: true);
|
||||
_controllerCompleter = new Completer();
|
||||
_target.addStream(_controller.stream).then((_) {
|
||||
if (_isBound) {
|
||||
// A new stream takes over - forward values to that stream.
|
||||
_controllerCompleter.complete(this);
|
||||
_controllerCompleter = null;
|
||||
_controllerInstance = null;
|
||||
} else {
|
||||
// No new stream, .close was called. Close _target.
|
||||
_closeTarget();
|
||||
}
|
||||
}, onError: (error, stackTrace) {
|
||||
if (_isBound) {
|
||||
// A new stream takes over - forward errors to that stream.
|
||||
_controllerCompleter.completeError(error, stackTrace);
|
||||
_controllerCompleter = null;
|
||||
_controllerInstance = null;
|
||||
} else {
|
||||
// No new stream. No need to close target, as it has already
|
||||
// failed.
|
||||
_completeDoneError(error, stackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
return _controllerInstance;
|
||||
}
|
||||
}
|
||||
|
||||
class _IOSinkImpl extends _StreamSinkImpl<List<int>> implements IOSink {
|
||||
Encoding _encoding;
|
||||
bool _encodingMutable = true;
|
||||
|
||||
_IOSinkImpl(StreamConsumer<List<int>> target, this._encoding) : super(target);
|
||||
|
||||
Encoding get encoding => _encoding;
|
||||
|
||||
void set encoding(Encoding value) {
|
||||
if (!_encodingMutable) {
|
||||
throw new StateError("IOSink encoding is not mutable");
|
||||
}
|
||||
_encoding = value;
|
||||
}
|
||||
|
||||
void write(Object obj) {
|
||||
String string = '$obj';
|
||||
if (string.isEmpty) return;
|
||||
add(_encoding.encode(string));
|
||||
}
|
||||
|
||||
void writeAll(Iterable objects, [String separator = ""]) {
|
||||
Iterator iterator = objects.iterator;
|
||||
if (!iterator.moveNext()) return;
|
||||
if (separator.isEmpty) {
|
||||
do {
|
||||
write(iterator.current);
|
||||
} while (iterator.moveNext());
|
||||
} else {
|
||||
write(iterator.current);
|
||||
while (iterator.moveNext()) {
|
||||
write(separator);
|
||||
write(iterator.current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeln([Object object = ""]) {
|
||||
write(object);
|
||||
write("\n");
|
||||
}
|
||||
|
||||
void writeCharCode(int charCode) {
|
||||
write(new String.fromCharCode(charCode));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _HttpOutboundMessage<T> extends _IOSinkImpl {
|
||||
// Used to mark when the body should be written. This is used for HEAD
|
||||
// requests and in error handling.
|
||||
|
@ -2044,11 +2346,6 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection>
|
|||
|
||||
_HttpConnection(this._socket, this._httpServer)
|
||||
: _httpParser = new _HttpParser.requestParser() {
|
||||
try {
|
||||
_socket._owner = this;
|
||||
} catch (_) {
|
||||
print(_);
|
||||
}
|
||||
_connections[_serviceId] = this;
|
||||
_httpParser.listenToStream(_socket as Object/*=Socket*/);
|
||||
_subscription = _httpParser.listen((incoming) {
|
||||
|
@ -2230,7 +2527,6 @@ class _HttpServer extends Stream<HttpRequest>
|
|||
new StreamController<HttpRequest>(sync: true, onCancel: close);
|
||||
idleTimeout = const Duration(seconds: 120);
|
||||
_servers[_serviceId] = this;
|
||||
_serverSocket._owner = this;
|
||||
}
|
||||
|
||||
_HttpServer.listenOn(this._serverSocket) : _closeServer = false {
|
||||
|
@ -2238,9 +2534,6 @@ class _HttpServer extends Stream<HttpRequest>
|
|||
new StreamController<HttpRequest>(sync: true, onCancel: close);
|
||||
idleTimeout = const Duration(seconds: 120);
|
||||
_servers[_serviceId] = this;
|
||||
try {
|
||||
_serverSocket._owner = this;
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
static HttpHeaders _initDefaultResponseHeaders() {
|
||||
|
@ -2608,10 +2901,6 @@ class _DetachedSocket extends Stream<List<int>> implements Socket {
|
|||
Map _toJSON(bool ref) {
|
||||
return (_socket as dynamic)._toJSON(ref);
|
||||
}
|
||||
|
||||
void set _owner(owner) {
|
||||
(_socket as dynamic)._owner = owner;
|
||||
}
|
||||
}
|
||||
|
||||
class _AuthenticationScheme {
|
||||
|
@ -2781,7 +3070,7 @@ class _HttpClientDigestCredentials extends _HttpClientCredentials
|
|||
hasher = new _MD5()..add(credentials.ha1.codeUnits)..add([_CharCode.COLON]);
|
||||
if (credentials.qop == "auth") {
|
||||
qop = credentials.qop;
|
||||
cnonce = _CryptoUtils.bytesToHex(_IOCrypto.getRandomBytes(4));
|
||||
cnonce = _CryptoUtils.bytesToHex(_CryptoUtils.getRandomBytes(4));
|
||||
++credentials.nonceCount;
|
||||
nc = credentials.nonceCount.toRadixString(16);
|
||||
nc = "00000000".substring(0, 8 - nc.length + 1) + nc;
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
// Global constants.
|
||||
class _Const {
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
const String _DART_SESSION_ID = "DARTSESSID";
|
||||
|
||||
|
@ -89,7 +89,7 @@ class _HttpSessionManager {
|
|||
|
||||
String createSessionId() {
|
||||
const int _KEY_LENGTH = 16; // 128 bits.
|
||||
var data = _IOCrypto.getRandomBytes(_KEY_LENGTH);
|
||||
var data = _CryptoUtils.getRandomBytes(_KEY_LENGTH);
|
||||
return _CryptoUtils.bytesToHex(data);
|
||||
}
|
||||
|
17
sdk/lib/_http/http_sources.gni
Normal file
17
sdk/lib/_http/http_sources.gni
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
||||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
http_sdk_sources = [
|
||||
"http.dart",
|
||||
|
||||
# The above file needs to be first if additional parts are added to the lib.
|
||||
"crypto.dart",
|
||||
"http_date.dart",
|
||||
"http_headers.dart",
|
||||
"http_impl.dart",
|
||||
"http_parser.dart",
|
||||
"http_session.dart",
|
||||
"websocket.dart",
|
||||
"websocket_impl.dart",
|
||||
]
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
/**
|
||||
* WebSocket status codes used when closing a WebSocket connection.
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart.io;
|
||||
part of dart._http;
|
||||
|
||||
const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
const String _clientNoContextTakeover = "client_no_context_takeover";
|
||||
|
@ -427,6 +427,23 @@ class _WebSocketTransformerImpl implements WebSocketTransformer {
|
|||
return _controller.stream;
|
||||
}
|
||||
|
||||
static List<String> _tokenizeFieldValue(String headerValue) {
|
||||
List<String> tokens = new List<String>();
|
||||
int start = 0;
|
||||
int index = 0;
|
||||
while (index < headerValue.length) {
|
||||
if (headerValue[index] == ",") {
|
||||
tokens.add(headerValue.substring(start, index));
|
||||
start = index + 1;
|
||||
} else if (headerValue[index] == " " || headerValue[index] == "\t") {
|
||||
start++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
tokens.add(headerValue.substring(start, index));
|
||||
return tokens;
|
||||
}
|
||||
|
||||
static Future<WebSocket> _upgrade(HttpRequest request,
|
||||
_ProtocolSelector _protocolSelector, CompressionOptions compression) {
|
||||
var response = request.response;
|
||||
|
@ -467,7 +484,7 @@ class _WebSocketTransformerImpl implements WebSocketTransformer {
|
|||
// The suggested protocols can be spread over multiple lines, each
|
||||
// consisting of multiple protocols. To unify all of them, first join
|
||||
// the lists with ', ' and then tokenize.
|
||||
protocols = _HttpParser._tokenizeFieldValue(protocols.join(', '));
|
||||
protocols = _tokenizeFieldValue(protocols.join(', '));
|
||||
return new Future<String>(() => _protocolSelector(protocols))
|
||||
.then<String>((protocol) {
|
||||
if (protocols.indexOf(protocol) < 0) {
|
||||
|
@ -551,8 +568,8 @@ class _WebSocketPerMessageDeflate {
|
|||
int serverMaxWindowBits;
|
||||
bool serverSide;
|
||||
|
||||
_Filter decoder;
|
||||
_Filter encoder;
|
||||
RawZLibFilter decoder;
|
||||
RawZLibFilter encoder;
|
||||
|
||||
_WebSocketPerMessageDeflate(
|
||||
{this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
|
||||
|
@ -563,21 +580,17 @@ class _WebSocketPerMessageDeflate {
|
|||
|
||||
void _ensureDecoder() {
|
||||
if (decoder == null) {
|
||||
decoder = _Filter._newZLibInflateFilter(
|
||||
serverSide ? clientMaxWindowBits : serverMaxWindowBits, null, true);
|
||||
decoder = new RawZLibFilter.inflateFilter(
|
||||
windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits,
|
||||
raw: true);
|
||||
}
|
||||
}
|
||||
|
||||
void _ensureEncoder() {
|
||||
if (encoder == null) {
|
||||
encoder = _Filter._newZLibDeflateFilter(
|
||||
false,
|
||||
ZLibOption.DEFAULT_LEVEL,
|
||||
serverSide ? serverMaxWindowBits : clientMaxWindowBits,
|
||||
ZLibOption.DEFAULT_MEM_LEVEL,
|
||||
ZLibOption.STRATEGY_DEFAULT,
|
||||
null,
|
||||
true);
|
||||
encoder = new RawZLibFilter.deflateFilter(
|
||||
windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits,
|
||||
raw: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -765,7 +778,7 @@ class _WebSocketOutgoingTransformer
|
|||
}
|
||||
if (mask) {
|
||||
header[1] |= 1 << 7;
|
||||
var maskBytes = _IOCrypto.getRandomBytes(4);
|
||||
var maskBytes = _CryptoUtils.getRandomBytes(4);
|
||||
header.setRange(index, index + 4, maskBytes);
|
||||
index += 4;
|
||||
if (data != null) {
|
||||
|
@ -1154,9 +1167,6 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
|
|||
onResume: _subscription.resume);
|
||||
|
||||
_webSockets[_serviceId] = this;
|
||||
try {
|
||||
_socket._owner = this;
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
StreamSubscription listen(void onData(message),
|
|
@ -565,15 +565,21 @@ class _WindowsCodePageEncoder {
|
|||
}
|
||||
|
||||
@patch
|
||||
class _Filter {
|
||||
class RawZLibFilter {
|
||||
@patch
|
||||
static _Filter _newZLibDeflateFilter(bool gzip, int level, int windowBits,
|
||||
int memLevel, int strategy, List<int> dictionary, bool raw) {
|
||||
static RawZLibFilter _makeZLibDeflateFilter(
|
||||
bool gzip,
|
||||
int level,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
List<int> dictionary,
|
||||
bool raw) {
|
||||
throw new UnsupportedError("_newZLibDeflateFilter");
|
||||
}
|
||||
|
||||
@patch
|
||||
static _Filter _newZLibInflateFilter(
|
||||
static RawZLibFilter _makeZLibInflateFilter(
|
||||
int windowBits, List<int> dictionary, bool raw) {
|
||||
throw new UnsupportedError("_newZLibInflateFilter");
|
||||
}
|
||||
|
|
|
@ -77,6 +77,8 @@ const Map<String, LibraryInfo> libraries = const {
|
|||
categories: "Client",
|
||||
maturity: Maturity.WEB_STABLE,
|
||||
platforms: DART2JS_PLATFORM),
|
||||
"_http":
|
||||
const LibraryInfo("_http/http.dart", categories: "", documented: false),
|
||||
"io": const LibraryInfo("io/io.dart",
|
||||
categories: "Server",
|
||||
dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
|
||||
|
|
|
@ -26,6 +26,7 @@ core: core/core.dart
|
|||
developer: developer/developer.dart
|
||||
html: html/dart2js/html_dart2js.dart
|
||||
html_common: html/html_common/html_common_dart2js.dart
|
||||
_http: unsupported:_http/http.dart
|
||||
indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
|
||||
io: unsupported:io/io.dart
|
||||
isolate: isolate/isolate.dart
|
||||
|
|
|
@ -28,6 +28,7 @@ typed_data: typed_data/typed_data.dart
|
|||
_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
|
||||
html: unsupported:
|
||||
html_common: unsupported:
|
||||
_http: _http/http.dart
|
||||
indexed_db: unsupported:
|
||||
svg: unsupported:
|
||||
web_audio: unsupported:
|
||||
|
|
|
@ -20,6 +20,7 @@ core: core/core.dart
|
|||
developer: developer/developer.dart
|
||||
html: html/dart2js/html_dart2js.dart
|
||||
html_common: html/html_common/html_common_dart2js.dart
|
||||
_http: _http/http.dart
|
||||
indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
|
||||
io: io/io.dart
|
||||
isolate: isolate/isolate.dart
|
||||
|
|
|
@ -448,6 +448,68 @@ class ZLibDecoder extends Converter<List<int>, List<int>> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The [RawZLibFilter] class provides a low-level interface to zlib.
|
||||
*/
|
||||
abstract class RawZLibFilter {
|
||||
/**
|
||||
* Returns a a [RawZLibFilter] whose [process] and [processed] methods
|
||||
* compress data.
|
||||
*/
|
||||
factory RawZLibFilter.deflateFilter({
|
||||
bool gzip: false,
|
||||
int level: ZLibOption.DEFAULT_LEVEL,
|
||||
int windowBits: ZLibOption.DEFAULT_WINDOW_BITS,
|
||||
int memLevel: ZLibOption.DEFAULT_MEM_LEVEL,
|
||||
int strategy: ZLibOption.STRATEGY_DEFAULT,
|
||||
List<int> dictionary,
|
||||
bool raw: false,
|
||||
}) {
|
||||
return _makeZLibDeflateFilter(
|
||||
gzip, level, windowBits, memLevel, strategy, dictionary, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a a [RawZLibFilter] whose [process] and [processed] methods
|
||||
* decompress data.
|
||||
*/
|
||||
factory RawZLibFilter.inflateFilter({
|
||||
int windowBits: ZLibOption.DEFAULT_WINDOW_BITS,
|
||||
List<int> dictionary,
|
||||
bool raw: false,
|
||||
}) {
|
||||
return _makeZLibInflateFilter(windowBits, dictionary, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to process a chunk of data. A call to [process] should only be made
|
||||
* when [processed] returns [:null:].
|
||||
*/
|
||||
void process(List<int> data, int start, int end);
|
||||
|
||||
/**
|
||||
* Get a chunk of processed data. When there are no more data available,
|
||||
* [processed] will return [:null:]. Set [flush] to [:false:] for non-final
|
||||
* calls to improve performance of some filters.
|
||||
*
|
||||
* The last call to [processed] should have [end] set to [:true:]. This will
|
||||
* make sure an 'end' packet is written on the stream.
|
||||
*/
|
||||
List<int> processed({bool flush: true, bool end: false});
|
||||
|
||||
external static RawZLibFilter _makeZLibDeflateFilter(
|
||||
bool gzip,
|
||||
int level,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
List<int> dictionary,
|
||||
bool raw);
|
||||
|
||||
external static RawZLibFilter _makeZLibInflateFilter(
|
||||
int windowBits, List<int> dictionary, bool raw);
|
||||
}
|
||||
|
||||
class _BufferSink extends ByteConversionSink {
|
||||
final BytesBuilder builder = new BytesBuilder(copy: false);
|
||||
|
||||
|
@ -479,18 +541,19 @@ class _ZLibEncoderSink extends _FilterSink {
|
|||
bool raw)
|
||||
: super(
|
||||
sink,
|
||||
_Filter._newZLibDeflateFilter(
|
||||
RawZLibFilter._makeZLibDeflateFilter(
|
||||
gzip, level, windowBits, memLevel, strategy, dictionary, raw));
|
||||
}
|
||||
|
||||
class _ZLibDecoderSink extends _FilterSink {
|
||||
_ZLibDecoderSink(
|
||||
ByteConversionSink sink, int windowBits, List<int> dictionary, bool raw)
|
||||
: super(sink, _Filter._newZLibInflateFilter(windowBits, dictionary, raw));
|
||||
: super(sink,
|
||||
RawZLibFilter._makeZLibInflateFilter(windowBits, dictionary, raw));
|
||||
}
|
||||
|
||||
class _FilterSink extends ByteConversionSink {
|
||||
final _Filter _filter;
|
||||
final RawZLibFilter _filter;
|
||||
final ByteConversionSink _sink;
|
||||
bool _closed = false;
|
||||
bool _empty = true;
|
||||
|
@ -542,39 +605,6 @@ class _FilterSink extends ByteConversionSink {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper-class to handle native filters.
|
||||
*/
|
||||
abstract class _Filter {
|
||||
/**
|
||||
* Call to process a chunk of data. A call to [process] should only be made
|
||||
* when [processed] returns [:null:].
|
||||
*/
|
||||
void process(List<int> data, int start, int end);
|
||||
|
||||
/**
|
||||
* Get a chunk of processed data. When there are no more data available,
|
||||
* [processed] will return [:null:]. Set [flush] to [:false:] for non-final
|
||||
* calls to improve performance of some filters.
|
||||
*
|
||||
* The last call to [processed] should have [end] set to [:true:]. This will
|
||||
* make sure an 'end' packet is written on the stream.
|
||||
*/
|
||||
List<int> processed({bool flush: true, bool end: false});
|
||||
|
||||
external static _Filter _newZLibDeflateFilter(
|
||||
bool gzip,
|
||||
int level,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
List<int> dictionary,
|
||||
bool raw);
|
||||
|
||||
external static _Filter _newZLibInflateFilter(
|
||||
int windowBits, List<int> dictionary, bool raw);
|
||||
}
|
||||
|
||||
void _validateZLibWindowBits(int windowBits) {
|
||||
if (ZLibOption.MIN_WINDOW_BITS > windowBits ||
|
||||
ZLibOption.MAX_WINDOW_BITS < windowBits) {
|
||||
|
|
|
@ -204,6 +204,8 @@ import 'dart:math';
|
|||
import 'dart:typed_data';
|
||||
import 'dart:nativewrappers';
|
||||
|
||||
export 'dart:_http';
|
||||
|
||||
part 'bytes_builder.dart';
|
||||
part 'common.dart';
|
||||
part 'crypto.dart';
|
||||
|
@ -215,12 +217,6 @@ part 'eventhandler.dart';
|
|||
part 'file.dart';
|
||||
part 'file_impl.dart';
|
||||
part 'file_system_entity.dart';
|
||||
part 'http.dart';
|
||||
part 'http_date.dart';
|
||||
part 'http_headers.dart';
|
||||
part 'http_impl.dart';
|
||||
part 'http_parser.dart';
|
||||
part 'http_session.dart';
|
||||
part 'io_resource_info.dart';
|
||||
part 'io_sink.dart';
|
||||
part 'io_service.dart';
|
||||
|
@ -237,5 +233,3 @@ part 'socket.dart';
|
|||
part 'stdio.dart';
|
||||
part 'string_transformer.dart';
|
||||
part 'sync_socket.dart';
|
||||
part 'websocket.dart';
|
||||
part 'websocket_impl.dart';
|
||||
|
|
|
@ -17,12 +17,6 @@ io_sdk_sources = [
|
|||
"file.dart",
|
||||
"file_impl.dart",
|
||||
"file_system_entity.dart",
|
||||
"http.dart",
|
||||
"http_date.dart",
|
||||
"http_headers.dart",
|
||||
"http_impl.dart",
|
||||
"http_parser.dart",
|
||||
"http_session.dart",
|
||||
"io_resource_info.dart",
|
||||
"io_sink.dart",
|
||||
"io_service.dart",
|
||||
|
@ -39,6 +33,4 @@ io_sdk_sources = [
|
|||
"stdio.dart",
|
||||
"string_transformer.dart",
|
||||
"sync_socket.dart",
|
||||
"websocket.dart",
|
||||
"websocket_impl.dart",
|
||||
]
|
||||
|
|
|
@ -6,7 +6,7 @@ part of dart.io;
|
|||
|
||||
int _nextServiceId = 1;
|
||||
|
||||
// TODO(ajohnsen): Use other way of getting a uniq id.
|
||||
// TODO(ajohnsen): Use other way of getting a unique id.
|
||||
abstract class _ServiceObject {
|
||||
int __serviceId = 0;
|
||||
int get _serviceId {
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
],
|
||||
"uri": "mirrors/mirrors.dart"
|
||||
},
|
||||
"_http": {
|
||||
"uri": "_http/http.dart"
|
||||
},
|
||||
"io": {
|
||||
"patches": [
|
||||
"../../runtime/bin/common_patch.dart",
|
||||
|
@ -126,4 +129,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,9 @@ vm:
|
|||
- "../../runtime/lib/profiler.dart"
|
||||
- "../../runtime/lib/timeline.dart"
|
||||
|
||||
_http:
|
||||
uri: "_http/http.dart"
|
||||
|
||||
io:
|
||||
uri: "io/io.dart"
|
||||
patches:
|
||||
|
|
|
@ -34,7 +34,7 @@ var blacklist = [
|
|||
|
||||
// These prevent the test from exiting.
|
||||
'dart.io.sleep',
|
||||
'dart.io.HttpServer.HttpServer.listenOn',
|
||||
'dart._http.HttpServer.HttpServer.listenOn',
|
||||
|
||||
// These either cause the VM to segfault or throw uncatchable API errors.
|
||||
// TODO(15274): Fix them and remove from blacklist.
|
||||
|
|
|
@ -34,7 +34,7 @@ var blacklist = [
|
|||
|
||||
// These prevent the test from exiting.
|
||||
'dart.io.sleep',
|
||||
'dart.io.HttpServer.HttpServer.listenOn',
|
||||
'dart._http.HttpServer.HttpServer.listenOn',
|
||||
|
||||
// These either cause the VM to segfault or throw uncatchable API errors.
|
||||
// TODO(15274): Fix them and remove from blacklist.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library dart.io;
|
||||
library dart.http;
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:async";
|
||||
|
@ -10,35 +10,16 @@ import "dart:collection";
|
|||
import "dart:convert";
|
||||
import "dart:developer";
|
||||
import "dart:math";
|
||||
import "dart:io";
|
||||
import "dart:typed_data";
|
||||
import "dart:isolate";
|
||||
|
||||
part "../../../sdk/lib/io/bytes_builder.dart";
|
||||
part "../../../sdk/lib/io/common.dart";
|
||||
part "../../../sdk/lib/io/crypto.dart";
|
||||
part "../../../sdk/lib/io/data_transformer.dart";
|
||||
part "../../../sdk/lib/io/directory.dart";
|
||||
part "../../../sdk/lib/io/directory_impl.dart";
|
||||
part "../../../sdk/lib/io/file.dart";
|
||||
part "../../../sdk/lib/io/file_impl.dart";
|
||||
part "../../../sdk/lib/io/file_system_entity.dart";
|
||||
part "../../../sdk/lib/io/link.dart";
|
||||
part "../../../sdk/lib/io/http.dart";
|
||||
part "../../../sdk/lib/io/http_impl.dart";
|
||||
part "../../../sdk/lib/io/http_date.dart";
|
||||
part "../../../sdk/lib/io/http_parser.dart";
|
||||
part "../../../sdk/lib/io/http_headers.dart";
|
||||
part "../../../sdk/lib/io/http_session.dart";
|
||||
part "../../../sdk/lib/io/io_resource_info.dart";
|
||||
part "../../../sdk/lib/io/io_service.dart";
|
||||
part "../../../sdk/lib/io/io_sink.dart";
|
||||
part "../../../sdk/lib/io/platform.dart";
|
||||
part "../../../sdk/lib/io/platform_impl.dart";
|
||||
part "../../../sdk/lib/io/service_object.dart";
|
||||
part "../../../sdk/lib/io/secure_socket.dart";
|
||||
part "../../../sdk/lib/io/secure_server_socket.dart";
|
||||
part "../../../sdk/lib/io/security_context.dart";
|
||||
part "../../../sdk/lib/io/socket.dart";
|
||||
part "../../../sdk/lib/_http/crypto.dart";
|
||||
part "../../../sdk/lib/_http/http_impl.dart";
|
||||
part "../../../sdk/lib/_http/http_date.dart";
|
||||
part "../../../sdk/lib/_http/http_parser.dart";
|
||||
part "../../../sdk/lib/_http/http_headers.dart";
|
||||
part "../../../sdk/lib/_http/http_session.dart";
|
||||
|
||||
void testParseHttpCookieDate() {
|
||||
Expect.throws(() => HttpDate._parseCookieDate(""));
|
||||
|
|
|
@ -2,43 +2,24 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library dart.io;
|
||||
library dart.http;
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:async";
|
||||
import "dart:collection";
|
||||
import "dart:convert";
|
||||
import "dart:developer";
|
||||
import "dart:io";
|
||||
import "dart:math";
|
||||
import "dart:typed_data";
|
||||
import "dart:isolate";
|
||||
|
||||
part "../../../sdk/lib/io/bytes_builder.dart";
|
||||
part "../../../sdk/lib/io/common.dart";
|
||||
part "../../../sdk/lib/io/crypto.dart";
|
||||
part "../../../sdk/lib/io/data_transformer.dart";
|
||||
part "../../../sdk/lib/io/directory.dart";
|
||||
part "../../../sdk/lib/io/directory_impl.dart";
|
||||
part "../../../sdk/lib/io/file.dart";
|
||||
part "../../../sdk/lib/io/file_impl.dart";
|
||||
part "../../../sdk/lib/io/file_system_entity.dart";
|
||||
part "../../../sdk/lib/io/link.dart";
|
||||
part "../../../sdk/lib/io/http.dart";
|
||||
part "../../../sdk/lib/io/http_impl.dart";
|
||||
part "../../../sdk/lib/io/http_date.dart";
|
||||
part "../../../sdk/lib/io/http_parser.dart";
|
||||
part "../../../sdk/lib/io/http_headers.dart";
|
||||
part "../../../sdk/lib/io/http_session.dart";
|
||||
part "../../../sdk/lib/io/io_resource_info.dart";
|
||||
part "../../../sdk/lib/io/io_service.dart";
|
||||
part "../../../sdk/lib/io/io_sink.dart";
|
||||
part "../../../sdk/lib/io/platform.dart";
|
||||
part "../../../sdk/lib/io/platform_impl.dart";
|
||||
part "../../../sdk/lib/io/service_object.dart";
|
||||
part "../../../sdk/lib/io/secure_socket.dart";
|
||||
part "../../../sdk/lib/io/secure_server_socket.dart";
|
||||
part "../../../sdk/lib/io/security_context.dart";
|
||||
part "../../../sdk/lib/io/socket.dart";
|
||||
part "../../../sdk/lib/_http/crypto.dart";
|
||||
part "../../../sdk/lib/_http/http_impl.dart";
|
||||
part "../../../sdk/lib/_http/http_date.dart";
|
||||
part "../../../sdk/lib/_http/http_parser.dart";
|
||||
part "../../../sdk/lib/_http/http_headers.dart";
|
||||
part "../../../sdk/lib/_http/http_session.dart";
|
||||
|
||||
void testMultiValue() {
|
||||
_HttpHeaders headers = new _HttpHeaders("1.1");
|
||||
|
|
|
@ -2,43 +2,24 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library dart.io;
|
||||
library dart.http;
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:async";
|
||||
import "dart:collection";
|
||||
import "dart:convert";
|
||||
import "dart:developer";
|
||||
import "dart:io";
|
||||
import "dart:math";
|
||||
import "dart:typed_data";
|
||||
import "dart:isolate";
|
||||
|
||||
part "../../../sdk/lib/io/bytes_builder.dart";
|
||||
part "../../../sdk/lib/io/common.dart";
|
||||
part "../../../sdk/lib/io/crypto.dart";
|
||||
part "../../../sdk/lib/io/data_transformer.dart";
|
||||
part "../../../sdk/lib/io/directory.dart";
|
||||
part "../../../sdk/lib/io/directory_impl.dart";
|
||||
part "../../../sdk/lib/io/file.dart";
|
||||
part "../../../sdk/lib/io/file_impl.dart";
|
||||
part "../../../sdk/lib/io/file_system_entity.dart";
|
||||
part "../../../sdk/lib/io/link.dart";
|
||||
part "../../../sdk/lib/io/http.dart";
|
||||
part "../../../sdk/lib/io/http_impl.dart";
|
||||
part "../../../sdk/lib/io/http_date.dart";
|
||||
part "../../../sdk/lib/io/http_parser.dart";
|
||||
part "../../../sdk/lib/io/http_headers.dart";
|
||||
part "../../../sdk/lib/io/http_session.dart";
|
||||
part "../../../sdk/lib/io/io_resource_info.dart";
|
||||
part "../../../sdk/lib/io/io_service.dart";
|
||||
part "../../../sdk/lib/io/io_sink.dart";
|
||||
part "../../../sdk/lib/io/platform.dart";
|
||||
part "../../../sdk/lib/io/platform_impl.dart";
|
||||
part "../../../sdk/lib/io/service_object.dart";
|
||||
part "../../../sdk/lib/io/secure_socket.dart";
|
||||
part "../../../sdk/lib/io/secure_server_socket.dart";
|
||||
part "../../../sdk/lib/io/security_context.dart";
|
||||
part "../../../sdk/lib/io/socket.dart";
|
||||
part "../../../sdk/lib/_http/crypto.dart";
|
||||
part "../../../sdk/lib/_http/http_impl.dart";
|
||||
part "../../../sdk/lib/_http/http_date.dart";
|
||||
part "../../../sdk/lib/_http/http_parser.dart";
|
||||
part "../../../sdk/lib/_http/http_headers.dart";
|
||||
part "../../../sdk/lib/_http/http_session.dart";
|
||||
|
||||
class HttpParserTest {
|
||||
static void runAllTests() {
|
||||
|
|
|
@ -10,38 +10,19 @@ import "dart:async";
|
|||
import "dart:collection";
|
||||
import "dart:convert";
|
||||
import "dart:developer";
|
||||
import "dart:io";
|
||||
import "dart:math";
|
||||
import "dart:typed_data";
|
||||
import "dart:isolate";
|
||||
|
||||
part "../../../sdk/lib/io/bytes_builder.dart";
|
||||
part "../../../sdk/lib/io/common.dart";
|
||||
part "../../../sdk/lib/io/crypto.dart";
|
||||
part "../../../sdk/lib/io/data_transformer.dart";
|
||||
part "../../../sdk/lib/io/directory.dart";
|
||||
part "../../../sdk/lib/io/directory_impl.dart";
|
||||
part "../../../sdk/lib/io/file.dart";
|
||||
part "../../../sdk/lib/io/file_impl.dart";
|
||||
part "../../../sdk/lib/io/file_system_entity.dart";
|
||||
part "../../../sdk/lib/io/link.dart";
|
||||
part "../../../sdk/lib/io/http.dart";
|
||||
part "../../../sdk/lib/io/http_impl.dart";
|
||||
part "../../../sdk/lib/io/http_date.dart";
|
||||
part "../../../sdk/lib/io/http_parser.dart";
|
||||
part "../../../sdk/lib/io/http_headers.dart";
|
||||
part "../../../sdk/lib/io/http_session.dart";
|
||||
part "../../../sdk/lib/io/io_resource_info.dart";
|
||||
part "../../../sdk/lib/io/io_service.dart";
|
||||
part "../../../sdk/lib/io/io_sink.dart";
|
||||
part "../../../sdk/lib/io/platform.dart";
|
||||
part "../../../sdk/lib/io/platform_impl.dart";
|
||||
part "../../../sdk/lib/io/service_object.dart";
|
||||
part "../../../sdk/lib/io/secure_socket.dart";
|
||||
part "../../../sdk/lib/io/secure_server_socket.dart";
|
||||
part "../../../sdk/lib/io/security_context.dart";
|
||||
part "../../../sdk/lib/io/socket.dart";
|
||||
part "../../../sdk/lib/io/websocket.dart";
|
||||
part "../../../sdk/lib/io/websocket_impl.dart";
|
||||
part "../../../sdk/lib/_http/crypto.dart";
|
||||
part "../../../sdk/lib/_http/http_impl.dart";
|
||||
part "../../../sdk/lib/_http/http_date.dart";
|
||||
part "../../../sdk/lib/_http/http_parser.dart";
|
||||
part "../../../sdk/lib/_http/http_headers.dart";
|
||||
part "../../../sdk/lib/_http/http_session.dart";
|
||||
part "../../../sdk/lib/_http/websocket.dart";
|
||||
part "../../../sdk/lib/_http/websocket_impl.dart";
|
||||
|
||||
class WebSocketFrame {
|
||||
WebSocketFrame(int opcode, List<int> data);
|
||||
|
|
Loading…
Reference in a new issue