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:
Zachary Anderson 2017-09-21 19:21:25 +00:00 committed by Zach Anderson
parent 2d2af807f3
commit 2948f8c1b7
39 changed files with 1094 additions and 290 deletions

View file

@ -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

View file

@ -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"),

View file

@ -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");
}

View file

@ -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",

View file

@ -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.

View file

@ -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_[];

View file

@ -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}};

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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
View 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;
}

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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 {

View file

@ -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);
}

View 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",
]

View file

@ -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.

View file

@ -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),

View file

@ -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");
}

View file

@ -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"),

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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) {

View file

@ -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';

View file

@ -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",
]

View file

@ -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 {

View file

@ -85,6 +85,9 @@
],
"uri": "mirrors/mirrors.dart"
},
"_http": {
"uri": "_http/http.dart"
},
"io": {
"patches": [
"../../runtime/bin/common_patch.dart",
@ -126,4 +129,4 @@
}
}
}
}
}

View file

@ -83,6 +83,9 @@ vm:
- "../../runtime/lib/profiler.dart"
- "../../runtime/lib/timeline.dart"
_http:
uri: "_http/http.dart"
io:
uri: "io/io.dart"
patches:

View file

@ -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.

View file

@ -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.

View file

@ -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(""));

View file

@ -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");

View file

@ -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() {

View file

@ -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);