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

library http_io;

import 'dart:async';
import 'dart:collection'
    show HashMap, HashSet, Queue, ListQueue, LinkedList, LinkedListEntry;
import 'dart:convert';
import 'dart:io'
    show
        ConnectionTask,
        BytesBuilder,
        gzip,
        HandshakeException,
        InternetAddress,
        IOSink,
        Platform,
        RawSocketOption,
        SecureServerSocket,
        SecureSocket,
        SecurityContext,
        ServerSocket,
        Socket,
        SocketException,
        SocketOption,
        stderr,
        TlsException,
        X509Certificate,
        ZLibEncoder;
import 'dart:typed_data';

import 'src/char_code.dart';
import 'src/crypto.dart';
import 'src/http_exception.dart';
import 'src/http_headers_impl.dart';
import 'src/http_incoming.dart';
import 'src/http_parser.dart';
import 'src/http_session.dart';
import 'src/http_session_impl.dart';
import 'src/http_status.dart';

export 'src/http_date.dart';
export 'src/http_exception.dart';
export 'src/http_session.dart';
export 'src/http_status.dart';

part 'src/http_impl.dart';
part 'src/http_overrides.dart';

/**
 * A server that delivers content, such as web pages, using the HTTP protocol.
 *
 * The HttpServer is a [Stream] that provides [HttpRequest] objects. Each
 * HttpRequest has an associated [HttpResponse] object.
 * The server responds to a request by writing to that HttpResponse object.
 * The following example shows how to bind an HttpServer to an IPv6
 * [InternetAddress] on port 80 (the standard port for HTTP servers)
 * and how to listen for requests.
 * Port 80 is the default HTTP port. However, on most systems accessing
 * this requires super-user privileges. For local testing consider
 * using a non-reserved port (1024 and above).
 *
 *     import 'dart:io';
 *
 *     main() {
 *       HttpServer
 *           .bind(InternetAddress.anyIPv6, 80)
 *           .then((server) {
 *             server.listen((HttpRequest request) {
 *               request.response.write('Hello, world!');
 *               request.response.close();
 *             });
 *           });
 *     }
 *
 * Incomplete requests, in which all or part of the header is missing, are
 * ignored, and no exceptions or HttpRequest objects are generated for them.
 * Likewise, when writing to an HttpResponse, any [Socket] exceptions are
 * ignored and any future writes are ignored.
 *
 * The HttpRequest exposes the request headers and provides the request body,
 * if it exists, as a Stream of data. If the body is unread, it is drained
 * when the server writes to the HttpResponse or closes it.
 *
 * ## Bind with a secure HTTPS connection
 *
 * Use [bindSecure] to create an HTTPS server.
 *
 * The server presents a certificate to the client. The certificate
 * chain and the private key are set in the [SecurityContext]
 * object that is passed to [bindSecure].
 *
 *     import 'dart:io';
 *     import "dart:isolate";
 *
 *     main() {
 *       SecurityContext context = new SecurityContext();
 *       var chain =
 *           Platform.script.resolve('certificates/server_chain.pem')
 *           .toFilePath();
 *       var key =
 *           Platform.script.resolve('certificates/server_key.pem')
 *           .toFilePath();
 *       context.useCertificateChain(chain);
 *       context.usePrivateKey(key, password: 'dartdart');
 *
 *       HttpServer
 *           .bindSecure(InternetAddress.anyIPv6,
 *                       443,
 *                       context)
 *           .then((server) {
 *             server.listen((HttpRequest request) {
 *               request.response.write('Hello, world!');
 *               request.response.close();
 *             });
 *           });
 *     }
 *
 *  The certificates and keys are PEM files, which can be created and
 *  managed with the tools in OpenSSL.
 *
 * ## Connect to a server socket
 *
 * You can use the [HttpServer.listenOn] constructor to attach an HTTP server to
 * a [ServerSocket].
 *
 *     import 'dart:io';
 *
 *     main() {
 *       ServerSocket.bind(InternetAddress.anyIPv6, 80)
 *         .then((serverSocket) {
 *           HttpServer httpserver = new HttpServer.listenOn(serverSocket);
 *           serverSocket.listen((Socket socket) {
 *             socket.write('Hello, client.');
 *           });
 *         });
 *     }
 *
 * ## Other resources
 *
 * * HttpServer is a Stream. Refer to the [Stream] class for information
 * about the streaming qualities of an HttpServer.
 * Pausing the subscription of the stream, pauses at the OS level.
 *
 * * The [shelf](https://pub.dartlang.org/packages/shelf)
 * package on pub.dartlang.org contains a set of high-level classes that,
 * together with this class, makes it easy to provide content through HTTP
 * servers.
 */
abstract class HttpServer implements Stream<HttpRequest> {
  /**
   * Gets and sets the default value of the `Server` header for all responses
   * generated by this [HttpServer].
   *
   * If [serverHeader] is `null`, no `Server` header will be added to each
   * response.
   *
   * The default value is `null`.
   */
  String serverHeader;

  /**
   * Default set of headers added to all response objects.
   *
   * By default the following headers are in this set:
   *
   *     Content-Type: text/plain; charset=utf-8
   *     X-Frame-Options: SAMEORIGIN
   *     X-Content-Type-Options: nosniff
   *     X-XSS-Protection: 1; mode=block
   *
   * If the `Server` header is added here and the `serverHeader` is set as
   * well then the value of `serverHeader` takes precedence.
   */
  HttpHeaders get defaultResponseHeaders;

  /**
   * Whether the [HttpServer] should compress the content, if possible.
   *
   * The content can only be compressed when the response is using
   * chunked Transfer-Encoding and the incoming request has `gzip`
   * as an accepted encoding in the Accept-Encoding header.
   *
   * The default value is `false` (compression disabled).
   * To enable, set `autoCompress` to `true`.
   */
  bool autoCompress;

  /**
   * Gets or sets the timeout used for idle keep-alive connections. If no
   * further request is seen within [idleTimeout] after the previous request was
   * completed, the connection is dropped.
   *
   * Default is 120 seconds.
   *
   * Note that it may take up to `2 * idleTimeout` before a idle connection is
   * aborted.
   *
   * To disable, set [idleTimeout] to `null`.
   */
  Duration idleTimeout;

  /**
   * Starts listening for HTTP requests on the specified [address] and
   * [port].
   *
   * The [address] can either be a [String] or an
   * [InternetAddress]. If [address] is a [String], [bind] will
   * perform a [InternetAddress.lookup] and use the first value in the
   * list. To listen on the loopback adapter, which will allow only
   * incoming connections from the local host, use the value
   * [InternetAddress.loopbackIPv4] or
   * [InternetAddress.loopbackIPv6]. To allow for incoming
   * connection from the network use either one of the values
   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
   * bind to all interfaces or the IP address of a specific interface.
   *
   * If an IP version 6 (IPv6) address is used, both IP version 6
   * (IPv6) and version 4 (IPv4) connections will be accepted. To
   * restrict this to version 6 (IPv6) only, use [v6Only] to set
   * version 6 only. However, if the address is
   * [InternetAddress.loopbackIPv6], only IP version 6 (IPv6) connections
   * will be accepted.
   *
   * If [port] has the value [:0:] an ephemeral port will be chosen by
   * the system. The actual port used can be retrieved using the
   * [port] getter.
   *
   * The optional argument [backlog] can be used to specify the listen
   * backlog for the underlying OS listen setup. If [backlog] has the
   * value of [:0:] (the default) a reasonable value will be chosen by
   * the system.
   *
   * The optional argument [shared] specifies whether additional HttpServer
   * objects can bind to the same combination of `address`, `port` and `v6Only`.
   * If `shared` is `true` and more `HttpServer`s from this isolate or other
   * isolates are bound to the port, then the incoming connections will be
   * distributed among all the bound `HttpServer`s. Connections can be
   * distributed over multiple isolates this way.
   */
  static Future<HttpServer> bind(address, int port,
          {int backlog: 0, bool v6Only: false, bool shared: false}) =>
      _HttpServer.bind(address, port, backlog, v6Only, shared);

