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 the default HTTP port. However, on most systems accessing |
| 67 * this requires super-user privileges. For local testing consider |
| 68 * using a non-reserved port (1024 and above). |
65 * | 69 * |
66 * Incomplete requests where all or parts of the header is missing, are | 70 * import 'dart:io'; |
67 * ignored and no exceptions or [HttpRequest] objects are generated for them. | 71 * |
68 * Likewise, when writing to a [HttpResponse], any [Socket] exceptions are | 72 * main() { |
| 73 * HttpServer |
| 74 * .bind(InternetAddress.ANY_IP_V6, 80) |
| 75 * .then((server) { |
| 76 * server.listen((HttpRequest request) { |
| 77 * request.response.write('Hello, world!'); |
| 78 * request.response.close(); |
| 79 * }); |
| 80 * }); |
| 81 * } |
| 82 * |
| 83 * Incomplete requests, in which all or part of the header is missing, are |
| 84 * ignored, and no exceptions or HttpRequest objects are generated for them. |
| 85 * Likewise, when writing to an HttpResponse, any [Socket] exceptions are |
69 * ignored and any future writes are ignored. | 86 * ignored and any future writes are ignored. |
70 * | 87 * |
71 * The [HttpRequest] exposes the request headers, and provides the request body, | 88 * 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 | 89 * 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. | 90 * when the server writes to the HttpResponse or closes it. |
74 * | 91 * |
75 * The following example shows how to bind a [HttpServer] to a IPv6 | 92 * ## Bind with a secure HTTPS connection |
76 * [InternetAddress] on port 80, and listening to requests. | |
77 * | 93 * |
78 * HttpServer.bind(InternetAddress.ANY_IP_V6, 80).then((server) { | 94 * Use [bindSecure] to create an HTTPS server. |
79 * server.listen((HttpRequest request) { | 95 * |
80 * // Handle requests. | 96 * The server presents a certificate to the client. In the following |
81 * }); | 97 * example, the certificate is named `localhost_cert` and comes from |
82 * }); | 98 * the database found in the `pkcert` directory. |
| 99 * |
| 100 * import 'dart:io'; |
| 101 * import "dart:isolate"; |
| 102 * |
| 103 * main() { |
| 104 * var testPkcertDatabase = Platform.script.resolve('pkcert') |
| 105 * .toFilePath(); |
| 106 * SecureSocket.initialize(database: testPkcertDatabase, |
| 107 * password: 'dartdart'); |
| 108 * |
| 109 * HttpServer |
| 110 * .bindSecure(InternetAddress.ANY_IP_V6, |
| 111 * 443, |
| 112 * certificateName: 'localhost_cert') |
| 113 * .then((server) { |
| 114 * server.listen((HttpRequest request) { |
| 115 * request.response.write('Hello, world!'); |
| 116 * request.response.close(); |
| 117 * }); |
| 118 * }); |
| 119 * } |
| 120 * |
| 121 * The certificate database is managed using the Mozilla certutil tool (see |
| 122 * [NSS Tools certutil](https://developer.mozilla.org/en-US/docs/NSS/tools/NSS_T
ools_certutil)). |
| 123 * Dart uses the NSS library to handle SSL, and the Mozilla certutil |
| 124 * must be used to manipulate the certificate database. |
| 125 * |
| 126 * ## Connect to a server socket |
| 127 * |
| 128 * You can use the [listenOn] constructor to attach an HTTP server to |
| 129 * a [ServerSocket]. |
| 130 * |
| 131 * import 'dart:io'; |
| 132 * |
| 133 * main() { |
| 134 * ServerSocket.bind(InternetAddress.ANY_IP_V6, 80) |
| 135 * .then((serverSocket) { |
| 136 * HttpServer httpserver = new HttpServer.listenOn(serverSocket); |
| 137 * serverSocket.listen((Socket socket) { |
| 138 * socket.write('Hello, client.'); |
| 139 * }); |
| 140 * }); |
| 141 * } |
| 142 * |
| 143 * ## Other resources |
| 144 * |
| 145 * * HttpServer is a Stream. Refer to the [Stream] class for information |
| 146 * about the streaming qualities of an HttpServer. |
| 147 * Pausing the subscription of the stream, pauses at the OS level. |
| 148 * |
| 149 * * The [http_server](https://pub.dartlang.org/packages/http_server) |
| 150 * package on pub.dartlang.org contains a set of high-level classes that, |
| 151 * together with this class, makes it easy to provide content through HTTP |
| 152 * servers. |
83 */ | 153 */ |
84 abstract class HttpServer implements Stream<HttpRequest> { | 154 abstract class HttpServer implements Stream<HttpRequest> { |
85 /** | 155 /** |
86 * Set and get the default value of the `Server` header for all responses | 156 * Set and get the default value of the `Server` header for all responses |
87 * generated by this [HttpServer]. By default, it's disabled. | 157 * generated by this [HttpServer]. By default, it's disabled. |
88 * | 158 * |
89 * If the serverHeader is set to `null`, no default `Server` header will be | 159 * If the serverHeader is set to `null`, no default `Server` header will be |
90 * added to each response. | 160 * added to each response. |
91 */ | 161 */ |
92 String serverHeader; | 162 String serverHeader; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 /** | 324 /** |
255 * Number of connections which are preparing to close. Note: These | 325 * Number of connections which are preparing to close. Note: These |
256 * connections are also part of the [:active:] count as they might | 326 * connections are also part of the [:active:] count as they might |
257 * still be sending data to the client before finally closing. | 327 * still be sending data to the client before finally closing. |
258 */ | 328 */ |
259 int closing = 0; | 329 int closing = 0; |
260 } | 330 } |
261 | 331 |
262 | 332 |
263 /** | 333 /** |
264 * Access to the HTTP headers for requests and responses. In some | 334 * Headers for HTTP requests and responses. |
265 * situations the headers will be immutable and the mutating methods | 335 * |
266 * will then throw exceptions. | 336 * In some situations, headers are immutable: |
| 337 * |
| 338 * * HttpRequest and HttpClientResponse always have immutable headers. |
| 339 * |
| 340 * * HttpResponse and HttpClientRequest have immutable headers |
| 341 * from the moment the body is written to. |
| 342 * |
| 343 * In these situations, the mutating methods throw exceptions. |
267 * | 344 * |
268 * For all operations on HTTP headers the header name is | 345 * For all operations on HTTP headers the header name is |
269 * case-insensitive. | 346 * case-insensitive. |
| 347 * |
| 348 * To set the value of a header use the `set()` method: |
| 349 * |
| 350 * request.headers.set(HttpHeaders.CACHE_CONTROL, |
| 351 'max-age=3600, must-revalidate'); |
| 352 * |
| 353 * To retrieve the value of a header use the `value()` method: |
| 354 * |
| 355 * print(request.headers.value(HttpHeaders.USER_AGENT)); |
| 356 * |
| 357 * An HttpHeaders object holds a list of values for each name |
| 358 * as the standard allows. In most cases a name holds only a single value, |
| 359 * The most common mode of operation is to use `set()` for setting a value, |
| 360 * and `value()` for retrieving a value. |
270 */ | 361 */ |
271 abstract class HttpHeaders { | 362 abstract class HttpHeaders { |
272 static const ACCEPT = "accept"; | 363 static const ACCEPT = "accept"; |
273 static const ACCEPT_CHARSET = "accept-charset"; | 364 static const ACCEPT_CHARSET = "accept-charset"; |
274 static const ACCEPT_ENCODING = "accept-encoding"; | 365 static const ACCEPT_ENCODING = "accept-encoding"; |
275 static const ACCEPT_LANGUAGE = "accept-language"; | 366 static const ACCEPT_LANGUAGE = "accept-language"; |
276 static const ACCEPT_RANGES = "accept-ranges"; | 367 static const ACCEPT_RANGES = "accept-ranges"; |
277 static const AGE = "age"; | 368 static const AGE = "age"; |
278 static const ALLOW = "allow"; | 369 static const ALLOW = "allow"; |
279 static const AUTHORIZATION = "authorization"; | 370 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. | 843 * which listens for HTTP requests on a specific host and port. |
753 * For each request received, the HttpServer, which is a [Stream], | 844 * For each request received, the HttpServer, which is a [Stream], |
754 * generates an `HttpRequest` object and adds it to the stream. | 845 * generates an `HttpRequest` object and adds it to the stream. |
755 * | 846 * |
756 * An `HttpRequest` object delivers the body content of the request | 847 * An `HttpRequest` object delivers the body content of the request |
757 * as a stream of byte lists. | 848 * as a stream of byte lists. |
758 * The object also contains information about the request, | 849 * The object also contains information about the request, |
759 * such as the method, URI, and headers. | 850 * such as the method, URI, and headers. |
760 * | 851 * |
761 * In the following code, an HttpServer listens | 852 * In the following code, an HttpServer listens |
762 * for HTTP requests and, within the callback function, | 853 * for HTTP requests. When the server receives a request, |
763 * uses the `HttpRequest` object's `method` property to dispatch requests. | 854 * it uses the HttpRequest object's `method` property to dispatch requests. |
764 * | 855 * |
765 * final HOST = InternetAddress.LOOPBACK_IP_V4; | 856 * final HOST = InternetAddress.LOOPBACK_IP_V4; |
766 * final PORT = 4040; | 857 * final PORT = 80; |
767 * | 858 * |
768 * HttpServer.bind(HOST, PORT).then((_server) { | 859 * HttpServer.bind(HOST, PORT).then((_server) { |
769 * _server.listen((HttpRequest request) { | 860 * _server.listen((HttpRequest request) { |
770 * switch (request.method) { | 861 * switch (request.method) { |
771 * case 'GET': | 862 * case 'GET': |
772 * handleGetRequest(request); | 863 * handleGetRequest(request); |
773 * break; | 864 * break; |
774 * case 'POST': | 865 * case 'POST': |
775 * ... | 866 * ... |
776 * } | 867 * } |
777 * }, | 868 * }, |
778 * onError: handleError); // listen() failed. | 869 * onError: handleError); // listen() failed. |
779 * }).catchError(handleError); | 870 * }).catchError(handleError); |
780 * | 871 * |
781 * Listen to the `HttpRequest` stream to handle the | 872 * An HttpRequest object provides access to the associated [HttpResponse] |
782 * data and be notified once the entire body is received. | 873 * object through the response property. |
783 * An `HttpRequest` object contains an [HttpResponse] object, | 874 * The server writes its response to the body of the HttpResponse object. |
784 * to which the server can write its response. | 875 * For example, here's a function that responds to a request: |
785 * For example, here's a skeletal callback function | |
786 * that responds to a request: | |
787 * | 876 * |
788 * void handleGetRequest(HttpRequest req) { | 877 * void handleGetRequest(HttpRequest req) { |
789 * HttpResponse res = req.response; | 878 * HttpResponse res = req.response; |
790 * var body = []; | 879 * var body = []; |
791 * req.listen((List<int> buffer) => body.add(buffer), | 880 * req.listen((List<int> buffer) => body.add(buffer), |
792 * onDone: () { | 881 * onDone: () { |
793 * res.write('Received ${body.length} for request '); | 882 * res.write('Received ${body.length} for request '); |
794 * res.write(' ${req.method}: ${req.uri.path}'); | 883 * res.write(' ${req.method}: ${req.uri.path}'); |
795 * res.close(); | 884 * res.close(); |
796 * }, | 885 * }, |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 * | 975 * |
887 * If the [contentLength] of the body isn't 0, and the body isn't being read, | 976 * 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 | 977 * any write calls on the [HttpResponse] automatically drain the request |
889 * body. | 978 * body. |
890 */ | 979 */ |
891 HttpResponse get response; | 980 HttpResponse get response; |
892 } | 981 } |
893 | 982 |
894 | 983 |
895 /** | 984 /** |
896 * An [HttpResponse] represents the headers and data to be returned to | 985 * An HTTP response, which returns the headers and data |
897 * a client in response to an HTTP request. | 986 * from the server to the client in response to an HTTP request. |
898 * | 987 * |
899 * This object has a number of properties for setting up the HTTP | 988 * Every HttpRequest object provides access to the associated [HttpResponse] |
900 * header of the response. When the header has been set up the methods | 989 * object through the `response` property. |
901 * from the [IOSink] can be used to write the actual body of the HTTP | 990 * The server sends its response to the client by writing to the |
902 * response. When one of the [IOSink] methods is used for the | 991 * HttpResponse object. |
903 * first time the request header is send. Calling any methods that | |
904 * will change the header after it is sent will throw an exception. | |
905 * | 992 * |
906 * When writing string data through the [IOSink] the encoding used | 993 * ## Writing the response |
907 * will be determined from the "charset" parameter of the | 994 * |
| 995 * This class implements [IOSink]. |
| 996 * After the header has been set up, the methods |
| 997 * from IOSink, such as `writeln()`, can be used to write |
| 998 * the body of the HTTP response. |
| 999 * Use the `close()` method to close the response and send it to the client. |
| 1000 * |
| 1001 * server.listen((HttpRequest request) { |
| 1002 * request.response.write('Hello, world!'); |
| 1003 * request.response.close(); |
| 1004 * }); |
| 1005 * |
| 1006 * When one of the IOSink methods is used for the |
| 1007 * first time, the request header is sent. Calling any methods that |
| 1008 * change the header after it is sent throws an exception. |
| 1009 * |
| 1010 * ## Setting the headers |
| 1011 * |
| 1012 * The HttpResponse object has a number of properties for setting up |
| 1013 * the HTTP headers of the response. |
| 1014 * When writing string data through the IOSink, the encoding used |
| 1015 * is determined from the "charset" parameter of the |
908 * "Content-Type" header. | 1016 * "Content-Type" header. |
909 * | 1017 * |
910 * HttpResponse response = ... | 1018 * HttpResponse response = ... |
911 * response.headers.contentType | 1019 * response.headers.contentType |
912 * = new ContentType("application", "json", charset: "utf-8"); | 1020 * = new ContentType("application", "json", charset: "utf-8"); |
913 * response.write(...); // Strings written will be UTF-8 encoded. | 1021 * response.write(...); // Strings written will be UTF-8 encoded. |
914 * | 1022 * |
915 * If no charset is provided the default of ISO-8859-1 (Latin 1) will | 1023 * If no charset is provided the default of ISO-8859-1 (Latin 1) will |
916 * be used. | 1024 * be used. |
917 * | 1025 * |
918 * HttpResponse response = ... | 1026 * HttpResponse response = ... |
919 * response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); | 1027 * response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); |
920 * response.write(...); // Strings written will be ISO-8859-1 encoded. | 1028 * response.write(...); // Strings written will be ISO-8859-1 encoded. |
921 * | 1029 * |
922 * If an unsupported encoding is used an exception will be thrown if | 1030 * An exception is thrown if you use the `write()` method |
923 * using one of the write methods taking a string. | 1031 * while an unsupported content-type is set. |
924 */ | 1032 */ |
925 abstract class HttpResponse implements IOSink { | 1033 abstract class HttpResponse implements IOSink { |
926 // TODO(ajohnsen): Add documentation of how to pipe a file to the response. | 1034 // TODO(ajohnsen): Add documentation of how to pipe a file to the response. |
927 /** | 1035 /** |
928 * Gets and sets the content length of the response. If the size of | 1036 * 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 | 1037 * the response is not known in advance set the content length to |
930 * -1 - which is also the default if not set. | 1038 * -1 - which is also the default if not set. |
931 */ | 1039 */ |
932 int contentLength; | 1040 int contentLength; |
933 | 1041 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 * socket is not available. | 1112 * socket is not available. |
1005 */ | 1113 */ |
1006 HttpConnectionInfo get connectionInfo; | 1114 HttpConnectionInfo get connectionInfo; |
1007 } | 1115 } |
1008 | 1116 |
1009 | 1117 |
1010 /** | 1118 /** |
1011 * A client that receives content, such as web pages, from | 1119 * A client that receives content, such as web pages, from |
1012 * a server using the HTTP protocol. | 1120 * a server using the HTTP protocol. |
1013 * | 1121 * |
1014 * HttpClient contains a number of methods to send a HTTP request | 1122 * HttpClient contains a number of methods to send an [HttpClientRequest] |
1015 * to a HTTP server and receive a HTTP response back. | 1123 * to an Http server and receive an [HttpClientResponse] back. |
| 1124 * For example, you can use the [get], [getUrl], [post], and [postUrl] methods |
| 1125 * for GET and POST requests, respectively. |
1016 * | 1126 * |
1017 * This is a two-step process, triggered by two futures. When the | 1127 * ## 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 * | 1128 * |
1023 * The second future, which is returned by [:close:], completes with | 1129 * A `getUrl` request is a two-step process, triggered by two [Future]s. |
1024 * an [HttpClientResponse] object when the response is received from | 1130 * When the first future completes with a [HttpClientRequest], the underlying |
1025 * the server. This object contains the headers and body of the | 1131 * network connection has been established, but no data has been sent. |
1026 * response. | 1132 * In the callback function for the first future, the HTTP headers and body |
1027 | 1133 * can be set on the request. Either the first write to the request object |
1028 * The future for [HttpClientRequest] is created by methods such as | 1134 * or a call to [close] sends the request to the server. |
1029 * [getUrl] and [open]. | |
1030 * | 1135 * |
1031 * When the HTTP response is ready a [HttpClientResponse] object is | 1136 * When the HTTP response is received from the server, |
1032 * provided which provides access to the headers and body of the response. The | 1137 * the second future, which is returned by close, |
1033 * body is available as a stream implemented by [HttpClientResponse]. | 1138 * completes with an [HttpClientResponse] object. |
1034 * If a body is present, it must be read. Otherwise, it'll lead to a resource | 1139 * This object provides access to the headers and body of the response. |
| 1140 * The body is available as a stream implemented by HttpClientResponse. |
| 1141 * If a body is present, it must be read. Otherwise, it leads to resource |
1035 * leaks. Consider using [HttpClientResponse.drain] if the body is unused. | 1142 * leaks. Consider using [HttpClientResponse.drain] if the body is unused. |
1036 * | 1143 * |
1037 * HttpClient client = new HttpClient(); | 1144 * HttpClient client = new HttpClient(); |
1038 * client.getUrl(Uri.parse("http://www.example.com/")) | 1145 * client.getUrl(Uri.parse("http://www.example.com/")) |
1039 * .then((HttpClientRequest request) { | 1146 * .then((HttpClientRequest request) { |
1040 * // Prepare the request then call close on it to send it. | 1147 * // Optionally set up headers... |
| 1148 * // Optionally write to the request object... |
| 1149 * // Then call close. |
| 1150 * ... |
1041 * return request.close(); | 1151 * return request.close(); |
1042 * }) | 1152 * }) |
1043 * .then((HttpClientResponse response) { | 1153 * .then((HttpClientResponse response) { |
1044 * // Process the response. | 1154 * // Process the response. |
| 1155 * ... |
1045 * }); | 1156 * }); |
1046 * | 1157 * |
1047 * All [HttpClient] requests set the following header by default: | 1158 * The future for [HttpClientRequest] is created by methods such as |
| 1159 * [getUrl] and [open]. |
| 1160 * |
| 1161 * ## Headers |
| 1162 * |
| 1163 * All HttpClient requests set the following header by default: |
1048 * | 1164 * |
1049 * Accept-Encoding: gzip | 1165 * Accept-Encoding: gzip |
1050 * | 1166 * |
1051 * This allows the HTTP server to use gzip compression for the body if | 1167 * This allows the HTTP server to use gzip compression for the body if |
1052 * possible. If this behavior is not desired set the | 1168 * possible. If this behavior is not desired set the |
1053 * "Accept-Encoding" header to something else. | 1169 * `Accept-Encoding` header to something else. |
| 1170 * To turn off gzip compression of the response, clear this header: |
1054 * | 1171 * |
1055 * The [HttpClient] supports persistent connections and caches network | 1172 * request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING) |
1056 * connections to reuse then for multiple requests whenever | 1173 * |
| 1174 * ## Closing the HttpClient |
| 1175 * |
| 1176 * The HttpClient supports persistent connections and caches network |
| 1177 * connections to reuse them for multiple requests whenever |
1057 * possible. This means that network connections can be kept open for | 1178 * possible. This means that network connections can be kept open for |
1058 * some time after a request have completed. Use [:HttpClient.close:] | 1179 * some time after a request has completed. Use HttpClient.close |
1059 * to force shut down the [HttpClient] object and close the idle | 1180 * to force the HttpClient object to shut down and to close the idle |
1060 * network connections. | 1181 * network connections. |
1061 * | 1182 * |
| 1183 * ## Turning proxies on and off |
| 1184 * |
1062 * By default the HttpClient uses the proxy configuration available | 1185 * By default the HttpClient uses the proxy configuration available |
1063 * from the environment, see [findProxyFromEnvironment]. To turn off | 1186 * from the environment, see [findProxyFromEnvironment]. To turn off |
1064 * the use of proxies all together set the [findProxy] property to | 1187 * the use of proxies set the [findProxy] property to |
1065 * [:null:]. | 1188 * [:null:]. |
1066 * | 1189 * |
1067 * HttpClient client = new HttpClient(); | 1190 * HttpClient client = new HttpClient(); |
1068 * client.findProxy = null; | 1191 * client.findProxy = null; |
1069 */ | 1192 */ |
1070 abstract class HttpClient { | 1193 abstract class HttpClient { |
1071 static const int DEFAULT_HTTP_PORT = 80; | 1194 static const int DEFAULT_HTTP_PORT = 80; |
1072 static const int DEFAULT_HTTPS_PORT = 443; | 1195 static const int DEFAULT_HTTPS_PORT = 443; |
1073 | 1196 |
1074 /** | 1197 /** |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 * trying to establish a new connection after calling [shutdown] | 1462 * trying to establish a new connection after calling [shutdown] |
1340 * will throw an exception. | 1463 * will throw an exception. |
1341 */ | 1464 */ |
1342 void close({bool force: false}); | 1465 void close({bool force: false}); |
1343 } | 1466 } |
1344 | 1467 |
1345 | 1468 |
1346 /** | 1469 /** |
1347 * HTTP request for a client connection. | 1470 * HTTP request for a client connection. |
1348 * | 1471 * |
1349 * This object has a number of properties for setting up the HTTP | 1472 * To set up a request, set the headers using the headers property |
1350 * header of the request. When the header has been set up the methods | 1473 * 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 | 1474 * HttpClientRequest is an [IOSink]. Use the methods from IOSink, |
1352 * request. When one of the [IOSink] methods is used for the first | 1475 * such as writeCharCode(), to write the body of the HTTP |
1353 * time the request header is send. Calling any methods that will | 1476 * request. When one of the IOSink methods is used for the first |
1354 * change the header after it is sent will throw an exception. | 1477 * time, the request header is sent. Calling any methods that |
| 1478 * change the header after it is sent throws an exception. |
1355 * | 1479 * |
1356 * When writing string data through the [IOSink] the | 1480 * When writing string data through the [IOSink] the |
1357 * encoding used will be determined from the "charset" parameter of | 1481 * encoding used is determined from the "charset" parameter of |
1358 * the "Content-Type" header. | 1482 * the "Content-Type" header. |
1359 * | 1483 * |
1360 * HttpClientRequest request = ... | 1484 * HttpClientRequest request = ... |
1361 * request.headers.contentType | 1485 * request.headers.contentType |
1362 * = new ContentType("application", "json", charset: "utf-8"); | 1486 * = new ContentType("application", "json", charset: "utf-8"); |
1363 * request.write(...); // Strings written will be UTF-8 encoded. | 1487 * request.write(...); // Strings written will be UTF-8 encoded. |
1364 * | 1488 * |
1365 * If no charset is provided the default of ISO-8859-1 (Latin 1) will | 1489 * If no charset is provided the default of ISO-8859-1 (Latin 1) is |
1366 * be used. | 1490 * be used. |
1367 * | 1491 * |
1368 * HttpClientRequest request = ... | 1492 * HttpClientRequest request = ... |
1369 * request.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); | 1493 * request.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); |
1370 * request.write(...); // Strings written will be ISO-8859-1 encoded. | 1494 * request.write(...); // Strings written will be ISO-8859-1 encoded. |
1371 * | 1495 * |
1372 * If an unsupported encoding is used an exception will be thrown if | 1496 * An exception is thrown if you use an unsupported encoding and the |
1373 * using one of the write methods taking a string. | 1497 * `write()` method being used takes a string parameter. |
1374 */ | 1498 */ |
1375 abstract class HttpClientRequest implements IOSink { | 1499 abstract class HttpClientRequest implements IOSink { |
1376 /** | 1500 /** |
1377 * Gets and sets the requested persistent connection state. | 1501 * Gets and sets the requested persistent connection state. |
1378 * | 1502 * |
1379 * The default value is [:true:]. | 1503 * The default value is [:true:]. |
1380 */ | 1504 */ |
1381 bool persistentConnection; | 1505 bool persistentConnection; |
1382 | 1506 |
1383 /** | 1507 /** |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1450 | 1574 |
1451 /** | 1575 /** |
1452 * Get information about the client connection. Returns [:null:] if the socket | 1576 * Get information about the client connection. Returns [:null:] if the socket |
1453 * is not available. | 1577 * is not available. |
1454 */ | 1578 */ |
1455 HttpConnectionInfo get connectionInfo; | 1579 HttpConnectionInfo get connectionInfo; |
1456 } | 1580 } |
1457 | 1581 |
1458 | 1582 |
1459 /** | 1583 /** |
1460 * HTTP response for a client connection. The [HttpClientResponse] is a | 1584 * HTTP response for a client connection. |
1461 * [Stream] of the body content of the response. Listen to the body to handle | 1585 |
1462 * the data and be notified once the entire body is received. | 1586 * The body of a [HttpClientResponse] object is a |
| 1587 * [Stream] of data from the server. Listen to the body to handle |
| 1588 * the data and be notified when the entire body is received. |
| 1589 * |
| 1590 * new HttpClient().get('localhost', 80, '/file.txt') |
| 1591 * .then((HttpClientRequeset request) => request.close()) |
| 1592 * .then((HttpClientResponse response) { |
| 1593 * response.transform(UTF8.decoder).listen((contents) { |
| 1594 * // handle data |
| 1595 * }); |
| 1596 * }); |
1463 */ | 1597 */ |
1464 abstract class HttpClientResponse implements Stream<List<int>> { | 1598 abstract class HttpClientResponse implements Stream<List<int>> { |
1465 /** | 1599 /** |
1466 * Returns the status code. | 1600 * Returns the status code. |
1467 */ | 1601 */ |
1468 int get statusCode; | 1602 int get statusCode; |
1469 | 1603 |
1470 /** | 1604 /** |
1471 * Returns the reason phrase associated with the status code. | 1605 * Returns the reason phrase associated with the status code. |
1472 */ | 1606 */ |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 class RedirectException implements HttpException { | 1777 class RedirectException implements HttpException { |
1644 final String message; | 1778 final String message; |
1645 final List<RedirectInfo> redirects; | 1779 final List<RedirectInfo> redirects; |
1646 | 1780 |
1647 const RedirectException(this.message, this.redirects); | 1781 const RedirectException(this.message, this.redirects); |
1648 | 1782 |
1649 String toString() => "RedirectException: $message"; | 1783 String toString() => "RedirectException: $message"; |
1650 | 1784 |
1651 Uri get uri => redirects.last.location; | 1785 Uri get uri => redirects.last.location; |
1652 } | 1786 } |
OLD | NEW |