| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library base_request; |
| 6 |
| 7 import 'dart:io'; |
| 8 import 'dart:uri'; |
| 9 |
| 10 import 'client.dart'; |
| 11 import 'streamed_response.dart'; |
| 12 |
| 13 /// The base class for HTTP requests. |
| 14 /// |
| 15 /// Subclasses of [BaseRequest] can be constructed manually and passed to |
| 16 /// [BaseClient.send], which allows the user to provide fine-grained control |
| 17 /// over the request properties. However, usually it's easier to use convenience |
| 18 /// methods like [get] or [BaseClient.get]. |
| 19 abstract class BaseRequest { |
| 20 /// The HTTP method of the request. Most commonly "GET" or "POST", less |
| 21 /// commonly "HEAD", "PUT", or "DELETE". Non-standard method names are also |
| 22 /// supported. |
| 23 final String method; |
| 24 |
| 25 /// The URL to which the request will be sent. |
| 26 final Uri url; |
| 27 |
| 28 /// The size of the request body, in bytes. This defaults to -1, which |
| 29 /// indicates that the size of the request is not known in advance. |
| 30 int get contentLength => _contentLength; |
| 31 int _contentLength = -1; |
| 32 |
| 33 set contentLength(int value) { |
| 34 _checkFinalized(); |
| 35 _contentLength = value; |
| 36 } |
| 37 |
| 38 /// Whether a persistent connection should be maintained with the server. |
| 39 /// Defaults to true. |
| 40 bool get persistentConnection => _persistentConnection; |
| 41 bool _persistentConnection = true; |
| 42 |
| 43 set persistentConnection(bool value) { |
| 44 _checkFinalized(); |
| 45 _persistentConnection = value; |
| 46 } |
| 47 |
| 48 /// Whether the client should follow redirects while resolving this request. |
| 49 /// Defaults to true. |
| 50 bool get followRedirects => _followRedirects; |
| 51 bool _followRedirects = true; |
| 52 |
| 53 set followRedirects(bool value) { |
| 54 _checkFinalized(); |
| 55 _followRedirects = value; |
| 56 } |
| 57 |
| 58 /// The maximum number of redirects to follow when [followRedirects] is true. |
| 59 /// If this number is exceeded the [BaseResponse] future will signal a |
| 60 /// [RedirectLimitExceeded] exception. Defaults to 5. |
| 61 int get maxRedirects => _maxRedirects; |
| 62 int _maxRedirects = 5; |
| 63 |
| 64 set maxRedirects(int value) { |
| 65 _checkFinalized(); |
| 66 _maxRedirects = value; |
| 67 } |
| 68 |
| 69 // TODO(nweiz): automatically parse cookies from headers |
| 70 |
| 71 // TODO(nweiz): make this a HttpHeaders object |
| 72 /// The headers for this request. |
| 73 final Map<String, String> headers; |
| 74 |
| 75 /// Whether the request has been finalized. |
| 76 bool get finalized => _finalized; |
| 77 bool _finalized = false; |
| 78 |
| 79 /// Creates a new HTTP request. |
| 80 BaseRequest(this.method, this.url) |
| 81 : headers = <String>{}; |
| 82 |
| 83 /// Finalizes the HTTP request in preparation for it being sent. This freezes |
| 84 /// all mutable fields and returns an [InputStream] that should emit the body |
| 85 /// of the request. The stream may be closed to indicate a request with no |
| 86 /// body. |
| 87 /// |
| 88 /// The base implementation of this returns null rather than an [InputStream]; |
| 89 /// subclasses are responsible for creating the return value. They should also |
| 90 /// freeze any additional mutable fields they add that don't make sense to |
| 91 /// change after the request headers are sent. |
| 92 InputStream finalize() { |
| 93 // TODO(nweiz): freeze headers |
| 94 if (finalized) throw new StateError("Can't finalize a finalized Request."); |
| 95 _finalized = true; |
| 96 return null; |
| 97 } |
| 98 |
| 99 /// Sends this request. |
| 100 /// |
| 101 /// This automatically initializes a new [Client] and closes that client once |
| 102 /// the request is complete. If you're planning on making multiple requests to |
| 103 /// the same server, you should use a single [Client] for all of those |
| 104 /// requests. |
| 105 Future<StreamedResponse> send() { |
| 106 var client = new Client(); |
| 107 var future = client.send(this); |
| 108 future.onComplete((_) => client.close()); |
| 109 return future; |
| 110 } |
| 111 |
| 112 /// Throws an error if this request has been finalized. |
| 113 void _checkFinalized() { |
| 114 if (!finalized) return; |
| 115 throw new StateError("Can't modify a finalized Request."); |
| 116 } |
| 117 } |
| OLD | NEW |