  /**
   * The [address] can either be a [String] or an
   * [InternetAddress]. If [address] is a [String], [bind] will
   * perform a [InternetAddress.lookup] and use the first value in the
   * list. To listen on the loopback adapter, which will allow only
   * incoming connections from the local host, use the value
   * [InternetAddress.loopbackIPv4] or
   * [InternetAddress.loopbackIPv6]. To allow for incoming
   * connection from the network use either one of the values
   * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to
   * bind to all interfaces or the IP address of a specific interface.
   *
   * If an IP version 6 (IPv6) address is used, both IP version 6
   * (IPv6) and version 4 (IPv4) connections will be accepted. To
   * restrict this to version 6 (IPv6) only, use [v6Only] to set
   * version 6 only.
   *
   * If [port] has the value [:0:] an ephemeral port will be chosen by
   * the system. The actual port used can be retrieved using the
   * [port] getter.
   *
   * The optional argument [backlog] can be used to specify the listen
   * backlog for the underlying OS listen setup. If [backlog] has the
   * value of [:0:] (the default) a reasonable value will be chosen by
   * the system.
   *
   * If [requestClientCertificate] is true, the server will
   * request clients to authenticate with a client certificate.
   * The server will advertise the names of trusted issuers of client
   * certificates, getting them from a [SecurityContext], where they have been
   * set using [SecurityContext.setClientAuthorities].
   *
   * The optional argument [shared] specifies whether additional HttpServer
   * objects can bind to the same combination of `address`, `port` and `v6Only`.
   * If `shared` is `true` and more `HttpServer`s from this isolate or other
   * isolates are bound to the port, then the incoming connections will be
   * distributed among all the bound `HttpServer`s. Connections can be
   * distributed over multiple isolates this way.
   */

  static Future<HttpServer> bindSecure(
          address, int port, SecurityContext context,
          {int backlog: 0,
          bool v6Only: false,
          bool requestClientCertificate: false,
          bool shared: false}) =>
      _HttpServer.bindSecure(address, port, context, backlog, v6Only,
          requestClientCertificate, shared);

  /**
   * Attaches the HTTP server to an existing [ServerSocket]. When the
   * [HttpServer] is closed, the [HttpServer] will just detach itself,
   * closing current connections but not closing [serverSocket].
   */
  factory HttpServer.listenOn(ServerSocket serverSocket) =>
      new _HttpServer.listenOn(serverSocket);

  /**
   * Permanently stops this [HttpServer] from listening for new
   * connections.  This closes the [Stream] of [HttpRequest]s with a
   * done event. The returned future completes when the server is
   * stopped. For a server started using [bind] or [bindSecure] this
   * means that the port listened on no longer in use.
   *
   * If [force] is `true`, active connections will be closed immediately.
   */
  Future close({bool force: false});

  /**
   * Returns the port that the server is listening on. This can be
   * used to get the actual port used when a value of 0 for [:port:] is
   * specified in the [bind] or [bindSecure] call.
   */
  int get port;

  /**
   * Returns the address that the server is listening on. This can be
   * used to get the actual address used, when the address is fetched by
   * a lookup from a hostname.
   */
  InternetAddress get address;

  /**
   * Sets the timeout, in seconds, for sessions of this [HttpServer].
   * The default timeout is 20 minutes.
   */
  set sessionTimeout(int timeout);

  /**
   * Returns an [HttpConnectionsInfo] object summarizing the number of
   * current connections handled by the server.
   */
  HttpConnectionsInfo connectionsInfo();
}

/**
 * Summary statistics about an [HttpServer]s current socket connections.
 */
class HttpConnectionsInfo {
  /**
   * Total number of socket connections.
   */
  int total = 0;

  /**
   * Number of active connections where actual request/response
   * processing is active.
   */
  int active = 0;

  /**
   * Number of idle connections held by clients as persistent connections.
   */
  int idle = 0;

  /**
   * Number of connections which are preparing to close. Note: These
   * connections are also part of the [:active:] count as they might
   * still be sending data to the client before finally closing.
   */
  int closing = 0;
}

/**
 * Headers for HTTP requests and responses.
 *
 * In some situations, headers are immutable:
 *
 * * HttpRequest and HttpClientResponse always have immutable headers.
 *
 * * HttpResponse and HttpClientRequest have immutable headers
 *   from the moment the body is written to.
 *
 * In these situations, the mutating methods throw exceptions.
 *
 * For all operations on HTTP headers the header name is
 * case-insensitive.
 *
 * To set the value of a header use the `set()` method:
 *
 *     request.headers.set(HttpHeaders.CACHE_CONTROL,
 *                         'max-age=3600, must-revalidate');
 *
 * To retrieve the value of a header use the `value()` method:
 *
 *     print(request.headers.value(HttpHeaders.USER_AGENT));
 *
 * An HttpHeaders object holds a list of values for each name
 * as the standard allows. In most cases a name holds only a single value,
 * The most common mode of operation is to use `set()` for setting a value,
 * and `value()` for retrieving a value.
 */
abstract class HttpHeaders {
  static const ACCEPT = "accept";
  static const ACCEPT_CHARSET = "accept-charset";
  static const ACCEPT_ENCODING = "accept-encoding";
  static const ACCEPT_LANGUAGE = "accept-language";
  static const ACCEPT_RANGES = "accept-ranges";
  static const AGE = "age";
  static const ALLOW = "allow";
  static const AUTHORIZATION = "authorization";
  static const CACHE_CONTROL = "cache-control";
  static const CONNECTION = "connection";
  static const CONTENT_ENCODING = "content-encoding";
  static const CONTENT_LANGUAGE = "content-language";
  static const CONTENT_LENGTH = "content-length";
  static const CONTENT_LOCATION = "content-location";
  static const CONTENT_MD5 = "content-md5";
  static const CONTENT_RANGE = "content-range";
  static const CONTENT_TYPE = "content-type";
  static const DATE = "date";
  static const ETAG = "etag";
  static const EXPECT = "expect";
  static const EXPIRES = "expires";
  static const FROM = "from";
  static const HOST = "host";
  static const IF_MATCH = "if-match";
  static const IF_MODIFIED_SINCE = "if-modified-since";
  static const IF_NONE_MATCH = "if-none-match";
  static const IF_RANGE = "if-range";
  static const IF_UNMODIFIED_SINCE = "if-unmodified-since";
  static const LAST_MODIFIED = "last-modified";
  static const LOCATION = "location";
  static const MAX_FORWARDS = "max-forwards";
  static const PRAGMA = "pragma";
  static const PROXY_AUTHENTICATE = "proxy-authenticate";
  static const PROXY_AUTHORIZATION = "proxy-authorization";
  static const RANGE = "range";
  static const REFERER = "referer";
  static const RETRY_AFTER = "retry-after";
  static const SERVER = "server";
  static const TE = "te";
  static const TRAILER = "trailer";
  static const TRANSFER_ENCODING = "transfer-encoding";
  static const UPGRADE = "upgrade";
  static const USER_AGENT = "user-agent";
  static const VARY = "vary";
  static const VIA = "via";
  static const WARNING = "warning";
  static const WWW_AUTHENTICATE = "www-authenticate";

