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 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 /** | 7 /** |
8 * HTTP status codes. | 8 * HTTP status codes. |
9 */ | 9 */ |
10 abstract class HttpStatus { | 10 abstract class HttpStatus { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 static const int BAD_GATEWAY = 502; | 48 static const int BAD_GATEWAY = 502; |
49 static const int SERVICE_UNAVAILABLE = 503; | 49 static const int SERVICE_UNAVAILABLE = 503; |
50 static const int GATEWAY_TIMEOUT = 504; | 50 static const int GATEWAY_TIMEOUT = 504; |
51 static const int HTTP_VERSION_NOT_SUPPORTED = 505; | 51 static const int HTTP_VERSION_NOT_SUPPORTED = 505; |
52 // Client generated status code. | 52 // Client generated status code. |
53 static const int NETWORK_CONNECT_TIMEOUT_ERROR = 599; | 53 static const int NETWORK_CONNECT_TIMEOUT_ERROR = 599; |
54 } | 54 } |
55 | 55 |
56 | 56 |
57 /** | 57 /** |
58 * A server that delivers content, such as web pages, using | 58 * A server that delivers content, such as web pages, using the HTTP protocol. |
59 * the HTTP protocol. | |
60 * | 59 * |
61 * The [HttpServer] is a [Stream] of [HttpRequest]s. Each | 60 * The HttpServer is a [Stream] that provides [HttpRequest] objects. Each |
62 * [HttpRequest] has an associated [HttpResponse] object as its | 61 * HttpRequest has an associated [HttpResponse] object. |
63 * [HttpRequest.response] member, and the server responds to a request by | 62 * The server responds to a request by writing to that HttpResponse object. |
64 * writing to that [HttpResponse] object. | 63 * The following example shows how to bind an HttpServer to an IPv6 |
64 * [InternetAddress] on port 80 (the standard port for HTTP servers) | |
65 * and how to listen for requests. | |
66 * Port 80 is generally already in use, so your servers should use a | |
Søren Gjesse
2014/03/25 10:27:26
Thin this sentence should be something like this:
mem
2014/03/25 17:30:49
Done.
| |
67 * non-reserved port (above 1023). | |
65 * | 68 * |
66 * Incomplete requests where all or parts of the header is missing, are | 69 * import 'dart:io'; |
67 * ignored and no exceptions or [HttpRequest] objects are generated for them. | 70 * |
68 * Likewise, when writing to a [HttpResponse], any [Socket] exceptions are | 71 * main() { |
72 * HttpServer | |
73 * .bind(InternetAddress.ANY_IP_V6, 80) | |
74 * .then((server) { | |
75 * server.listen((HttpRequest request) { | |
76 * request.response.write('Hello, world!'); | |
77 * request.response.close(); | |
78 * }); | |
79 * }); | |
80 * } | |
81 * | |
82 * Incomplete requests, in which all or part of the header is missing, are | |
83 * ignored, and no exceptions or HttpRequest objects are generated for them. | |
84 * Likewise, when writing to an HttpResponse, any [Socket] exceptions are | |
69 * ignored and any future writes are ignored. | 85 * ignored and any future writes are ignored. |
70 * | 86 * |
71 * The [HttpRequest] exposes the request headers, and provides the request body, | 87 * The HttpRequest exposes the request headers and provides the request body, |
72 * if it exists, as a stream of data. If the body is unread, it'll be drained | 88 * if it exists, as a Stream of data. If the body is unread, it is drained |
73 * when the [HttpResponse] is being written to or closed. | 89 * when the server writes to the HttpResponse or closes it. |
74 * | 90 * |
75 * The following example shows how to bind a [HttpServer] to a IPv6 | 91 * ## Bind with a secure HTTPS connection |
76 * [InternetAddress] on port 80, and listening to requests. | |
77 * | 92 * |
78 * HttpServer.bind(InternetAddress.ANY_IP_V6, 80).then((server) { | 93 * Use [bindSecure] to create a secure HTTPS connection. |
Søren Gjesse
2014/03/25 10:27:26
'create a secure HTTPS connection' -> 'create a HT
mem
2014/03/25 17:30:49
Done.
| |
79 * server.listen((HttpRequest request) { | 94 * The client needs to present a value certificate to connect successfully. |
Søren Gjesse
2014/03/25 10:27:26
The client does not need to present a certificate
mem
2014/03/25 17:30:49
Done.
| |
80 * // Handle requests. | 95 * The code below uses a certificate used by Dart for testing purposes. |
81 * }); | 96 * |
82 * }); | 97 * import 'dart:io'; |
98 * import "dart:isolate"; | |
99 * | |
100 * main() { | |
101 * var testPkcertDatabase = Platform.script.resolve('pkcert') | |
102 * .toFilePath(); | |
103 * SecureSocket.initialize(database: testPkcertDatabase, | |
104 * password: 'dartdart'); | |
105 * | |
106 * HttpServer | |
107 * .bindSecure(InternetAddress.ANY_IP_V6, | |
108 * 80, | |
Søren Gjesse
2014/03/25 10:27:26
Use the default HTTPS port 443 here.
mem
2014/03/25 17:30:49
Done.
| |
109 * backlog: 5, | |
Søren Gjesse
2014/03/25 10:27:26
Just remove the backlog optional argument in the s
mem
2014/03/25 17:30:49
Done.
| |
110 * certificateName: 'localhost_cert') | |
111 * .then((server) { | |
112 * ReceivePort serverPort = new ReceivePort(); | |
Søren Gjesse
2014/03/25 10:27:26
Please remove the receive port.
mem
2014/03/25 17:30:49
Done.
| |
113 * server.listen((HttpRequest request) { | |
114 * request.response.write('Hello, world!'); | |
115 * request.response.close(); | |
116 * }); | |
117 * }); | |
118 * } | |
119 * | |
120 * ## Connect to a socket | |
121 * | |
122 * You can use the [listenOn] constructor to attach an HTTP server to | |
123 * a [ServerSocket]. By subclassing ServerSocket you can provide | |
Søren Gjesse
2014/03/25 10:27:26
I don't think we should mention "subclassing Serve
mem
2014/03/25 17:30:49
Done.
| |
124 * socket specialization. | |
125 * | |
126 * import 'dart:io'; | |
127 * | |
128 * main() { | |
129 * ServerSocket.bind(InternetAddress.ANY_IP_V6, 80) | |
130 * .then((serverSocket) { | |
131 * HttpServer httpserver = new HttpServer.listenOn(serverSocket); | |
132 * serverSocket.listen((Socket socket) { | |
133 * socket.write('Hello, client.'); | |
134 * }); | |
135 * }); | |
136 * } | |
137 * | |
138 * ## Other resources | |
139 * | |
140 * * HttpServer is a Stream. Refer to the [Stream] class for information | |
141 * about the streaming qualities of an HttpServer. | |
142 * | |
143 * * The [http_server](https://pub.dartlang.org/packages/http_server) | |
144 * package on pub.dartlang.org contains a set of high-level classes that, | |
145 * together with this class, makes it easy to provide content through HTTP | |
146 * servers. | |
83 */ | 147 */ |
84 abstract class HttpServer implements Stream<HttpRequest> { | 148 abstract class HttpServer implements Stream<HttpRequest> { |
85 /** | 149 /** |
86 * Set and get the default value of the `Server` header for all responses | 150 * Set and get the default value of the `Server` header for all responses |
87 * generated by this [HttpServer]. By default, it's disabled. | 151 * generated by this [HttpServer]. By default, it's disabled. |
88 * | 152 * |
89 * If the serverHeader is set to `null`, no default `Server` header will be | 153 * If the serverHeader is set to `null`, no default `Server` header will be |
90 * added to each response. | 154 * added to each response. |
91 */ | 155 */ |
92 String serverHeader; | 156 String serverHeader; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 /** | 318 /** |
255 * Number of connections which are preparing to close. Note: These | 319 * Number of connections which are preparing to close. Note: These |
256 * connections are also part of the [:active:] count as they might | 320 * connections are also part of the [:active:] count as they might |
257 * still be sending data to the client before finally closing. | 321 * still be sending data to the client before finally closing. |
258 */ | 322 */ |
259 int closing = 0; | 323 int closing = 0; |
260 } | 324 } |
261 | 325 |
262 | 326 |
263 /** | 327 /** |
264 * Access to the HTTP headers for requests and responses. In some | 328 * Headers for HTTP requests and responses. |
265 * situations the headers will be immutable and the mutating methods | 329 * |
266 * will then throw exceptions. | 330 * In some situations the headers are immutable, |
331 * in which case the mutating methods throw exceptions. | |
267 * | 332 * |
268 * For all operations on HTTP headers the header name is | 333 * For all operations on HTTP headers the header name is |
269 * case-insensitive. | 334 * case-insensitive. |
335 * | |
336 * To set the value of a header use the `add()` method: | |
337 * | |
338 * request.headers.add(HttpHeaders.CONTENT_ENCODING, 'JSON'); | |
Søren Gjesse
2014/03/25 10:27:26
We should probably use a more common header, e.g.
| |
339 * | |
340 * To retrieve the value of a header use the `value()` method: | |
341 * | |
342 * print(request.headers.value(HttpHeaders.FROM)); | |
Søren Gjesse
2014/03/25 10:27:26
I think FROM is not the best choice here - don't t
mem
2014/03/25 17:30:49
Done.
| |
343 * | |
344 * Alternatively, you can use the square bracket (`[]`) operator: | |
345 * request.headers['FROM'] = john@example.com' | |
Søren Gjesse
2014/03/25 10:27:26
The operator[] is only for getting the list of val
mem
2014/03/25 17:30:49
Done.
mem
2014/03/25 17:30:49
Done.
| |
270 */ | 346 */ |
271 abstract class HttpHeaders { | 347 abstract class HttpHeaders { |
272 static const ACCEPT = "accept"; | 348 static const ACCEPT = "accept"; |
273 static const ACCEPT_CHARSET = "accept-charset"; | 349 static const ACCEPT_CHARSET = "accept-charset"; |
274 static const ACCEPT_ENCODING = "accept-encoding"; | 350 static const ACCEPT_ENCODING = "accept-encoding"; |
275 static const ACCEPT_LANGUAGE = "accept-language"; | 351 static const ACCEPT_LANGUAGE = "accept-language"; |
276 static const ACCEPT_RANGES = "accept-ranges"; | 352 static const ACCEPT_RANGES = "accept-ranges"; |
277 static const AGE = "age"; | 353 static const AGE = "age"; |
278 static const ALLOW = "allow"; | 354 static const ALLOW = "allow"; |
279 static const AUTHORIZATION = "authorization"; | 355 static const AUTHORIZATION = "authorization"; |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
752 * which listens for HTTP requests on a specific host and port. | 828 * which listens for HTTP requests on a specific host and port. |
753 * For each request received, the HttpServer, which is a [Stream], | 829 * For each request received, the HttpServer, which is a [Stream], |
754 * generates an `HttpRequest` object and adds it to the stream. | 830 * generates an `HttpRequest` object and adds it to the stream. |
755 * | 831 * |
756 * An `HttpRequest` object delivers the body content of the request | 832 * An `HttpRequest` object delivers the body content of the request |
757 * as a stream of byte lists. | 833 * as a stream of byte lists. |
758 * The object also contains information about the request, | 834 * The object also contains information about the request, |
759 * such as the method, URI, and headers. | 835 * such as the method, URI, and headers. |
760 * | 836 * |
761 * In the following code, an HttpServer listens | 837 * In the following code, an HttpServer listens |
762 * for HTTP requests and, within the callback function, | 838 * for HTTP requests. When the server receives a request, |
763 * uses the `HttpRequest` object's `method` property to dispatch requests. | 839 * it uses the HttpRequest object's `method` property to dispatch requests. |
764 * | 840 * |
765 * final HOST = InternetAddress.LOOPBACK_IP_V4; | 841 * final HOST = InternetAddress.LOOPBACK_IP_V4; |
766 * final PORT = 4040; | 842 * final PORT = 80; |
767 * | 843 * |
768 * HttpServer.bind(HOST, PORT).then((_server) { | 844 * HttpServer.bind(HOST, PORT).then((_server) { |
769 * _server.listen((HttpRequest request) { | 845 * _server.listen((HttpRequest request) { |
770 * switch (request.method) { | 846 * switch (request.method) { |
771 * case 'GET': | 847 * case 'GET': |
772 * handleGetRequest(request); | 848 * handleGetRequest(request); |
773 * break; | 849 * break; |
774 * case 'POST': | 850 * case 'POST': |
775 * ... | 851 * ... |
776 * } | 852 * } |
777 * }, | 853 * }, |
778 * onError: handleError); // listen() failed. | 854 * onError: handleError); // listen() failed. |
779 * }).catchError(handleError); | 855 * }).catchError(handleError); |
780 * | 856 * |
781 * Listen to the `HttpRequest` stream to handle the | 857 * An HttpRequest object contains an [HttpResponse] object, |
Søren Gjesse
2014/03/25 10:27:26
'contains an' provides access to the associated Ht
mem
2014/03/25 17:30:49
Done.
| |
782 * data and be notified once the entire body is received. | |
783 * An `HttpRequest` object contains an [HttpResponse] object, | |
784 * to which the server can write its response. | 858 * to which the server can write its response. |
785 * For example, here's a skeletal callback function | 859 * For example, here's a function that responds to a request: |
786 * that responds to a request: | |
787 * | 860 * |
788 * void handleGetRequest(HttpRequest req) { | 861 * void handleGetRequest(HttpRequest req) { |
789 * HttpResponse res = req.response; | 862 * HttpResponse res = req.response; |
790 * var body = []; | 863 * var body = []; |
791 * req.listen((List<int> buffer) => body.add(buffer), | 864 * req.listen((List<int> buffer) => body.add(buffer), |
792 * onDone: () { | 865 * onDone: () { |
793 * res.write('Received ${body.length} for request '); | 866 * res.write('Received ${body.length} for request '); |
794 * res.write(' ${req.method}: ${req.uri.path}'); | 867 * res.write(' ${req.method}: ${req.uri.path}'); |
795 * res.close(); | 868 * res.close(); |
796 * }, | 869 * }, |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
886 * | 959 * |
887 * If the [contentLength] of the body isn't 0, and the body isn't being read, | 960 * If the [contentLength] of the body isn't 0, and the body isn't being read, |
888 * any write calls on the [HttpResponse] automatically drain the request | 961 * any write calls on the [HttpResponse] automatically drain the request |
889 * body. | 962 * body. |
890 */ | 963 */ |
891 HttpResponse get response; | 964 HttpResponse get response; |
892 } | 965 } |
893 | 966 |
894 | 967 |
895 /** | 968 /** |
896 * An [HttpResponse] represents the headers and data to be returned to | 969 * An [HttpResponse] contains the headers and data returned |
897 * a client in response to an HTTP request. | 970 * from the server to the client in response to an HTTP request. |
898 * | 971 * |
972 * Every HttpRequest object contains an HttpResponse object, | |
Søren Gjesse
2014/03/25 10:27:26
See above.
mem
2014/03/25 17:30:49
Done.
| |
973 * by which the server sends a response to the client. | |
899 * This object has a number of properties for setting up the HTTP | 974 * This object has a number of properties for setting up the HTTP |
900 * header of the response. When the header has been set up the methods | 975 * header of the response. This class implements [IOSink]. |
901 * from the [IOSink] can be used to write the actual body of the HTTP | 976 * When the header has been set up, the methods |
902 * response. When one of the [IOSink] methods is used for the | 977 * from IOSink, such as `writeln()`, can be used to write |
903 * first time the request header is send. Calling any methods that | 978 * the body of the HTTP response. |
904 * will change the header after it is sent will throw an exception. | 979 * Use the `close()` method to close the response and send it to the client. |
905 * | 980 * |
906 * When writing string data through the [IOSink] the encoding used | 981 * server.listen((HttpRequest request) { |
907 * will be determined from the "charset" parameter of the | 982 * request.response.write('Hello, world!'); |
983 * request.response.close(); | |
984 * }); | |
985 * | |
986 * When one of the IOSink methods is used for the | |
987 * first time, the request header is sent. Calling any methods that | |
988 * change the header after it is sent throws an exception. | |
989 | |
990 * When writing string data through the IOSink, the encoding used | |
991 * is determined from the "charset" parameter of the | |
908 * "Content-Type" header. | 992 * "Content-Type" header. |
909 * | 993 * |
910 * HttpResponse response = ... | 994 * HttpResponse response = ... |
911 * response.headers.contentType | 995 * response.headers.contentType |
912 * = new ContentType("application", "json", charset: "utf-8"); | 996 * = new ContentType("application", "json", charset: "utf-8"); |
913 * response.write(...); // Strings written will be UTF-8 encoded. | 997 * response.write(...); // Strings written will be UTF-8 encoded. |
914 * | 998 * |
915 * If no charset is provided the default of ISO-8859-1 (Latin 1) will | 999 * If no charset is provided the default of ISO-8859-1 (Latin 1) will |
916 * be used. | 1000 * be used. |
917 * | 1001 * |
918 * HttpResponse response = ... | 1002 * HttpResponse response = ... |
919 * response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); | 1003 * response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); |
920 * response.write(...); // Strings written will be ISO-8859-1 encoded. | 1004 * response.write(...); // Strings written will be ISO-8859-1 encoded. |
921 * | 1005 * |
922 * If an unsupported encoding is used an exception will be thrown if | 1006 * An exception is thrown if you use an unsupported encoding and the |
923 * using one of the write methods taking a string. | 1007 * `write()` method being used takes a string parameter. |
924 */ | 1008 */ |
925 abstract class HttpResponse implements IOSink { | 1009 abstract class HttpResponse implements IOSink { |
926 // TODO(ajohnsen): Add documentation of how to pipe a file to the response. | 1010 // TODO(ajohnsen): Add documentation of how to pipe a file to the response. |
927 /** | 1011 /** |
928 * Gets and sets the content length of the response. If the size of | 1012 * Gets and sets the content length of the response. If the size of |
929 * the response is not known in advance set the content length to | 1013 * the response is not known in advance set the content length to |
930 * -1 - which is also the default if not set. | 1014 * -1 - which is also the default if not set. |
931 */ | 1015 */ |
932 int contentLength; | 1016 int contentLength; |
933 | 1017 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1004 * socket is not available. | 1088 * socket is not available. |
1005 */ | 1089 */ |
1006 HttpConnectionInfo get connectionInfo; | 1090 HttpConnectionInfo get connectionInfo; |
1007 } | 1091 } |
1008 | 1092 |
1009 | 1093 |
1010 /** | 1094 /** |
1011 * A client that receives content, such as web pages, from | 1095 * A client that receives content, such as web pages, from |
1012 * a server using the HTTP protocol. | 1096 * a server using the HTTP protocol. |
1013 * | 1097 * |
1014 * HttpClient contains a number of methods to send a HTTP request | 1098 * HttpClient contains a number of methods to send an [HttpClientRequest] |
1015 * to a HTTP server and receive a HTTP response back. | 1099 * to an [HttpServer] and receive an [HttpClientResponse] back. |
Søren Gjesse
2014/03/25 10:27:26
[HttpServer] should just be HTTP server, as it can
mem
2014/03/25 17:30:49
Done.
mem
2014/03/25 17:30:49
Done.
| |
1100 * For example, you can use the [get], [getUrl], [post], and [postUrl] methods | |
1101 * for GET and POST requests, respectively. | |
1016 * | 1102 * |
1017 * This is a two-step process, triggered by two futures. When the | 1103 * ## Making a simple GET request: an example |
1018 * first future completes with a [HttpClientRequest] the underlying | |
1019 * network connection has been established, but no data has yet been | |
1020 * sent. The HTTP headers and body can be set on the request, and | |
1021 * [:close:] is called to sent it to the server. | |
1022 * | 1104 * |
1023 * The second future, which is returned by [:close:], completes with | 1105 * A `getUrl` request is a two-step process, triggered by two [Future]s. |
1024 * an [HttpClientResponse] object when the response is received from | 1106 * When the first future completes with a HttpClientRequest, the underlying |
Søren Gjesse
2014/03/25 10:27:26
`` or [] around HttpClientRequest. I cannot rememb
mem
2014/03/25 17:30:49
Done.
| |
1025 * the server. This object contains the headers and body of the | 1107 * network connection has been established, but no data has been sent. |
1026 * response. | 1108 * In the callback function for the first future, the HTTP headers and body |
1109 * can be set on the request. A call to the [close] method sends the | |
1110 * request to the server. | |
1111 * | |
1112 * When the response is received from the server, | |
1113 * the second future, which is returned by close, completes with | |
1114 * an [HttpClientResponse] object. | |
Søren Gjesse
2014/03/25 10:27:26
Maybe `` instead of [].
mem
2014/03/25 17:30:49
Done.
| |
1027 | 1115 |
1028 * The future for [HttpClientRequest] is created by methods such as | 1116 * When the HTTP response is received from the server, |
Søren Gjesse
2014/03/25 10:27:26
This seems to be duplicate of the paragraph above.
mem
2014/03/25 17:30:49
Done.
| |
1029 * [getUrl] and [open]. | 1117 * the second future, which is returned by close, |
1030 * | 1118 * completes with an [HttpClientResponse] object. |
1031 * When the HTTP response is ready a [HttpClientResponse] object is | 1119 * This object provides access to the headers and body of the response. |
1032 * provided which provides access to the headers and body of the response. The | 1120 * The body is available as a stream implemented by HttpClientResponse. |
1033 * body is available as a stream implemented by [HttpClientResponse]. | 1121 * If a body is present, it must be read. Otherwise, it leads to resource |
1034 * If a body is present, it must be read. Otherwise, it'll lead to a resource | |
1035 * leaks. Consider using [HttpClientResponse.drain] if the body is unused. | 1122 * leaks. Consider using [HttpClientResponse.drain] if the body is unused. |
1036 * | 1123 * |
1037 * HttpClient client = new HttpClient(); | 1124 * HttpClient client = new HttpClient(); |
1038 * client.getUrl(Uri.parse("http://www.example.com/")) | 1125 * client.getUrl(Uri.parse("http://www.example.com/")) |
Søren Gjesse
2014/03/25 10:27:26
Let's stick to the 4-space indent specified by the
mem
2014/03/25 17:30:49
Done.
| |
1039 * .then((HttpClientRequest request) { | 1126 * .then((HttpClientRequest request) { |
1040 * // Prepare the request then call close on it to send it. | 1127 * // Prepare the request, then call close to send it. |
1041 * return request.close(); | 1128 * ... |
1042 * }) | 1129 * return request.close(); |
1043 * .then((HttpClientResponse response) { | 1130 * }) |
1044 * // Process the response. | 1131 * .then((HttpClientResponse response) { |
1045 * }); | 1132 * // Process the response. |
1133 * ... | |
1134 * }); | |
1046 * | 1135 * |
1047 * All [HttpClient] requests set the following header by default: | 1136 * The future for [HttpClientRequest] is created by methods such as |
1137 * [getUrl] and [open]. | |
1138 * | |
1139 * ## Headers | |
1140 * | |
1141 * All HttpClient requests set the following header by default: | |
1048 * | 1142 * |
1049 * Accept-Encoding: gzip | 1143 * Accept-Encoding: gzip |
1050 * | 1144 * |
1051 * This allows the HTTP server to use gzip compression for the body if | 1145 * This allows the HTTP server to use gzip compression for the body if |
1052 * possible. If this behavior is not desired set the | 1146 * possible. If this behavior is not desired set the |
1053 * "Accept-Encoding" header to something else. | 1147 * `Accept-Encoding` header to something else. |
1054 * | 1148 * |
1055 * The [HttpClient] supports persistent connections and caches network | 1149 * ## Closing the connection |
1056 * connections to reuse then for multiple requests whenever | 1150 * |
1151 * The HttpClient supports persistent connections and caches network | |
1152 * connections to reuse them for multiple requests whenever | |
1057 * possible. This means that network connections can be kept open for | 1153 * possible. This means that network connections can be kept open for |
1058 * some time after a request have completed. Use [:HttpClient.close:] | 1154 * some time after a request has completed. Use HttpClient.close |
1059 * to force shut down the [HttpClient] object and close the idle | 1155 * to force the HttpClient object to shut down and to close the idle |
1060 * network connections. | 1156 * network connections. |
1061 * | 1157 * |
1158 * ## Turning proxies on and off | |
1159 * | |
1062 * By default the HttpClient uses the proxy configuration available | 1160 * By default the HttpClient uses the proxy configuration available |
1063 * from the environment, see [findProxyFromEnvironment]. To turn off | 1161 * from the environment, see [findProxyFromEnvironment]. To turn off |
1064 * the use of proxies all together set the [findProxy] property to | 1162 * the use of proxies set the [findProxy] property to |
1065 * [:null:]. | 1163 * [:null:]. |
1066 * | 1164 * |
1067 * HttpClient client = new HttpClient(); | 1165 * HttpClient client = new HttpClient(); |
1068 * client.findProxy = null; | 1166 * client.findProxy = null; |
1069 */ | 1167 */ |
1070 abstract class HttpClient { | 1168 abstract class HttpClient { |
1071 static const int DEFAULT_HTTP_PORT = 80; | 1169 static const int DEFAULT_HTTP_PORT = 80; |
1072 static const int DEFAULT_HTTPS_PORT = 443; | 1170 static const int DEFAULT_HTTPS_PORT = 443; |
1073 | 1171 |
1074 /** | 1172 /** |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1339 * trying to establish a new connection after calling [shutdown] | 1437 * trying to establish a new connection after calling [shutdown] |
1340 * will throw an exception. | 1438 * will throw an exception. |
1341 */ | 1439 */ |
1342 void close({bool force: false}); | 1440 void close({bool force: false}); |
1343 } | 1441 } |
1344 | 1442 |
1345 | 1443 |
1346 /** | 1444 /** |
1347 * HTTP request for a client connection. | 1445 * HTTP request for a client connection. |
1348 * | 1446 * |
1349 * This object has a number of properties for setting up the HTTP | 1447 * To set up a request, set the headers using one of the many properties |
Søren Gjesse
2014/03/25 10:27:26
The headers is not set using 'one of the many prop
mem
2014/03/25 17:30:49
Done.
| |
1350 * header of the request. When the header has been set up the methods | 1448 * provided in this class and write the data to the body of the request. |
1351 * from the [IOSink] can be used to write the actual body of the HTTP | 1449 * HttpClientRequest is an [IOSink]. Use one of the methods from IOSink, |
Søren Gjesse
2014/03/25 10:27:26
Remove 'one of' as you can use several in combinat
mem
2014/03/25 17:30:49
Done.
| |
1352 * request. When one of the [IOSink] methods is used for the first | 1450 * such as writeCharCode(), to write the body of the HTTP |
1353 * time the request header is send. Calling any methods that will | 1451 * request. When one of the IOSink methods is used for the first |
1354 * change the header after it is sent will throw an exception. | 1452 * time, the request header is sent. Calling any methods that |
1453 * change the header after it is sent throws an exception. | |
1355 * | 1454 * |
1356 * When writing string data through the [IOSink] the | 1455 * When writing string data through the [IOSink] the |
1357 * encoding used will be determined from the "charset" parameter of | 1456 * encoding used is determined from the "charset" parameter of |
1358 * the "Content-Type" header. | 1457 * the "Content-Type" header. |
1359 * | 1458 * |
1360 * HttpClientRequest request = ... | 1459 * HttpClientRequest request = ... |
1361 * request.headers.contentType | 1460 * request.headers.contentType |
1362 * = new ContentType("application", "json", charset: "utf-8"); | 1461 * = new ContentType("application", "json", charset: "utf-8"); |
1363 * request.write(...); // Strings written will be UTF-8 encoded. | 1462 * request.write(...); // Strings written will be UTF-8 encoded. |
1364 * | 1463 * |
1365 * If no charset is provided the default of ISO-8859-1 (Latin 1) will | 1464 * If no charset is provided the default of ISO-8859-1 (Latin 1) is |
1366 * be used. | 1465 * be used. |
1367 * | 1466 * |
1368 * HttpClientRequest request = ... | 1467 * HttpClientRequest request = ... |
1369 * request.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); | 1468 * request.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); |
1370 * request.write(...); // Strings written will be ISO-8859-1 encoded. | 1469 * request.write(...); // Strings written will be ISO-8859-1 encoded. |
1371 * | 1470 * |
1372 * If an unsupported encoding is used an exception will be thrown if | 1471 * An exception is thrown if you use an unsupported encoding and the |
1373 * using one of the write methods taking a string. | 1472 * `write()` method being used takes a string parameter. |
1374 */ | 1473 */ |
1375 abstract class HttpClientRequest implements IOSink { | 1474 abstract class HttpClientRequest implements IOSink { |
1376 /** | 1475 /** |
1377 * Gets and sets the requested persistent connection state. | 1476 * Gets and sets the requested persistent connection state. |
1378 * | 1477 * |
1379 * The default value is [:true:]. | 1478 * The default value is [:true:]. |
1380 */ | 1479 */ |
1381 bool persistentConnection; | 1480 bool persistentConnection; |
1382 | 1481 |
1383 /** | 1482 /** |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1450 | 1549 |
1451 /** | 1550 /** |
1452 * Get information about the client connection. Returns [:null:] if the socket | 1551 * Get information about the client connection. Returns [:null:] if the socket |
1453 * is not available. | 1552 * is not available. |
1454 */ | 1553 */ |
1455 HttpConnectionInfo get connectionInfo; | 1554 HttpConnectionInfo get connectionInfo; |
1456 } | 1555 } |
1457 | 1556 |
1458 | 1557 |
1459 /** | 1558 /** |
1460 * HTTP response for a client connection. The [HttpClientResponse] is a | 1559 * HTTP response for a client connection. |
1461 * [Stream] of the body content of the response. Listen to the body to handle | 1560 |
1462 * the data and be notified once the entire body is received. | 1561 * The body of a [HttpClientResponse] object is a |
1562 * [Stream] of data from the server. Listen to the body to handle | |
1563 * the data and be notified when the entire body is received. | |
1564 * | |
1565 * new HttpClient().post('localhost', 80, '/file.txt') | |
Søren Gjesse
2014/03/25 10:27:26
Use get here to avoid data in the request.
mem
2014/03/25 17:30:49
Done.
mem
2014/03/25 17:30:49
Done.
| |
1566 * .then( ... ) | |
Søren Gjesse
2014/03/25 10:27:26
Change
.then( ... )
to
.then((HttpClientReq
mem
2014/03/25 17:30:49
Done.
| |
1567 * .then((HttpClientResponse response) { | |
1568 * response.transform(UTF8.decoder).listen((contents) { | |
1569 * // handle data | |
1570 * }); | |
1571 * }); | |
1463 */ | 1572 */ |
1464 abstract class HttpClientResponse implements Stream<List<int>> { | 1573 abstract class HttpClientResponse implements Stream<List<int>> { |
1465 /** | 1574 /** |
1466 * Returns the status code. | 1575 * Returns the status code. |
1467 */ | 1576 */ |
1468 int get statusCode; | 1577 int get statusCode; |
1469 | 1578 |
1470 /** | 1579 /** |
1471 * Returns the reason phrase associated with the status code. | 1580 * Returns the reason phrase associated with the status code. |
1472 */ | 1581 */ |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1643 class RedirectException implements HttpException { | 1752 class RedirectException implements HttpException { |
1644 final String message; | 1753 final String message; |
1645 final List<RedirectInfo> redirects; | 1754 final List<RedirectInfo> redirects; |
1646 | 1755 |
1647 const RedirectException(this.message, this.redirects); | 1756 const RedirectException(this.message, this.redirects); |
1648 | 1757 |
1649 String toString() => "RedirectException: $message"; | 1758 String toString() => "RedirectException: $message"; |
1650 | 1759 |
1651 Uri get uri => redirects.last.location; | 1760 Uri get uri => redirects.last.location; |
1652 } | 1761 } |
OLD | NEW |