| Index: pkg/http/lib/src/base_request.dart
|
| diff --git a/pkg/http/lib/src/base_request.dart b/pkg/http/lib/src/base_request.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ecf5f7a844561eb8a4478f90e80e412134dc50b5
|
| --- /dev/null
|
| +++ b/pkg/http/lib/src/base_request.dart
|
| @@ -0,0 +1,117 @@
|
| +// 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.
|
| +
|
| +library base_request;
|
| +
|
| +import 'dart:io';
|
| +import 'dart:uri';
|
| +
|
| +import 'client.dart';
|
| +import 'streamed_response.dart';
|
| +
|
| +/// The base class for HTTP requests.
|
| +///
|
| +/// Subclasses of [BaseRequest] can be constructed manually and passed to
|
| +/// [BaseClient.send], which allows the user to provide fine-grained control
|
| +/// over the request properties. However, usually it's easier to use convenience
|
| +/// methods like [get] or [BaseClient.get].
|
| +abstract class BaseRequest {
|
| + /// The HTTP method of the request. Most commonly "GET" or "POST", less
|
| + /// commonly "HEAD", "PUT", or "DELETE". Non-standard method names are also
|
| + /// supported.
|
| + final String method;
|
| +
|
| + /// The URL to which the request will be sent.
|
| + final Uri url;
|
| +
|
| + /// The size of the request body, in bytes. This defaults to -1, which
|
| + /// indicates that the size of the request is not known in advance.
|
| + int get contentLength => _contentLength;
|
| + int _contentLength = -1;
|
| +
|
| + set contentLength(int value) {
|
| + _checkFinalized();
|
| + _contentLength = value;
|
| + }
|
| +
|
| + /// Whether a persistent connection should be maintained with the server.
|
| + /// Defaults to true.
|
| + bool get persistentConnection => _persistentConnection;
|
| + bool _persistentConnection = true;
|
| +
|
| + set persistentConnection(bool value) {
|
| + _checkFinalized();
|
| + _persistentConnection = value;
|
| + }
|
| +
|
| + /// Whether the client should follow redirects while resolving this request.
|
| + /// Defaults to true.
|
| + bool get followRedirects => _followRedirects;
|
| + bool _followRedirects = true;
|
| +
|
| + set followRedirects(bool value) {
|
| + _checkFinalized();
|
| + _followRedirects = value;
|
| + }
|
| +
|
| + /// The maximum number of redirects to follow when [followRedirects] is true.
|
| + /// If this number is exceeded the [BaseResponse] future will signal a
|
| + /// [RedirectLimitExceeded] exception. Defaults to 5.
|
| + int get maxRedirects => _maxRedirects;
|
| + int _maxRedirects = 5;
|
| +
|
| + set maxRedirects(int value) {
|
| + _checkFinalized();
|
| + _maxRedirects = value;
|
| + }
|
| +
|
| + // TODO(nweiz): automatically parse cookies from headers
|
| +
|
| + // TODO(nweiz): make this a HttpHeaders object
|
| + /// The headers for this request.
|
| + final Map<String, String> headers;
|
| +
|
| + /// Whether the request has been finalized.
|
| + bool get finalized => _finalized;
|
| + bool _finalized = false;
|
| +
|
| + /// Creates a new HTTP request.
|
| + BaseRequest(this.method, this.url)
|
| + : headers = <String>{};
|
| +
|
| + /// Finalizes the HTTP request in preparation for it being sent. This freezes
|
| + /// all mutable fields and returns an [InputStream] that should emit the body
|
| + /// of the request. The stream may be closed to indicate a request with no
|
| + /// body.
|
| + ///
|
| + /// The base implementation of this returns null rather than an [InputStream];
|
| + /// subclasses are responsible for creating the return value. They should also
|
| + /// freeze any additional mutable fields they add that don't make sense to
|
| + /// change after the request headers are sent.
|
| + InputStream finalize() {
|
| + // TODO(nweiz): freeze headers
|
| + if (finalized) throw new StateError("Can't finalize a finalized Request.");
|
| + _finalized = true;
|
| + return null;
|
| + }
|
| +
|
| + /// Sends this request.
|
| + ///
|
| + /// This automatically initializes a new [Client] and closes that client once
|
| + /// the request is complete. If you're planning on making multiple requests to
|
| + /// the same server, you should use a single [Client] for all of those
|
| + /// requests.
|
| + Future<StreamedResponse> send() {
|
| + var client = new Client();
|
| + var future = client.send(this);
|
| + future.onComplete((_) => client.close());
|
| + return future;
|
| + }
|
| +
|
| + /// Throws an error if this request has been finalized.
|
| + void _checkFinalized() {
|
| + if (!finalized) return;
|
| + throw new StateError("Can't modify a finalized Request.");
|
| + }
|
| +}
|
|
|