  // Cookie headers from RFC 6265.
  static const COOKIE = "cookie";
  static const SET_COOKIE = "set-cookie";

  static const GENERAL_HEADERS = const [
    CACHE_CONTROL,
    CONNECTION,
    DATE,
    PRAGMA,
    TRAILER,
    TRANSFER_ENCODING,
    UPGRADE,
    VIA,
    WARNING
  ];

  static const ENTITY_HEADERS = const [
    ALLOW,
    CONTENT_ENCODING,
    CONTENT_LANGUAGE,
    CONTENT_LENGTH,
    CONTENT_LOCATION,
    CONTENT_MD5,
    CONTENT_RANGE,
    CONTENT_TYPE,
    EXPIRES,
    LAST_MODIFIED
  ];

  static const RESPONSE_HEADERS = const [
    ACCEPT_RANGES,
    AGE,
    ETAG,
    LOCATION,
    PROXY_AUTHENTICATE,
    RETRY_AFTER,
    SERVER,
    VARY,
    WWW_AUTHENTICATE
  ];

  static const REQUEST_HEADERS = const [
    ACCEPT,
    ACCEPT_CHARSET,
    ACCEPT_ENCODING,
    ACCEPT_LANGUAGE,
    AUTHORIZATION,
    EXPECT,
    FROM,
    HOST,
    IF_MATCH,
    IF_MODIFIED_SINCE,
    IF_NONE_MATCH,
    IF_RANGE,
    IF_UNMODIFIED_SINCE,
    MAX_FORWARDS,
    PROXY_AUTHORIZATION,
    RANGE,
    REFERER,
    TE,
    USER_AGENT
  ];

  /**
   * Gets and sets the date. The value of this property will
   * reflect the 'date' header.
   */
  DateTime date;

  /**
   * Gets and sets the expiry date. The value of this property will
   * reflect the 'expires' header.
   */
  DateTime expires;

  /**
   * Gets and sets the "if-modified-since" date. The value of this property will
   * reflect the "if-modified-since" header.
   */
  DateTime ifModifiedSince;

  /**
   * Gets and sets the host part of the 'host' header for the
   * connection.
   */
  String host;

  /**
   * Gets and sets the port part of the 'host' header for the
   * connection.
   */
  int port;

  /**
   * Gets the protocol version for the connection.
   */
  String get protocolVersion;

  /**
   * Gets and sets the content type. Note that the content type in the
   * header will only be updated if this field is set
   * directly. Mutating the returned current value will have no
   * effect.
   */
  ContentType contentType;

  /**
   * Gets and sets the content length header value.
   */
  int contentLength;

  /**
   * Gets and sets the persistent connection header value.
   */
  bool persistentConnection;

  /**
   * Gets and sets the chunked transfer encoding header value.
   */
  bool chunkedTransferEncoding;

  /**
   * Returns the list of values for the header named [name]. If there
   * is no header with the provided name, [:null:] will be returned.
   */
  List<String> operator [](String name);

  /**
   * Convenience method for the value for a single valued header. If
   * there is no header with the provided name, [:null:] will be
   * returned. If the header has more than one value an exception is
   * thrown.
   */
  String value(String name);

  /**
   * Adds a header value. The header named [name] will have the value
   * [value] added to its list of values. Some headers are single
   * valued, and for these adding a value will replace the previous
   * value. If the value is of type DateTime a HTTP date format will be
   * applied. If the value is a [:List:] each element of the list will
   * be added separately. For all other types the default [:toString:]
   * method will be used.
   */
  void add(String name, Object value);

  /**
   * Sets a header. The header named [name] will have all its values
   * cleared before the value [value] is added as its value.
   */
  void set(String name, Object value);

  /**
   * Removes a specific value for a header name. Some headers have
   * system supplied values and for these the system supplied values
   * will still be added to the collection of values for the header.
   */
  void remove(String name, Object value);

  /**
   * Removes all values for the specified header name. Some headers
   * have system supplied values and for these the system supplied
   * values will still be added to the collection of values for the
   * header.
   */
  void removeAll(String name);

  /**
   * Enumerates the headers, applying the function [f] to each
   * header. The header name passed in [:name:] will be all lower
   * case.
   */
  void forEach(void f(String name, List<String> values));

  /**
   * Disables folding for the header named [name] when sending the HTTP
   * header. By default, multiple header values are folded into a
   * single header line by separating the values with commas. The
   * 'set-cookie' header has folding disabled by default.
   */
  void noFolding(String name);

  /**
   * Remove all headers. Some headers have system supplied values and
   * for these the system supplied values will still be added to the
   * collection of values for the header.
   */
  void clear();
}

/**
 * Representation of a header value in the form:
 *
 *   [:value; parameter1=value1; parameter2=value2:]
 *
 * [HeaderValue] can be used to conveniently build and parse header
 * values on this form.
 *
 * To build an [:accepts:] header with the value
 *
 *     text/plain; q=0.3, text/html
 *
 * use code like this:
 *
 *     HttpClientRequest request = ...;
 *     var v = new HeaderValue("text/plain", {"q": "0.3"});
 *     request.headers.add(HttpHeaders.ACCEPT, v);
 *     request.headers.add(HttpHeaders.ACCEPT, "text/html");
 *
 * To parse the header values use the [:parse:] static method.
 *
 *     HttpRequest request = ...;
 *     List<String> values = request.headers[HttpHeaders.ACCEPT];
 *     values.forEach((value) {
 *       HeaderValue v = HeaderValue.parse(value);
 *       // Use v.value and v.parameters
 *     });
 *
 * An instance of [HeaderValue] is immutable.
 */
abstract class HeaderValue {
  /**
   * Creates a new header value object setting the value and parameters.
   */
  factory HeaderValue([String value = "", Map<String, String> parameters]) {
    return new HeaderValueImpl(value, parameters);
  }

  /**
   * Creates a new header value object from parsing a header value
   * string with both value and optional parameters.
   */
  static HeaderValue parse(String value,
      {String parameterSeparator: ";",
      String valueSeparator,
      bool preserveBackslash: false}) {
    return HeaderValueImpl.parse(value,
        parameterSeparator: parameterSeparator,
        valueSeparator: valueSeparator,
        preserveBackslash: preserveBackslash);
  }

  /**
   * Gets the header value.
   */
  String get value;

  /**
   * Gets the map of parameters.
   *
   * This map cannot be modified. Invoking any operation which would
   * modify the map will throw [UnsupportedError].
   */
  Map<String, String> get parameters;

  /**
   * Returns the formatted string representation in the form:
   *
   *     value; parameter1=value1; parameter2=value2
   */
  String toString();
}

/**
 * Representation of a content type. An instance of [ContentType] is
 * immutable.
 */
abstract class ContentType implements HeaderValue {
  /**
   * Content type for plain text using UTF-8 encoding.
   *
   *     text/plain; charset=utf-8
   */
  static final TEXT = new ContentType("text", "plain", charset: "utf-8");

