OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// A composable, [Future]-based library for making HTTP requests. | 5 /// A composable, [Future]-based library for making HTTP requests. |
6 /// | 6 /// |
7 /// ## Installing ## | 7 /// ## Installing ## |
8 /// | 8 /// |
9 /// Use [pub][] to install this package. Add the following to your | 9 /// Use [pub][] to install this package. Add the following to your |
10 /// `pubspec.yaml` file. | 10 /// `pubspec.yaml` file. |
11 /// | 11 /// |
12 /// dependencies: | 12 /// dependencies: |
13 /// http: any | 13 /// http: any |
14 /// | 14 /// |
15 /// Then run `pub install`. | 15 /// Then run `pub install`. |
16 /// | 16 /// |
17 /// For more information, see the | 17 /// For more information, see the |
18 /// [http package on pub.dartlang.org](http://pub.dartlang.org/packages/http). | 18 /// [http package on pub.dartlang.org](http://pub.dartlang.org/packages/http). |
19 /// | 19 /// |
20 /// The easiest way to use this library is via the top-level functions. They | 20 /// The easiest way to use this library is via the top-level functions. They |
21 /// allow you to make individual HTTP requests with minimal hassle: | 21 /// allow you to make individual HTTP requests with minimal hassle: |
22 /// | 22 /// |
23 /// import 'package:http/http.dart' as http; | 23 /// import 'package:http/http.dart' as http; |
24 /// | 24 /// |
25 /// var url = "http://example.com/whatsit/create"; | 25 /// var url = "http://example.com/whatsit/create"; |
26 /// http.post(url, fields: {"name": "doodle", "color": "blue"}) | 26 /// http.post(url, body: {"name": "doodle", "color": "blue"}) |
27 /// .then((response) { | 27 /// .then((response) { |
28 /// print("Response status: ${response.statusCode}"); | 28 /// print("Response status: ${response.statusCode}"); |
29 /// print("Response body: ${response.body}"); | 29 /// print("Response body: ${response.body}"); |
30 /// }); | 30 /// }); |
31 /// | 31 /// |
32 /// http.read("http://example.com/foobar.txt").then(print); | 32 /// http.read("http://example.com/foobar.txt").then(print); |
33 /// | 33 /// |
34 /// If you're making multiple requests to the same server, you can keep open a | 34 /// If you're making multiple requests to the same server, you can keep open a |
35 /// persistent connection by using a [Client] rather than making one-off | 35 /// persistent connection by using a [Client] rather than making one-off |
36 /// requests. If you do this, make sure to close the client when you're done: | 36 /// requests. If you do this, make sure to close the client when you're done: |
37 /// | 37 /// |
38 /// var client = new http.Client(); | 38 /// var client = new http.Client(); |
39 /// client.post( | 39 /// client.post( |
40 /// "http://example.com/whatsit/create", | 40 /// "http://example.com/whatsit/create", |
41 /// fields: {"name": "doodle", "color": "blue"}) | 41 /// body: {"name": "doodle", "color": "blue"}) |
42 /// .then((response) => client.get(response.bodyFields['uri'])) | 42 /// .then((response) => client.get(response.bodyFields['uri'])) |
43 /// .then((response) => print(response.body)) | 43 /// .then((response) => print(response.body)) |
44 /// .whenComplete(client.close); | 44 /// .whenComplete(client.close); |
45 /// | 45 /// |
46 /// You can also exert more fine-grained control over your requests and | 46 /// You can also exert more fine-grained control over your requests and |
47 /// responses by creating [Request] or [StreamedRequest] objects yourself and | 47 /// responses by creating [Request] or [StreamedRequest] objects yourself and |
48 /// passing them to [Client.send]. | 48 /// passing them to [Client.send]. |
49 /// | 49 /// |
50 /// This package is designed to be composable. This makes it easy for external | 50 /// This package is designed to be composable. This makes it easy for external |
51 /// libraries to work with one another to add behavior to it. Libraries wishing | 51 /// libraries to work with one another to add behavior to it. Libraries wishing |
52 /// to add behavior should create a subclass of [BaseClient] that wraps another | 52 /// to add behavior should create a subclass of [BaseClient] that wraps another |
53 /// [Client] and adds the desired behavior: | 53 /// [Client] and adds the desired behavior: |
54 /// | 54 /// |
55 /// class UserAgentClient extends http.BaseClient { | 55 /// class UserAgentClient extends http.BaseClient { |
56 /// final String userAgent; | 56 /// final String userAgent; |
57 /// final http.Client _inner; | 57 /// final http.Client _inner; |
58 /// | 58 /// |
59 /// UserAgentClient(this.userAgent, this._inner); | 59 /// UserAgentClient(this.userAgent, this._inner); |
60 /// | 60 /// |
61 /// Future<StreamedResponse> send(BaseRequest request) { | 61 /// Future<StreamedResponse> send(BaseRequest request) { |
62 /// request.headers[HttpHeaders.USER_AGENT] = userAgent; | 62 /// request.headers[HttpHeaders.USER_AGENT] = userAgent; |
63 /// return _inner.send(request); | 63 /// return _inner.send(request); |
64 /// } | 64 /// } |
65 /// } | 65 /// } |
66 /// | 66 /// |
67 /// [pub]: http://pub.dartlang.org | 67 /// [pub]: http://pub.dartlang.org |
68 library http; | 68 library http; |
69 | 69 |
70 import 'dart:async'; | 70 import 'dart:async'; |
71 import 'dart:convert'; | |
71 import 'dart:typed_data'; | 72 import 'dart:typed_data'; |
72 | 73 |
73 import 'src/client.dart'; | 74 import 'src/client.dart'; |
74 import 'src/response.dart'; | 75 import 'src/response.dart'; |
75 | 76 |
76 export 'src/base_client.dart'; | 77 export 'src/base_client.dart'; |
77 export 'src/base_request.dart'; | 78 export 'src/base_request.dart'; |
78 export 'src/base_response.dart'; | 79 export 'src/base_response.dart'; |
79 export 'src/byte_stream.dart'; | 80 export 'src/byte_stream.dart'; |
80 export 'src/client.dart'; | 81 export 'src/client.dart'; |
(...skipping 19 matching lines...) Expand all Loading... | |
100 /// be a [Uri] or a [String]. | 101 /// be a [Uri] or a [String]. |
101 /// | 102 /// |
102 /// This automatically initializes a new [Client] and closes that client once | 103 /// This automatically initializes a new [Client] and closes that client once |
103 /// the request is complete. If you're planning on making multiple requests to | 104 /// the request is complete. If you're planning on making multiple requests to |
104 /// the same server, you should use a single [Client] for all of those requests. | 105 /// the same server, you should use a single [Client] for all of those requests. |
105 /// | 106 /// |
106 /// For more fine-grained control over the request, use [Request] instead. | 107 /// For more fine-grained control over the request, use [Request] instead. |
107 Future<Response> get(url, {Map<String, String> headers}) => | 108 Future<Response> get(url, {Map<String, String> headers}) => |
108 _withClient((client) => client.get(url, headers: headers)); | 109 _withClient((client) => client.get(url, headers: headers)); |
109 | 110 |
110 /// Sends an HTTP POST request with the given headers and fields to the given | 111 /// Sends an HTTP POST request with the given headers and body to the given URL, |
111 /// URL, which an be a [Uri] or a [String]. If any fields are specified, the | 112 /// which can be a [Uri] or a [String]. |
112 /// content-type is automatically set to `"application/x-www-form-urlencoded"`. | |
113 /// | 113 /// |
114 /// This automatically initializes a new [Client] and closes that client once | 114 /// [body] sets the body of the request. It can be a [String], a [List<int>] or |
115 /// the request is complete. If you're planning on making multiple requests to | 115 /// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and |
116 /// the same server, you should use a single [Client] for all of those requests. | 116 /// used as the body of the request. The content-type of the request will |
117 /// default to "text/plain". | |
118 /// | |
119 /// If [body] is a List, it's used as-is as the body of the request. | |
Bob Nystrom
2013/11/12 00:07:33
Instead of "used as-is" how about clarifying that
nweiz
2013/11/12 01:59:13
Done.
| |
120 /// | |
121 /// If [body] is a Map, it's encoded as form fields using [encoding]. The | |
122 /// content-type of the request will be set to | |
123 /// `"application/x-www-form-urlencoded"`; this cannot be overridden. | |
124 /// | |
125 /// [encoding] defaults to [UTF8]. | |
117 /// | 126 /// |
118 /// For more fine-grained control over the request, use [Request] or | 127 /// For more fine-grained control over the request, use [Request] or |
119 /// [StreamedRequest] instead. | 128 /// [StreamedRequest] instead. |
120 Future<Response> post(url, | 129 Future<Response> post(url, {Map<String, String> headers, body, |
121 {Map<String, String> headers, | 130 Encoding encoding}) => |
122 Map<String, String> fields}) => | 131 _withClient((client) => client.post(url, |
123 _withClient((client) => client.post(url, headers: headers, fields: fields)); | 132 headers: headers, body: body, encoding: encoding)); |
124 | 133 |
125 /// Sends an HTTP POST request with the given headers and fields to the given | 134 /// Sends an HTTP PUT request with the given headers and body to the given URL, |
126 /// URL, which can be a [Uri] or a [String]. If any fields are specified, the | 135 /// which can be a [Uri] or a [String]. |
127 /// content-type is automatically set to `"application/x-www-form-urlencoded"`. | |
128 /// | 136 /// |
129 /// This automatically initializes a new [Client] and closes that client once | 137 /// [body] sets the body of the request. It can be a [String], a [List<int>] or |
130 /// the request is complete. If you're planning on making multiple requests to | 138 /// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and |
131 /// the same server, you should use a single [Client] for all of those requests. | 139 /// used as the body of the request. The content-type of the request will |
140 /// default to "text/plain". | |
141 /// | |
142 /// If [body] is a List, it's used as-is as the body of the request. | |
143 /// | |
144 /// If [body] is a Map, it's encoded as form fields using [encoding]. The | |
145 /// content-type of the request will be set to | |
146 /// `"application/x-www-form-urlencoded"`; this cannot be overridden. | |
147 /// | |
148 /// [encoding] defaults to [UTF8]. | |
132 /// | 149 /// |
133 /// For more fine-grained control over the request, use [Request] or | 150 /// For more fine-grained control over the request, use [Request] or |
134 /// [StreamedRequest] instead. | 151 /// [StreamedRequest] instead. |
135 Future<Response> put(url, | 152 Future<Response> put(url, {Map<String, String> headers, body, |
136 {Map<String, String> headers, | 153 Encoding encoding}) => |
137 Map<String, String> fields}) => | 154 _withClient((client) => client.put(url, |
138 _withClient((client) => client.put(url, headers: headers, fields: fields)); | 155 headers: headers, body: body, encoding: encoding)); |
139 | 156 |
140 /// Sends an HTTP DELETE request with the given headers to the given URL, which | 157 /// Sends an HTTP DELETE request with the given headers to the given URL, which |
141 /// can be a [Uri] or a [String]. | 158 /// can be a [Uri] or a [String]. |
142 /// | 159 /// |
143 /// This automatically initializes a new [Client] and closes that client once | 160 /// This automatically initializes a new [Client] and closes that client once |
144 /// the request is complete. If you're planning on making multiple requests to | 161 /// the request is complete. If you're planning on making multiple requests to |
145 /// the same server, you should use a single [Client] for all of those requests. | 162 /// the same server, you should use a single [Client] for all of those requests. |
146 /// | 163 /// |
147 /// For more fine-grained control over the request, use [Request] instead. | 164 /// For more fine-grained control over the request, use [Request] instead. |
148 Future<Response> delete(url, {Map<String, String> headers}) => | 165 Future<Response> delete(url, {Map<String, String> headers}) => |
(...skipping 29 matching lines...) Expand all Loading... | |
178 /// For more fine-grained control over the request and response, use [Request] | 195 /// For more fine-grained control over the request and response, use [Request] |
179 /// instead. | 196 /// instead. |
180 Future<Uint8List> readBytes(url, {Map<String, String> headers}) => | 197 Future<Uint8List> readBytes(url, {Map<String, String> headers}) => |
181 _withClient((client) => client.readBytes(url, headers: headers)); | 198 _withClient((client) => client.readBytes(url, headers: headers)); |
182 | 199 |
183 Future _withClient(Future fn(Client)) { | 200 Future _withClient(Future fn(Client)) { |
184 var client = new Client(); | 201 var client = new Client(); |
185 var future = fn(client); | 202 var future = fn(client); |
186 return future.whenComplete(client.close); | 203 return future.whenComplete(client.close); |
187 } | 204 } |
OLD | NEW |