Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(602)

Unified Diff: tool/input_sdk/lib/io/websocket.dart

Issue 1976103003: Migrate dart2js stubs for dart:io (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tool/input_sdk/lib/io/string_transformer.dart ('k') | tool/input_sdk/lib/io/websocket_impl.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tool/input_sdk/lib/io/websocket.dart
diff --git a/tool/input_sdk/lib/io/websocket.dart b/tool/input_sdk/lib/io/websocket.dart
new file mode 100644
index 0000000000000000000000000000000000000000..183714fedcce843c68425af99c0eb4bda4922254
--- /dev/null
+++ b/tool/input_sdk/lib/io/websocket.dart
@@ -0,0 +1,410 @@
+// Copyright (c) 2013, 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.io;
+
+/**
+ * WebSocket status codes used when closing a WebSocket connection.
+ */
+abstract class WebSocketStatus {
+ static const int NORMAL_CLOSURE = 1000;
+ static const int GOING_AWAY = 1001;
+ static const int PROTOCOL_ERROR = 1002;
+ static const int UNSUPPORTED_DATA = 1003;
+ static const int RESERVED_1004 = 1004;
+ static const int NO_STATUS_RECEIVED = 1005;
+ static const int ABNORMAL_CLOSURE = 1006;
+ static const int INVALID_FRAME_PAYLOAD_DATA = 1007;
+ static const int POLICY_VIOLATION = 1008;
+ static const int MESSAGE_TOO_BIG = 1009;
+ static const int MISSING_MANDATORY_EXTENSION = 1010;
+ static const int INTERNAL_SERVER_ERROR = 1011;
+ static const int RESERVED_1015 = 1015;
+}
+
+/**
+ * The [CompressionOptions] class allows you to control
+ * the options of WebSocket compression.
+ */
+class CompressionOptions {
+ /**
+ * Default WebSocket Compression options.
+ * Compression will be enabled with the following options:
+ * clientNoContextTakeover: false
+ * serverNoContextTakeover: false
+ * clientMaxWindowBits: 15
+ * serverMaxWindowBits: 15
+ */
+ static const CompressionOptions DEFAULT = const CompressionOptions();
+
+ /**
+ * Disables WebSocket Compression.
+ */
+ static const CompressionOptions OFF =
+ const CompressionOptions(enabled: false);
+
+ /**
+ * Control whether the client will reuse it's compression instances.
+ */
+ final bool clientNoContextTakeover;
+
+ /**
+ * Control whether the server will reuse it's compression instances.
+ */
+ final bool serverNoContextTakeover;
+
+ /**
+ * Sets the Max Window Bits for the Client.
+ */
+ final int clientMaxWindowBits;
+
+ /**
+ * Sets the Max Window Bits for the Server.
+ */
+ final int serverMaxWindowBits;
+
+ /**
+ * Enables or disables WebSocket compression.
+ */
+ final bool enabled;
+
+ const CompressionOptions(
+ {this.clientNoContextTakeover: false,
+ this.serverNoContextTakeover: false,
+ this.clientMaxWindowBits,
+ this.serverMaxWindowBits,
+ this.enabled: true});
+
+ /// Parses list of requested server headers to return server compression
+ /// response headers. Uses [serverMaxWindowBits] value if set, otherwise will
+ /// attempt to use value from headers. Defaults to
+ /// [WebSocket.DEFAULT_WINDOW_BITS]. Returns a [_CompressionMaxWindowBits]
+ /// object which contains the response headers and negotiated max window bits.
+ _CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) {
+ var info = new _CompressionMaxWindowBits();
+
+ int mwb;
+ String part;
+ if (requested?.parameters != null) {
+ part = requested.parameters[_serverMaxWindowBits];
+ }
+ if (part != null) {
+ if (part.length >= 2 && part.startsWith('0')) {
+ throw new ArgumentError("Illegal 0 padding on value.");
+ } else {
+ mwb = serverMaxWindowBits == null
+ ? int.parse(part,
+ onError: (source) => _WebSocketImpl.DEFAULT_WINDOW_BITS)
+ : serverMaxWindowBits;
+ info.headerValue = "; server_max_window_bits=${mwb}";
+ info.maxWindowBits = mwb;
+ }
+ } else {
+ info.headerValue = "";
+ info.maxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS;
+ }
+ return info;
+ }
+
+ /// Returns default values for client compression request headers.
+ String _createClientRequestHeader(HeaderValue requested, int size) {
+ var info = "";
+
+ // If responding to a valid request, specify size
+ if (requested != null) {
+ info = "; client_max_window_bits=$size";
+ } else {
+ // Client request. Specify default
+ if (clientMaxWindowBits == null) {
+ info = "; client_max_window_bits";
+ } else {
+ info = "; client_max_window_bits=$clientMaxWindowBits";
+ }
+ if (serverMaxWindowBits != null) {
+ info += "; server_max_window_bits=$serverMaxWindowBits";
+ }
+ }
+
+ return info;
+ }
+
+ /// Create a Compression Header. If [requested] is null or contains
+ /// client request headers, returns Client compression request headers with
+ /// default settings for `client_max_window_bits` header value.
+ /// If [requested] contains server response headers this method returns
+ /// a Server compression response header negotiating the max window bits
+ /// for both client and server as requested server_max_window_bits value.
+ /// This method returns a [_CompressionMaxWindowBits] object with the
+ /// response headers and negotiated maxWindowBits value.
+ _CompressionMaxWindowBits _createHeader([HeaderValue requested]) {
+ var info = new _CompressionMaxWindowBits("", 0);
+ if (!enabled) {
+ return info;
+ }
+
+ info.headerValue = _WebSocketImpl.PER_MESSAGE_DEFLATE;
+
+ if (clientNoContextTakeover &&
+ (requested == null || (requested != null &&
+ requested.parameters.containsKey(_clientNoContextTakeover)))) {
+ info.headerValue += "; client_no_context_takeover";
+ }
+
+ if (serverNoContextTakeover &&
+ (requested == null || (requested != null &&
+ requested.parameters.containsKey(_serverNoContextTakeover)))) {
+ info.headerValue += "; server_no_context_takeover";
+ }
+
+ var headerList = _createServerResponseHeader(requested);
+ info.headerValue += headerList.headerValue;
+ info.maxWindowBits = headerList.maxWindowBits;
+
+ info.headerValue +=
+ _createClientRequestHeader(requested, info.maxWindowBits);
+
+ return info;
+ }
+}
+
+/**
+ * The [WebSocketTransformer] provides the ability to upgrade a
+ * [HttpRequest] to a [WebSocket] connection. It supports both
+ * upgrading a single [HttpRequest] and upgrading a stream of
+ * [HttpRequest]s.
+ *
+ * To upgrade a single [HttpRequest] use the static [upgrade] method.
+ *
+ * HttpServer server;
+ * server.listen((request) {
+ * if (...) {
+ * WebSocketTransformer.upgrade(request).then((websocket) {
+ * ...
+ * });
+ * } else {
+ * // Do normal HTTP request processing.
+ * }
+ * });
+ *
+ * To transform a stream of [HttpRequest] events as it implements a
+ * stream transformer that transforms a stream of HttpRequest into a
+ * stream of WebSockets by upgrading each HttpRequest from the HTTP or
+ * HTTPS server, to the WebSocket protocol.
+ *
+ * server.transform(new WebSocketTransformer()).listen((webSocket) => ...);
+ *
+ * This transformer strives to implement WebSockets as specified by RFC6455.
+ */
+abstract class WebSocketTransformer
+ implements StreamTransformer<HttpRequest, WebSocket> {
+ /**
+ * Create a new [WebSocketTransformer].
+ *
+ * If [protocolSelector] is provided, [protocolSelector] will be called to
+ * select what protocol to use, if any were provided by the client.
+ * [protocolSelector] is should return either a [String] or a [Future]
+ * completing with a [String]. The [String] must exist in the list of
+ * protocols.
+ *
+ * If [compression] is provided, the [WebSocket] created will be configured
+ * to negotiate with the specified [CompressionOptions]. If none is specified
+ * then the [WebSocket] will be created with the default [CompressionOptions].
+ */
+ factory WebSocketTransformer(
+ {protocolSelector(List<String> protocols),
+ CompressionOptions compression: CompressionOptions.DEFAULT}) =>
+ new _WebSocketTransformerImpl(protocolSelector, compression);
+
+ /**
+ * Upgrades a [HttpRequest] to a [WebSocket] connection. If the
+ * request is not a valid WebSocket upgrade request an HTTP response
+ * with status code 500 will be returned. Otherwise the returned
+ * future will complete with the [WebSocket] when the upgrade pocess
+ * is complete.
+ *
+ * If [protocolSelector] is provided, [protocolSelector] will be called to
+ * select what protocol to use, if any were provided by the client.
+ * [protocolSelector] is should return either a [String] or a [Future]
+ * completing with a [String]. The [String] must exist in the list of
+ * protocols.
+ *
+ * If [compression] is provided, the [WebSocket] created will be configured
+ * to negotiate with the specified [CompressionOptions]. If none is specified
+ * then the [WebSocket] will be created with the default [CompressionOptions].
+ */
+ static Future<WebSocket> upgrade(HttpRequest request,
+ {protocolSelector(List<String> protocols),
+ CompressionOptions compression: CompressionOptions.DEFAULT}) {
+ return _WebSocketTransformerImpl._upgrade(
+ request, protocolSelector, compression);
+ }
+
+ /**
+ * Checks whether the request is a valid WebSocket upgrade request.
+ */
+ static bool isUpgradeRequest(HttpRequest request) {
+ return _WebSocketTransformerImpl._isUpgradeRequest(request);
+ }
+}
+
+/**
+ * A two-way HTTP communication object for client or server applications.
+ *
+ * The stream exposes the messages received. A text message will be of type
+ * [:String:] and a binary message will be of type [:List<int>:].
+ */
+abstract class WebSocket implements Stream, StreamSink {
+ /**
+ * Possible states of the connection.
+ */
+ static const int CONNECTING = 0;
+ static const int OPEN = 1;
+ static const int CLOSING = 2;
+ static const int CLOSED = 3;
+
+ /**
+ * Set and get the interval for sending ping signals. If a ping message is not
+ * answered by a pong message from the peer, the `WebSocket` is assumed
+ * disconnected and the connection is closed with a
+ * [WebSocketStatus.GOING_AWAY] close code. When a ping signal is sent, the
+ * pong message must be received within [pingInterval].
+ *
+ * There are never two outstanding pings at any given time, and the next ping
+ * timer starts when the pong is received.
+ *
+ * Set the [pingInterval] to `null` to disable sending ping messages.
+ *
+ * The default value is `null`.
+ */
+ Duration pingInterval;
+
+ /**
+ * Create a new WebSocket connection. The URL supplied in [url]
+ * must use the scheme `ws` or `wss`.
+ *
+ * The [protocols] argument is specifying the subprotocols the
+ * client is willing to speak.
+ *
+ * The [headers] argument is specifying additional HTTP headers for
+ * setting up the connection. This would typically be the `Origin`
+ * header and potentially cookies. The keys of the map are the header
+ * fields and the values are either String or List<String>.
+ *
+ * If [headers] is provided, there are a number of headers
+ * which are controlled by the WebSocket connection process. These
+ * headers are:
+ *
+ * - `connection`
+ * - `sec-websocket-key`
+ * - `sec-websocket-protocol`
+ * - `sec-websocket-version`
+ * - `upgrade`
+ *
+ * If any of these are passed in the `headers` map they will be ignored.
+ *
+ * If the `url` contains user information this will be passed as basic
+ * authentication when setting up the connection.
+ */
+ static Future<WebSocket> connect(String url,
+ {Iterable<String> protocols,
+ Map<String, dynamic> headers,
+ CompressionOptions compression: CompressionOptions.DEFAULT}) =>
+ _WebSocketImpl.connect(url, protocols, headers, compression: compression);
+
+ @Deprecated('This constructor will be removed in Dart 2.0. Use `implements`'
+ ' instead of `extends` if implementing this abstract class.')
+ WebSocket();
+
+ /**
+ * Creates a WebSocket from an already-upgraded socket.
+ *
+ * The initial WebSocket handshake must have occurred prior to this call. A
+ * WebSocket client can automatically perform the handshake using
+ * [WebSocket.connect], while a server can do so using
+ * [WebSocketTransformer.upgrade]. To manually upgrade an [HttpRequest],
+ * [HttpRequest.detachSocket] may be called.
+ *
+ * [protocol] should be the protocol negotiated by this handshake, if any.
+ *
+ * [serverSide] must be passed explicitly. If it's `false`, the WebSocket will
+ * act as the client and mask the messages it sends. If it's `true`, it will
+ * act as the server and will not mask its messages.
+ *
+ * If [compression] is provided, the [WebSocket] created will be configured
+ * to negotiate with the specified [CompressionOptions]. If none is specified
+ * then the [WebSocket] will be created with the default [CompressionOptions].
+ */
+ factory WebSocket.fromUpgradedSocket(Socket socket,
+ {String protocol,
+ bool serverSide,
+ CompressionOptions compression: CompressionOptions.DEFAULT}) {
+ if (serverSide == null) {
+ throw new ArgumentError("The serverSide argument must be passed "
+ "explicitly to WebSocket.fromUpgradedSocket.");
+ }
+ return new _WebSocketImpl._fromSocket(
+ socket, protocol, compression, serverSide);
+ }
+
+ /**
+ * Returns the current state of the connection.
+ */
+ int get readyState;
+
+ /**
+ * The extensions property is initially the empty string. After the
+ * WebSocket connection is established this string reflects the
+ * extensions used by the server.
+ */
+ String get extensions;
+
+ /**
+ * The protocol property is initially the empty string. After the
+ * WebSocket connection is established the value is the subprotocol
+ * selected by the server. If no subprotocol is negotiated the
+ * value will remain [:null:].
+ */
+ String get protocol;
+
+ /**
+ * The close code set when the WebSocket connection is closed. If
+ * there is no close code available this property will be [:null:]
+ */
+ int get closeCode;
+
+ /**
+ * The close reason set when the WebSocket connection is closed. If
+ * there is no close reason available this property will be [:null:]
+ */
+ String get closeReason;
+
+ /**
+ * Closes the WebSocket connection. Set the optional [code] and [reason]
+ * arguments to send close information to the remote peer. If they are
+ * omitted, the peer will see [WebSocketStatus.NO_STATUS_RECEIVED] code
+ * with no reason.
+ */
+ Future close([int code, String reason]);
+
+ /**
+ * Sends data on the WebSocket connection. The data in [data] must
+ * be either a [:String:], or a [:List<int>:] holding bytes.
+ */
+ void add(data);
+
+ /**
+ * Sends data from a stream on WebSocket connection. Each data event from
+ * [stream] will be send as a single WebSocket frame. The data from [stream]
+ * must be either [:String:]s, or [:List<int>:]s holding bytes.
+ */
+ Future addStream(Stream stream);
+}
+
+class WebSocketException implements IOException {
+ final String message;
+
+ const WebSocketException([this.message = ""]);
+
+ String toString() => "WebSocketException: $message";
+}
« no previous file with comments | « tool/input_sdk/lib/io/string_transformer.dart ('k') | tool/input_sdk/lib/io/websocket_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698