  /**
   *  Content type for HTML using UTF-8 encoding.
   *
   *     text/html; charset=utf-8
   */
  static final HTML = new ContentType("text", "html", charset: "utf-8");

  /**
   *  Content type for JSON using UTF-8 encoding.
   *
   *     application/json; charset=utf-8
   */
  static final JSON = new ContentType("application", "json", charset: "utf-8");

  /**
   *  Content type for binary data.
   *
   *     application/octet-stream
   */
  static final BINARY = new ContentType("application", "octet-stream");

  /**
   * Creates a new content type object setting the primary type and
   * sub type. The charset and additional parameters can also be set
   * using [charset] and [parameters]. If charset is passed and
   * [parameters] contains charset as well the passed [charset] will
   * override the value in parameters. Keys passed in parameters will be
   * converted to lower case. The `charset` entry, whether passed as `charset`
   * or in `parameters`, will have its value converted to lower-case.
   */
  factory ContentType(String primaryType, String subType,
      {String charset, Map<String, String> parameters}) {
    return new ContentTypeImpl(primaryType, subType, charset, parameters);
  }

  /**
   * Creates a new content type object from parsing a Content-Type
   * header value. As primary type, sub type and parameter names and
   * values are not case sensitive all these values will be converted
   * to lower case. Parsing this string
   *
   *     text/html; charset=utf-8
   *
   * will create a content type object with primary type [:text:], sub
   * type [:html:] and parameter [:charset:] with value [:utf-8:].
   */
  static ContentType parse(String value) {
    return ContentTypeImpl.parse(value);
  }

  /**
   * Gets the mime-type, without any parameters.
   */
  String get mimeType;

  /**
   * Gets the primary type.
   */
  String get primaryType;

  /**
   * Gets the sub type.
   */
  String get subType;

  /**
   * Gets the character set.
   */
  String get charset;
}

/**
 * Representation of a cookie. For cookies received by the server as
 * Cookie header values only [:name:] and [:value:] fields will be
 * set. When building a cookie for the 'set-cookie' header in the server
 * and when receiving cookies in the client as 'set-cookie' headers all
 * fields can be used.
 */
abstract class Cookie {
  /**
   * Gets and sets the name.
   */
  String name;

  /**
   * Gets and sets the value.
   */
  String value;

  /**
   * Gets and sets the expiry date.
   */
  DateTime expires;

  /**
   * Gets and sets the max age. A value of [:0:] means delete cookie
   * now.
   */
  int maxAge;

  /**
   * Gets and sets the domain.
   */
  String domain;

  /**
   * Gets and sets the path.
   */
  String path;

  /**
   * Gets and sets whether this cookie is secure.
   */
  bool secure;

  /**
   * Gets and sets whether this cookie is HTTP only.
   */
  bool httpOnly;

  /**
   * Creates a new cookie optionally setting the name and value.
   *
   * By default the value of `httpOnly` will be set to `true`.
   */
  factory Cookie([String name, String value]) => new CookieImpl(name, value);

  /**
   * Creates a new cookie by parsing a header value from a 'set-cookie'
   * header.
   */
  factory Cookie.fromSetCookieValue(String value) {
    return new CookieImpl.fromSetCookieValue(value);
  }

  /**
   * Returns the formatted string representation of the cookie. The
   * string representation can be used for for setting the Cookie or
   * 'set-cookie' headers
   */
  String toString();
}

/**
 * A server-side object
 * that contains the content of and information about an HTTP request.
 *
 * __Note__: Check out the
 * [http_server](http://pub.dartlang.org/packages/http_server)
 * package, which makes working with the low-level
 * dart:io HTTP server subsystem easier.
 *
 * `HttpRequest` objects are generated by an [HttpServer],
 * which listens for HTTP requests on a specific host and port.
 * For each request received, the HttpServer, which is a [Stream],
 * generates an `HttpRequest` object and adds it to the stream.
 *
 * An `HttpRequest` object delivers the body content of the request
 * as a stream of byte lists.
 * The object also contains information about the request,
 * such as the method, URI, and headers.
 *
 * In the following code, an HttpServer listens
 * for HTTP requests. When the server receives a request,
 * it uses the HttpRequest object's `method` property to dispatch requests.
 *
 *     final HOST = InternetAddress.loopbackIPv4;
 *     final PORT = 80;
 *
 *     HttpServer.bind(HOST, PORT).then((_server) {
 *       _server.listen((HttpRequest request) {
 *         switch (request.method) {
 *           case 'GET':
 *             handleGetRequest(request);
 *             break;
 *           case 'POST':
 *             ...
 *         }
 *       },
 *       onError: handleError);    // listen() failed.
 *     }).catchError(handleError);
 *
 * An HttpRequest object provides access to the associated [HttpResponse]
 * object through the response property.
 * The server writes its response to the body of the HttpResponse object.
 * For example, here's a function that responds to a request:
 *
 *     void handleGetRequest(HttpRequest req) {
 *       HttpResponse res = req.response;
 *       res.write('Received request ${req.method}: ${req.uri.path}');
 *       res.close();
 *     }
 */
abstract class HttpRequest implements Stream<List<int>> {
  /**
   * The content length of the request body.
   *
   * If the size of the request body is not known in advance,
   * this value is -1.
   */
  int get contentLength;

  /**
   * The method, such as 'GET' or 'POST', for the request.
   */
  String get method;

  /**
   * The URI for the request.
   *
   * This provides access to the
   * path and query string for the request.
   */
  Uri get uri;

  /**
   * The requested URI for the request.
   *
   * The returned URI is reconstructed by using http-header fields, to access
   * otherwise lost information, e.g. host and scheme.
   *
   * To reconstruct the scheme, first 'X-Forwarded-Proto' is checked, and then
   * falling back to server type.
   *
   * To reconstruct the host, first 'X-Forwarded-Host' is checked, then 'Host'
   * and finally calling back to server.
   */
  Uri get requestedUri;

  /**
   * The request headers.
   *
   * The returned [HttpHeaders] are immutable.
   */
  HttpHeaders get headers;

  /**
   * The cookies in the request, from the Cookie headers.
   */
  List<Cookie> get cookies;

  /**
   * The persistent connection state signaled by the client.
   */
  bool get persistentConnection;

  /**
   * The client certificate of the client making the request.
   *
   * This value is null if the connection is not a secure TLS or SSL connection,
   * or if the server does not request a client certificate, or if the client
   * does not provide one.
   */
  X509Certificate get certificate;

  /**
   * The session for the given request.
   *
   * If the session is
   * being initialized by this call, [:isNew:] is true for the returned
   * session.
   * See [HttpServer.sessionTimeout] on how to change default timeout.
   */
  HttpSession get session;

  /**
   * The HTTP protocol version used in the request,
   * either "1.0" or "1.1".
   */
  String get protocolVersion;

  /**
   * Information about the client connection.
   *
   * Returns [:null:] if the socket is not available.
   */
  HttpConnectionInfo get connectionInfo;

  /**
   * The [HttpResponse] object, used for sending back the response to the
   * client.
   *
   * If the [contentLength] of the body isn't 0, and the body isn't being read,
   * any write calls on the [HttpResponse] automatically drain the request
   * body.
   */
  HttpResponse get response;
}

