| 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 http_server; | 5 part of http_server; |
| 6 | 6 |
| 7 class _HttpBodyHandlerTransformer | 7 class _HttpBodyHandlerTransformer |
| 8 extends StreamEventTransformer<HttpRequest, HttpRequestBody> { | 8 extends StreamEventTransformer<HttpRequest, HttpRequestBody> { |
| 9 final Encoding _defaultEncoding; | 9 final Encoding _defaultEncoding; |
| 10 _HttpBodyHandlerTransformer(this._defaultEncoding); | 10 _HttpBodyHandlerTransformer(this._defaultEncoding); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 return stream | 46 return stream |
| 47 .fold(new BytesBuilder(), (builder, data) => builder..add(data)) | 47 .fold(new BytesBuilder(), (builder, data) => builder..add(data)) |
| 48 .then((builder) => new _HttpBody(contentType, | 48 .then((builder) => new _HttpBody(contentType, |
| 49 "binary", | 49 "binary", |
| 50 builder.takeBytes())); | 50 builder.takeBytes())); |
| 51 } | 51 } |
| 52 | 52 |
| 53 Future<HttpBody> asText(Encoding defaultEncoding) { | 53 Future<HttpBody> asText(Encoding defaultEncoding) { |
| 54 var encoding; | 54 var encoding; |
| 55 var charset = contentType.charset; | 55 var charset = contentType.charset; |
| 56 if (charset != null) encoding = Encoding.fromName(charset); | 56 if (charset != null) encoding = encodingFromName(charset); |
| 57 if (encoding == null) encoding = defaultEncoding; | 57 if (encoding == null) encoding = defaultEncoding; |
| 58 return stream | 58 return stream |
| 59 .transform(new StringDecoder(encoding)) | 59 .transform(encoding.decoder) |
| 60 .fold(new StringBuffer(), (buffer, data) => buffer..write(data)) | 60 .fold(new StringBuffer(), (buffer, data) => buffer..write(data)) |
| 61 .then((buffer) => new _HttpBody(contentType, | 61 .then((buffer) => new _HttpBody(contentType, |
| 62 "text", | 62 "text", |
| 63 buffer.toString())); | 63 buffer.toString())); |
| 64 } | 64 } |
| 65 | 65 |
| 66 Future<HttpBody> asFormData() { | 66 Future<HttpBody> asFormData() { |
| 67 return stream | 67 return stream |
| 68 .transform(new MimeMultipartTransformer( | 68 .transform(new MimeMultipartTransformer( |
| 69 contentType.parameters['boundary'])) | 69 contentType.parameters['boundary'])) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 100 return new _HttpBody(contentType, 'form', map); | 100 return new _HttpBody(contentType, 'form', map); |
| 101 }); | 101 }); |
| 102 } | 102 } |
| 103 | 103 |
| 104 if (contentType == null) { | 104 if (contentType == null) { |
| 105 return asBinary(); | 105 return asBinary(); |
| 106 } | 106 } |
| 107 | 107 |
| 108 switch (contentType.primaryType) { | 108 switch (contentType.primaryType) { |
| 109 case "text": | 109 case "text": |
| 110 return asText(Encoding.ASCII); | 110 return asText(ASCII); |
| 111 | 111 |
| 112 case "application": | 112 case "application": |
| 113 switch (contentType.subType) { | 113 switch (contentType.subType) { |
| 114 case "json": | 114 case "json": |
| 115 return asText(Encoding.UTF_8) | 115 return asText(UTF8) |
| 116 .then((body) => new _HttpBody(contentType, | 116 .then((body) => new _HttpBody(contentType, |
| 117 "json", | 117 "json", |
| 118 JSON.parse(body.body))); | 118 JSON.parse(body.body))); |
| 119 | 119 |
| 120 case "x-www-form-urlencoded": | 120 case "x-www-form-urlencoded": |
| 121 return asText(Encoding.ASCII) | 121 return asText(ASCII) |
| 122 .then((body) { | 122 .then((body) { |
| 123 var map = Uri.splitQueryString(body.body, | 123 var map = Uri.splitQueryString(body.body, |
| 124 decode: (s) => _decodeString(s, defaultEncoding)); | 124 decode: (s) => defaultEncoding.decode(s)); |
| 125 var result = {}; | 125 var result = {}; |
| 126 for (var key in map.keys) { | 126 for (var key in map.keys) { |
| 127 result[key] = map[key]; | 127 result[key] = map[key]; |
| 128 } | 128 } |
| 129 return new _HttpBody(contentType, "form", result); | 129 return new _HttpBody(contentType, "form", result); |
| 130 }); | 130 }); |
| 131 | 131 |
| 132 default: | 132 default: |
| 133 break; | 133 break; |
| 134 } | 134 } |
| 135 break; | 135 break; |
| 136 | 136 |
| 137 case "multipart": | 137 case "multipart": |
| 138 switch (contentType.subType) { | 138 switch (contentType.subType) { |
| 139 case "form-data": | 139 case "form-data": |
| 140 return asFormData(); | 140 return asFormData(); |
| 141 | 141 |
| 142 default: | 142 default: |
| 143 break; | 143 break; |
| 144 } | 144 } |
| 145 break; | 145 break; |
| 146 | 146 |
| 147 default: | 147 default: |
| 148 break; | 148 break; |
| 149 } | 149 } |
| 150 | 150 |
| 151 return asBinary(); | 151 return asBinary(); |
| 152 } | 152 } |
| 153 | |
| 154 // Utility function to synchronously decode a list of bytes. | |
| 155 static String _decodeString(List<int> bytes, | |
| 156 [Encoding encoding = Encoding.UTF_8]) { | |
| 157 if (bytes.length == 0) return ""; | |
| 158 var string; | |
| 159 var error; | |
| 160 var controller = new StreamController(sync: true); | |
| 161 controller.stream | |
| 162 .transform(new StringDecoder(encoding)) | |
| 163 .listen((data) => string = data, | |
| 164 onError: (e) => error = e); | |
| 165 controller.add(bytes); | |
| 166 controller.close(); | |
| 167 if (error != null) throw error; | |
| 168 assert(string != null); | |
| 169 return string; | |
| 170 } | |
| 171 } | 153 } |
| 172 | 154 |
| 173 class _HttpBodyFileUpload implements HttpBodyFileUpload { | 155 class _HttpBodyFileUpload implements HttpBodyFileUpload { |
| 174 final ContentType contentType; | 156 final ContentType contentType; |
| 175 final String filename; | 157 final String filename; |
| 176 final dynamic content; | 158 final dynamic content; |
| 177 _HttpBodyFileUpload(this.contentType, this.filename, this.content); | 159 _HttpBodyFileUpload(this.contentType, this.filename, this.content); |
| 178 } | 160 } |
| 179 | 161 |
| 180 class _HttpBody implements HttpBody { | 162 class _HttpBody implements HttpBody { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 208 _HttpClientResponseBody(HttpClientResponse response, HttpBody body) | 190 _HttpClientResponseBody(HttpClientResponse response, HttpBody body) |
| 209 : super(body.contentType, body.type, body.body), | 191 : super(body.contentType, body.type, body.body), |
| 210 this.response = response; | 192 this.response = response; |
| 211 | 193 |
| 212 int get statusCode => response.statusCode; | 194 int get statusCode => response.statusCode; |
| 213 | 195 |
| 214 String get reasonPhrase => response.reasonPhrase; | 196 String get reasonPhrase => response.reasonPhrase; |
| 215 | 197 |
| 216 HttpHeaders get headers => response.headers; | 198 HttpHeaders get headers => response.headers; |
| 217 } | 199 } |
| OLD | NEW |