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 io_client; | |
6 | |
7 import 'dart:async'; | |
8 | |
9 import 'package:stack_trace/stack_trace.dart'; | |
10 | |
11 import 'base_client.dart'; | |
12 import 'base_request.dart'; | |
13 import 'exception.dart'; | |
14 import 'io.dart' as io; | |
15 import 'streamed_response.dart'; | |
16 | |
17 /// A `dart:io`-based HTTP client. | |
18 /// | |
19 /// This is the default client when running on the command line. | |
20 class IOClient extends BaseClient { | |
21 /// The underlying `dart:io` HTTP client. | |
22 var _inner; | |
23 | |
24 /// Creates a new HTTP client. | |
25 /// | |
26 /// [innerClient] must be a `dart:io` HTTP client. If it's not passed, a | |
27 /// default one will be instantiated. | |
28 IOClient([innerClient]) { | |
29 io.assertSupported("IOClient"); | |
30 if (innerClient != null) { | |
31 // TODO(nweiz): remove this assert when we can type [innerClient] | |
32 // properly. | |
33 assert(io.isHttpClient(innerClient)); | |
34 _inner = innerClient; | |
35 } else { | |
36 _inner = io.newHttpClient(); | |
37 } | |
38 } | |
39 | |
40 /// Sends an HTTP request and asynchronously returns the response. | |
41 Future<StreamedResponse> send(BaseRequest request) { | |
42 var stream = request.finalize(); | |
43 | |
44 return Chain.track(_inner.openUrl(request.method, request.url)) | |
45 .then((ioRequest) { | |
46 var contentLength = request.contentLength == null ? | |
47 -1 : request.contentLength; | |
48 ioRequest | |
49 ..followRedirects = request.followRedirects | |
50 ..maxRedirects = request.maxRedirects | |
51 ..contentLength = contentLength | |
52 ..persistentConnection = request.persistentConnection; | |
53 request.headers.forEach((name, value) { | |
54 ioRequest.headers.set(name, value); | |
55 }); | |
56 return Chain.track(stream.pipe(ioRequest)); | |
57 }).then((response) { | |
58 var headers = {}; | |
59 response.headers.forEach((key, values) { | |
60 headers[key] = values.join(','); | |
61 }); | |
62 | |
63 var contentLength = response.contentLength == -1 ? | |
64 null : response.contentLength; | |
65 return new StreamedResponse( | |
66 response.handleError((error) => | |
67 throw new ClientException(error.message, error.uri), | |
68 test: (error) => io.isHttpException(error)), | |
69 response.statusCode, | |
70 contentLength: contentLength, | |
71 request: request, | |
72 headers: headers, | |
73 isRedirect: response.isRedirect, | |
74 persistentConnection: response.persistentConnection, | |
75 reasonPhrase: response.reasonPhrase); | |
76 }).catchError((error) { | |
77 if (!io.isHttpException(error)) throw error; | |
78 throw new ClientException(error.message, error.uri); | |
79 }); | |
80 } | |
81 | |
82 /// Closes the client. This terminates all active connections. If a client | |
83 /// remains unclosed, the Dart process may not terminate. | |
84 void close() { | |
85 if (_inner != null) _inner.close(force: true); | |
86 _inner = null; | |
87 } | |
88 } | |
OLD | NEW |