/**
 * An HTTP response, which returns the headers and data
 * from the server to the client in response to an HTTP request.
 *
 * Every HttpRequest object provides access to the associated [HttpResponse]
 * object through the `response` property.
 * The server sends its response to the client by writing to the
 * HttpResponse object.
 *
 * ## Writing the response
 *
 * This class implements [IOSink].
 * After the header has been set up, the methods
 * from IOSink, such as `writeln()`, can be used to write
 * the body of the HTTP response.
 * Use the `close()` method to close the response and send it to the client.
 *
 *     server.listen((HttpRequest request) {
 *       request.response.write('Hello, world!');
 *       request.response.close();
 *     });
 *
 * When one of the IOSink methods is used for the
 * first time, the request header is sent. Calling any methods that
 * change the header after it is sent throws an exception.
 *
 * ## Setting the headers
 *
 * The HttpResponse object has a number of properties for setting up
 * the HTTP headers of the response.
 * When writing string data through the IOSink, the encoding used
 * is determined from the "charset" parameter of the
 * "Content-Type" header.
 *
 *     HttpResponse response = ...
 *     response.headers.contentType
 *         = new ContentType("application", "json", charset: "utf-8");
 *     response.write(...);  // Strings written will be UTF-8 encoded.
 *
 * If no charset is provided the default of ISO-8859-1 (Latin 1) will
 * be used.
 *
 *     HttpResponse response = ...
 *     response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
 *     response.write(...);  // Strings written will be ISO-8859-1 encoded.
 *
 * An exception is thrown if you use the `write()` method
 * while an unsupported content-type is set.
 */
abstract class HttpResponse implements IOSink {
  // TODO(ajohnsen): Add documentation of how to pipe a file to the response.
  /**
   * Gets and sets the content length of the response. If the size of
   * the response is not known in advance set the content length to
   * -1 - which is also the default if not set.
   */
  int contentLength;

  /**
   * Gets and sets the status code. Any integer value is accepted. For
   * the official HTTP status codes use the fields from
   * [HttpStatus]. If no status code is explicitly set the default
   * value [HttpStatus.OK] is used.
   *
   * The status code must be set before the body is written
   * to. Setting the status code after writing to the response body or
   * closing the response will throw a `StateError`.
   */
  int statusCode;

  /**
   * Gets and sets the reason phrase. If no reason phrase is explicitly
   * set a default reason phrase is provided.
   *
   * The reason phrase must be set before the body is written
   * to. Setting the reason phrase after writing to the response body
   * or closing the response will throw a `StateError`.
   */
  String reasonPhrase;

  /**
   * Gets and sets the persistent connection state. The initial value
   * of this property is the persistent connection state from the
   * request.
   */
  bool persistentConnection;

  /**
   * Set and get the [deadline] for the response. The deadline is timed from the
   * time it's set. Setting a new deadline will override any previous deadline.
   * When a deadline is exceeded, the response will be closed and any further
   * data ignored.
   *
   * To disable a deadline, set the [deadline] to `null`.
   *
   * The [deadline] is `null` by default.
   */
  Duration deadline;

  /**
   * Gets or sets if the [HttpResponse] should buffer output.
   *
   * Default value is `true`.
   *
   * __Note__: Disabling buffering of the output can result in very poor
   * performance, when writing many small chunks.
   */
  bool bufferOutput;

  /**
   * Returns the response headers.
   *
   * The response headers can be modified until the response body is
   * written to or closed. After that they become immutable.
   */
  HttpHeaders get headers;

  /**
   * Cookies to set in the client (in the 'set-cookie' header).
   */
  List<Cookie> get cookies;

  /**
   * Respond with a redirect to [location].
   *
   * The URI in [location] should be absolute, but there are no checks
   * to enforce that.
   *
   * By default the HTTP status code `HttpStatus.MOVED_TEMPORARILY`
   * (`302`) is used for the redirect, but an alternative one can be
   * specified using the [status] argument.
   *
   * This method will also call `close`, and the returned future is
   * the future returned by `close`.
   */
  Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY});

  /**
   * Detaches the underlying socket from the HTTP server. When the
   * socket is detached the HTTP server will no longer perform any
   * operations on it.
   *
   * This is normally used when a HTTP upgrade request is received
   * and the communication should continue with a different protocol.
   *
   * If [writeHeaders] is `true`, the status line and [headers] will be written
   * to the socket before it's detached. If `false`, the socket is detached
   * immediately, without any data written to the socket. Default is `true`.
   */
  Future<Socket> detachSocket({bool writeHeaders: true});

  /**
   * Gets information about the client connection. Returns [:null:] if the
   * socket is not available.
   */
  HttpConnectionInfo get connectionInfo;
}

/**
 * A client that receives content, such as web pages, from
 * a server using the HTTP protocol.
 *
 * HttpClient contains a number of methods to send an [HttpClientRequest]
 * to an Http server and receive an [HttpClientResponse] back.
 * For example, you can use the [get], [getUrl], [post], and [postUrl] methods
 * for GET and POST requests, respectively.
 *
 * ## Making a simple GET request: an example
 *
 * A `getUrl` request is a two-step process, triggered by two [Future]s.
 * When the first future completes with a [HttpClientRequest], the underlying
 * network connection has been established, but no data has been sent.
 * In the callback function for the first future, the HTTP headers and body
 * can be set on the request. Either the first write to the request object
 * or a call to [close] sends the request to the server.
 *
 * When the HTTP response is received from the server,
 * the second future, which is returned by close,
 * completes with an [HttpClientResponse] object.
 * This object provides access to the headers and body of the response.
 * The body is available as a stream implemented by HttpClientResponse.
 * If a body is present, it must be read. Otherwise, it leads to resource
 * leaks. Consider using [HttpClientResponse.drain] if the body is unused.
 *
 *     HttpClient client = new HttpClient();
 *     client.getUrl(Uri.parse("http://www.example.com/"))
 *         .then((HttpClientRequest request) {
 *           // Optionally set up headers...
 *           // Optionally write to the request object...
 *           // Then call close.
 *           ...
 *           return request.close();
 *         })
 *         .then((HttpClientResponse response) {
 *           // Process the response.
 *           ...
 *         });
 *
 * The future for [HttpClientRequest] is created by methods such as
 * [getUrl] and [open].
 *
 * ## HTTPS connections
 *
 * An HttpClient can make HTTPS requests, connecting to a server using
 * the TLS (SSL) secure networking protocol. Calling [getUrl] with an
 * https: scheme will work automatically, if the server's certificate is
 * signed by a root CA (certificate authority) on the default list of
 * well-known trusted CAs, compiled by Mozilla.
 *
 * To add a custom trusted certificate authority, or to send a client
 * certificate to servers that request one, pass a [SecurityContext] object
 * as the optional `context` argument to the `HttpClient` constructor.
 * The desired security options can be set on the [SecurityContext] object.
 *
 * ## Headers
 *
 * All HttpClient requests set the following header by default:
 *
 *     Accept-Encoding: gzip
 *
 * This allows the HTTP server to use gzip compression for the body if
 * possible. If this behavior is not desired set the
 * `Accept-Encoding` header to something else.
 * To turn off gzip compression of the response, clear this header:
 *
 *      request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING)
 *
 * ## Closing the HttpClient
 *
 * The HttpClient supports persistent connections and caches network
 * connections to reuse them for multiple requests whenever
 * possible. This means that network connections can be kept open for
 * some time after a request has completed. Use HttpClient.close
 * to force the HttpClient object to shut down and to close the idle
 * network connections.
 *
 * ## Turning proxies on and off
 *
 * By default the HttpClient uses the proxy configuration available
 * from the environment, see [findProxyFromEnvironment]. To turn off
 * the use of proxies set the [findProxy] property to
 * [:null:].
 *
 *     HttpClient client = new HttpClient();
 *     client.findProxy = null;
 */
abstract class HttpClient {
  static const int DEFAULT_HTTP_PORT = 80;
  static const int DEFAULT_HTTPS_PORT = 443;

  /// Gets and sets the idle timeout of non-active persistent (keep-alive)
  /// connections.
  ///
  /// The default value is 15 seconds.
  Duration idleTimeout;

  /// Gets and sets the connection timeout.
  ///
  /// When connecting to a new host exceeds this timeout, a [SocketException]
  /// is thrown. The timeout applies only to connections initiated after the
  /// timeout is set.
  ///
  /// When this is `null`, the OS default timeout is used. The default is
  /// `null`.
  Duration connectionTimeout;

  /**
   * Gets and sets the maximum number of live connections, to a single host.
   *
   * Increasing this number may lower performance and take up unwanted
   * system resources.
   *
   * To disable, set to `null`.
   *
   * Default is `null`.
   */
  int maxConnectionsPerHost;

  /**
   * Gets and sets whether the body of a response will be automatically
   * uncompressed.
   *
   * The body of an HTTP response can be compressed. In most
   * situations providing the un-compressed body is most
   * convenient. Therefore the default behavior is to un-compress the
   * body. However in some situations (e.g. implementing a transparent
   * proxy) keeping the uncompressed stream is required.
   *
   * NOTE: Headers in the response are never modified. This means
   * that when automatic un-compression is turned on the value of the
   * header `Content-Length` will reflect the length of the original
   * compressed body. Likewise the header `Content-Encoding` will also
   * have the original value indicating compression.
   *
   * NOTE: Automatic un-compression is only performed if the
   * `Content-Encoding` header value is `gzip`.
   *
   * This value affects all responses produced by this client after the
   * value is changed.
   *
   * To disable, set to `false`.
   *
   * Default is `true`.
   */
  bool autoUncompress;

  /// Gets and sets the default value of the `User-Agent` header for all requests
  /// generated by this [HttpClient].
  ///
  /// The default value is `Dart/<version> (dart:io)`.
  ///
  /// If the userAgent is set to `null`, no default `User-Agent` header will be
  /// added to each request.
  String userAgent;

  factory HttpClient({SecurityContext context}) {
    HttpOverrides overrides = HttpOverrides.current;
    if (overrides == null) {
      return new _HttpClient(context);
    }
    return overrides.createHttpClient(context);
  }

  /**
   * Opens a HTTP connection.
   *
   * The HTTP method to use is specified in [method], the server is
   * specified using [host] and [port], and the path (including
   * a possible query) is specified using [path].
   * The path may also contain a URI fragment, which will be ignored.
   *
   * The `Host` header for the request will be set to the value
   * [host]:[port]. This can be overridden through the
   * [HttpClientRequest] interface before the request is sent.  NOTE
   * if [host] is an IP address this will still be set in the `Host`
   * header.
   *
   * For additional information on the sequence of events during an
   * HTTP transaction, and the objects returned by the futures, see
   * the overall documentation for the class [HttpClient].
   */
  Future<HttpClientRequest> open(
      String method, String host, int port, String path);

  /**
   * Opens a HTTP connection.
   *
   * The HTTP method is specified in [method] and the URL to use in
   * [url].
   *
   * The `Host` header for the request will be set to the value
   * [Uri.host]:[Uri.port] from [url]. This can be overridden through the
   * [HttpClientRequest] interface before the request is sent.  NOTE
   * if [Uri.host] is an IP address this will still be set in the `Host`
   * header.
   *
   * For additional information on the sequence of events during an
   * HTTP transaction, and the objects returned by the futures, see
   * the overall documentation for the class [HttpClient].
   */
  Future<HttpClientRequest> openUrl(String method, Uri url);

  /**
   * Opens a HTTP connection using the GET method.
   *
   * The server is specified using [host] and [port], and the path
   * (including a possible query) is specified using
   * [path].
   *
   * See [open] for details.
   */
  Future<HttpClientRequest> get(String host, int port, String path);

  /**
   * Opens a HTTP connection using the GET method.
   *
   * The URL to use is specified in [url].
   *
   * See [openUrl] for details.
   */
  Future<HttpClientRequest> getUrl(Uri url);

  /**
   * Opens a HTTP connection using the POST method.
   *
   * The server is specified using [host] and [port], and the path
   * (including a possible query) is specified using
   * [path].
   *
   * See [open] for details.
   */
  Future<HttpClientRequest> post(String host, int port, String path);

  /**
   * Opens a HTTP connection using the POST method.
   *
   * The URL to use is specified in [url].
   *
   * See [openUrl] for details.
   */
  Future<HttpClientRequest> postUrl(Uri url);

  /**
   * Opens a HTTP connection using the PUT method.
   *
   * The server is specified using [host] and [port], and the path
   * (including a possible query) is specified using [path].
   *
   * See [open] for details.
   */
  Future<HttpClientRequest> put(String host, int port, String path);

  /**
   * Opens a HTTP connection using the PUT method.
   *
   * The URL to use is specified in [url].
   *
   * See [openUrl] for details.
   */
  Future<HttpClientRequest> putUrl(Uri url);

  /**
   * Opens a HTTP connection using the DELETE method.
   *
   * The server is specified using [host] and [port], and the path
   * (including a possible query) is specified using [path].
   *
   * See [open] for details.
   */
  Future<HttpClientRequest> delete(String host, int port, String path);

  /**
   * Opens a HTTP connection using the DELETE method.
   *
   * The URL to use is specified in [url].
   *
   * See [openUrl] for details.
   */
  Future<HttpClientRequest> deleteUrl(Uri url);

  /**
   * Opens a HTTP connection using the PATCH method.
   *
   * The server is specified using [host] and [port], and the path
   * (including a possible query) is specified using [path].
   *
   * See [open] for details.
   */
  Future<HttpClientRequest> patch(String host, int port, String path);

  /**
   * Opens a HTTP connection using the PATCH method.
   *
   * The URL to use is specified in [url].
   *
   * See [openUrl] for details.
   */
  Future<HttpClientRequest> patchUrl(Uri url);

  /**
   * Opens a HTTP connection using the HEAD method.
   *
   * The server is specified using [host] and [port], and the path
   * (including a possible query) is specified using [path].
   *
   * See [open] for details.
   */
  Future<HttpClientRequest> head(String host, int port, String path);

  /**
   * Opens a HTTP connection using the HEAD method.
   *
   * The URL to use is specified in [url].
   *
   * See [openUrl] for details.
   */
  Future<HttpClientRequest> headUrl(Uri url);

  /**
   * Sets the function to be called when a site is requesting
   * authentication. The URL requested and the security realm from the
   * server are passed in the arguments `url` and `realm`.
   *
   * The function returns a [Future] which should complete when the
   * authentication has been resolved. If credentials cannot be
   * provided the [Future] should complete with [:false:]. If
   * credentials are available the function should add these using
   * [addCredentials] before completing the [Future] with the value
   * [:true:].
   *
   * If the [Future] completes with true the request will be retried
   * using the updated credentials. Otherwise response processing will
   * continue normally.
   */
  set authenticate(Future<bool> f(Uri url, String scheme, String realm));

  /**
   * Add credentials to be used for authorizing HTTP requests.
   */
  void addCredentials(Uri url, String realm, HttpClientCredentials credentials);

  /**
   * Sets the function used to resolve the proxy server to be used for
   * opening a HTTP connection to the specified `url`. If this
   * function is not set, direct connections will always be used.
   *
   * The string returned by [f] must be in the format used by browser
   * PAC (proxy auto-config) scripts. That is either
   *
   *     "DIRECT"
   *
   * for using a direct connection or
   *
   *     "PROXY host:port"
   *
   * for using the proxy server [:host:] on port [:port:].
   *
   * A configuration can contain several configuration elements
   * separated by semicolons, e.g.
   *
   *     "PROXY host:port; PROXY host2:port2; DIRECT"
   *
   * The static function [findProxyFromEnvironment] on this class can
   * be used to implement proxy server resolving based on environment
   * variables.
   */
  set findProxy(String f(Uri url));

  /**
   * Function for resolving the proxy server to be used for a HTTP
   * connection from the proxy configuration specified through
   * environment variables.
   *
   * The following environment variables are taken into account:
   *
   *     http_proxy
   *     https_proxy
   *     no_proxy
   *     HTTP_PROXY
   *     HTTPS_PROXY
   *     NO_PROXY
   *
   * [:http_proxy:] and [:HTTP_PROXY:] specify the proxy server to use for
   * http:// urls. Use the format [:hostname:port:]. If no port is used a
   * default of 1080 will be used. If both are set the lower case one takes
   * precedence.
   *
   * [:https_proxy:] and [:HTTPS_PROXY:] specify the proxy server to use for
   * https:// urls. Use the format [:hostname:port:]. If no port is used a
   * default of 1080 will be used. If both are set the lower case one takes
   * precedence.
   *
   * [:no_proxy:] and [:NO_PROXY:] specify a comma separated list of
   * postfixes of hostnames for which not to use the proxy
   * server. E.g. the value "localhost,127.0.0.1" will make requests
   * to both "localhost" and "127.0.0.1" not use a proxy. If both are set
   * the lower case one takes precedence.
   *
   * To activate this way of resolving proxies assign this function to
   * the [findProxy] property on the [HttpClient].
   *
   *     HttpClient client = new HttpClient();
   *     client.findProxy = HttpClient.findProxyFromEnvironment;
   *
   * If you don't want to use the system environment you can use a
   * different one by wrapping the function.
   *
   *     HttpClient client = new HttpClient();
   *     client.findProxy = (url) {
   *       return HttpClient.findProxyFromEnvironment(
   *           url, environment: {"http_proxy": ..., "no_proxy": ...});
   *     }
   *
   * If a proxy requires authentication it is possible to configure
   * the username and password as well. Use the format
   * [:username:password@hostname:port:] to include the username and
   * password. Alternatively the API [addProxyCredentials] can be used
   * to set credentials for proxies which require authentication.
   */
  static String findProxyFromEnvironment(Uri url,
      {Map<String, String> environment}) {
    HttpOverrides overrides = HttpOverrides.current;
    if (overrides == null) {
      return _HttpClient._findProxyFromEnvironment(url, environment);
    }
    return overrides.findProxyFromEnvironment(url, environment);
  }

  /**
   * Sets the function to be called when a proxy is requesting
   * authentication. Information on the proxy in use and the security
   * realm for the authentication are passed in the arguments `host`,
   * `port` and `realm`.
   *
   * The function returns a [Future] which should complete when the
   * authentication has been resolved. If credentials cannot be
   * provided the [Future] should complete with [:false:]. If
   * credentials are available the function should add these using
   * [addProxyCredentials] before completing the [Future] with the value
   * [:true:].
   *
   * If the [Future] completes with [:true:] the request will be retried
   * using the updated credentials. Otherwise response processing will
   * continue normally.
   */
  set authenticateProxy(
      Future<bool> f(String host, int port, String scheme, String realm));

  /**
   * Add credentials to be used for authorizing HTTP proxies.
   */
  void addProxyCredentials(
      String host, int port, String realm, HttpClientCredentials credentials);

  /**
   * Sets a callback that will decide whether to accept a secure connection
   * with a server certificate that cannot be authenticated by any of our
   * trusted root certificates.
   *
   * When an secure HTTP request if made, using this HttpClient, and the
   * server returns a server certificate that cannot be authenticated, the
   * callback is called asynchronously with the [X509Certificate] object and
   * the server's hostname and port.  If the value of [badCertificateCallback]
   * is [:null:], the bad certificate is rejected, as if the callback
   * returned [:false:]
   *
   * If the callback returns true, the secure connection is accepted and the
   * [:Future<HttpClientRequest>:] that was returned from the call making the
   * request completes with a valid HttpRequest object. If the callback returns
   * false, the [:Future<HttpClientRequest>:] completes with an exception.
   *
   * If a bad certificate is received on a connection attempt, the library calls
   * the function that was the value of badCertificateCallback at the time
   * the request is made, even if the value of badCertificateCallback
   * has changed since then.
   */
  set badCertificateCallback(
      bool callback(X509Certificate cert, String host, int port));

  /// Shuts down the HTTP client.
  ///
  /// If [force] is `false` (the default) the [HttpClient] will be kept alive
  /// until all active connections are done. If [force] is `true` any active
  /// connections will be closed to immediately release all resources. These
  /// closed connections will receive an error event to indicate that the client
  /// was shut down. In both cases trying to establish a new connection after
  /// calling [close] will throw an exception.
  void close({bool force: false});
}

/**
 * HTTP request for a client connection.
 *
 * To set up a request, set the headers using the headers property
 * provided in this class and write the data to the body of the request.
 * HttpClientRequest is an [IOSink]. Use the methods from IOSink,
 * such as writeCharCode(), to write the body of the HTTP
 * request. When one of the IOSink methods is used for the first
 * time, the request header is sent. Calling any methods that
 * change the header after it is sent throws an exception.
 *
 * When writing string data through the [IOSink] the
 * encoding used is determined from the "charset" parameter of
 * the "Content-Type" header.
 *
 *     HttpClientRequest request = ...
 *     request.headers.contentType
 *         = new ContentType("application", "json", charset: "utf-8");
 *     request.write(...);  // Strings written will be UTF-8 encoded.
 *
 * If no charset is provided the default of ISO-8859-1 (Latin 1) is
 * be used.
 *
 *     HttpClientRequest request = ...
 *     request.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
 *     request.write(...);  // Strings written will be ISO-8859-1 encoded.
 *
 * An exception is thrown if you use an unsupported encoding and the
 * `write()` method being used takes a string parameter.
 */
abstract class HttpClientRequest implements IOSink {
  /**
   * Gets and sets the requested persistent connection state.
   *
   * The default value is [:true:].
   */
  bool persistentConnection;

  /**
   * Set this property to [:true:] if this request should
   * automatically follow redirects. The default is [:true:].
   *
   * Automatic redirect will only happen for "GET" and "HEAD" requests
   * and only for the status codes [:HttpStatus.MOVED_PERMANENTLY:]
   * (301), [:HttpStatus.FOUND:] (302),
   * [:HttpStatus.MOVED_TEMPORARILY:] (302, alias for
   * [:HttpStatus.FOUND:]), [:HttpStatus.SEE_OTHER:] (303) and
   * [:HttpStatus.TEMPORARY_REDIRECT:] (307). For
   * [:HttpStatus.SEE_OTHER:] (303) automatic redirect will also happen
   * for "POST" requests with the method changed to "GET" when
   * following the redirect.
   *
   * All headers added to the request will be added to the redirection
   * request(s). However, any body send with the request will not be
   * part of the redirection request(s).
   */
  bool followRedirects;

  /**
   * Set this property to the maximum number of redirects to follow
   * when [followRedirects] is `true`. If this number is exceeded
   * an error event will be added with a [RedirectException].
   *
   * The default value is 5.
   */
  int maxRedirects;

  /**
   * The method of the request.
   */
  String get method;

  /**
   * The uri of the request.
   */
  Uri get uri;

  /// Gets and sets the content length of the request.
  ///
  /// If the size of the request is not known in advance set content length to
  /// -1, which is also the default.
  int contentLength;

  /**
   * Gets or sets if the [HttpClientRequest] should buffer output.
   *
   * Default value is `true`.
   *
   * __Note__: Disabling buffering of the output can result in very poor
   * performance, when writing many small chunks.
   */
  bool bufferOutput;

  /**
   * Returns the client request headers.
   *
   * The client request headers can be modified until the client
   * request body is written to or closed. After that they become
   * immutable.
   */
  HttpHeaders get headers;

  /**
   * Cookies to present to the server (in the 'cookie' header).
   */
  List<Cookie> get cookies;

  /// A [HttpClientResponse] future that will complete once the response is
  /// available.
  ///
  /// If an error occurs before the response is available, this future will
  /// complete with an error.
  Future<HttpClientResponse> get done;

  /**
   * Close the request for input. Returns the value of [done].
   */
  Future<HttpClientResponse> close();

  /// Gets information about the client connection.
  ///
  /// Returns [:null:] if the socket is not available.
  HttpConnectionInfo get connectionInfo;
}

/**
 * HTTP response for a client connection.
 *
 * The body of a [HttpClientResponse] object is a
 * [Stream] of data from the server. Listen to the body to handle
 * the data and be notified when the entire body is received.
 *
 *     new HttpClient().get('localhost', 80, '/file.txt')
 *          .then((HttpClientRequest request) => request.close())
 *          .then((HttpClientResponse response) {
 *            response.transform(utf8.decoder).listen((contents) {
 *              // handle data
 *            });
 *          });
 */
abstract class HttpClientResponse implements Stream<List<int>> {
  /**
   * Returns the status code.
   *
   * The status code must be set before the body is written
   * to. Setting the status code after writing to the body will throw
   * a `StateError`.
   */
  int get statusCode;

  /**
   * Returns the reason phrase associated with the status code.
   *
   * The reason phrase must be set before the body is written
   * to. Setting the reason phrase after writing to the body will throw
   * a `StateError`.
   */
  String get reasonPhrase;

  /**
   * Returns the content length of the response body. Returns -1 if the size of
   * the response body is not known in advance.
   *
   * If the content length needs to be set, it must be set before the
   * body is written to. Setting the reason phrase after writing to
   * the body will throw a `StateError`.
   */
  int get contentLength;

  /**
   * Gets the persistent connection state returned by the server.
   *
   * if the persistent connection state needs to be set, it must be
   * set before the body is written to. Setting the reason phrase
   * after writing to the body will throw a `StateError`.
   */
  bool get persistentConnection;

  /**
   * Returns whether the status code is one of the normal redirect
   * codes [HttpStatus.MOVED_PERMANENTLY], [HttpStatus.FOUND],
   * [HttpStatus.MOVED_TEMPORARILY], [HttpStatus.SEE_OTHER] and
   * [HttpStatus.TEMPORARY_REDIRECT].
   */
  bool get isRedirect;

  /**
   * Returns the series of redirects this connection has been through. The
   * list will be empty if no redirects were followed. [redirects] will be
   * updated both in the case of an automatic and a manual redirect.
   */
  List<RedirectInfo> get redirects;

  /**
   * Redirects this connection to a new URL. The default value for
   * [method] is the method for the current request. The default value
   * for [url] is the value of the [HttpHeaders.LOCATION] header of
   * the current response. All body data must have been read from the
   * current response before calling [redirect].
   *
   * All headers added to the request will be added to the redirection
   * request. However, any body sent with the request will not be
   * part of the redirection request.
   *
   * If [followLoops] is set to [:true:], redirect will follow the redirect,
   * even if the URL was already visited. The default value is [:false:].
   *
   * The method will ignore [HttpClientRequest.maxRedirects]
   * and will always perform the redirect.
   */
  Future<HttpClientResponse> redirect(
      [String method, Uri url, bool followLoops]);

  /**
   * Returns the client response headers.
   *
   * The client response headers are immutable.
   */
  HttpHeaders get headers;

  /**
   * Detach the underlying socket from the HTTP client. When the
   * socket is detached the HTTP client will no longer perform any
   * operations on it.
   *
   * This is normally used when a HTTP upgrade is negotiated and the
   * communication should continue with a different protocol.
   */
  Future<Socket> detachSocket();

  /**
   * Cookies set by the server (from the 'set-cookie' header).
   */
  List<Cookie> get cookies;

  /**
   * Returns the certificate of the HTTPS server providing the response.
   * Returns null if the connection is not a secure TLS or SSL connection.
   */
  X509Certificate get certificate;

  /**
   * Gets information about the client connection. Returns [:null:] if the socket
   * is not available.
   */
  HttpConnectionInfo get connectionInfo;
}

abstract class HttpClientCredentials {}

/**
 * Represents credentials for basic authentication.
 */
abstract class HttpClientBasicCredentials extends HttpClientCredentials {
  factory HttpClientBasicCredentials(String username, String password) =>
      new _HttpClientBasicCredentials(username, password);
}

/**
 * Represents credentials for digest authentication. Digest
 * authentication is only supported for servers using the MD5
 * algorithm and quality of protection (qop) of either "none" or
 * "auth".
 */
abstract class HttpClientDigestCredentials extends HttpClientCredentials {
  factory HttpClientDigestCredentials(String username, String password) =>
      new _HttpClientDigestCredentials(username, password);
}

/**
 * Information about an [HttpRequest], [HttpResponse], [HttpClientRequest], or
 * [HttpClientResponse] connection.
 */
abstract class HttpConnectionInfo {
  InternetAddress get remoteAddress;
  int get remotePort;
  int get localPort;
}

/**
 * Redirect information.
 */
abstract class RedirectInfo {
  /**
   * Returns the status code used for the redirect.
   */
  int get statusCode;

  /**
   * Returns the method used for the redirect.
   */
  String get method;

  /**
   * Returns the location for the redirect.
   */
  Uri get location;
}

/**
 * When detaching a socket from either the [:HttpServer:] or the
 * [:HttpClient:] due to a HTTP connection upgrade there might be
 * unparsed data already read from the socket. This unparsed data
 * together with the detached socket is returned in an instance of
 * this class.
 */
abstract class DetachedSocket {
  Socket get socket;
  List<int> get unparsedData;
}

class RedirectException implements HttpException {
  final String message;
  final List<RedirectInfo> redirects;

  const RedirectException(this.message, this.redirects);

  String toString() => "RedirectException: $message";

  Uri get uri => redirects.last.location;
}
