Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: mojo/public/dart/third_party/shelf/lib/src/message.dart

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2014, 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 shelf.message;
6
7 import 'dart:async';
8 import 'dart:convert';
9
10 import 'package:http_parser/http_parser.dart';
11
12 import 'body.dart';
13 import 'shelf_unmodifiable_map.dart';
14 import 'util.dart';
15
16 Body getBody(Message message) => message._body;
17
18 /// Represents logic shared between [Request] and [Response].
19 abstract class Message {
20 /// The HTTP headers.
21 ///
22 /// The value is immutable.
23 final Map<String, String> headers;
24
25 /// Extra context that can be used by for middleware and handlers.
26 ///
27 /// For requests, this is used to pass data to inner middleware and handlers;
28 /// for responses, it's used to pass data to outer middleware and handlers.
29 ///
30 /// Context properties that are used by a particular package should begin with
31 /// that package's name followed by a period. For example, if [logRequests]
32 /// wanted to take a prefix, its property name would be `"shelf.prefix"`,
33 /// since it's in the `shelf` package.
34 ///
35 /// The value is immutable.
36 final Map<String, Object> context;
37
38 /// The streaming body of the message.
39 ///
40 /// This can be read via [read] or [readAsString].
41 final Body _body;
42
43 /// Creates a new [Message].
44 ///
45 /// [body] is the response body. It may be either a [String], a
46 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String],
47 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to
48 /// UTF-8.
49 ///
50 /// If [headers] is `null`, it is treated as empty.
51 ///
52 /// If [encoding] is passed, the "encoding" field of the Content-Type header
53 /// in [headers] will be set appropriately. If there is no existing
54 /// Content-Type header, it will be set to "application/octet-stream".
55 Message(body, {Encoding encoding, Map<String, String> headers,
56 Map<String, Object> context})
57 : this._body = new Body(body, encoding),
58 this.headers = new ShelfUnmodifiableMap<String>(
59 _adjustHeaders(headers, encoding), ignoreKeyCase: true),
60 this.context = new ShelfUnmodifiableMap<Object>(context,
61 ignoreKeyCase: false);
62
63 /// The contents of the content-length field in [headers].
64 ///
65 /// If not set, `null`.
66 int get contentLength {
67 if (_contentLengthCache != null) return _contentLengthCache;
68 if (!headers.containsKey('content-length')) return null;
69 _contentLengthCache = int.parse(headers['content-length']);
70 return _contentLengthCache;
71 }
72 int _contentLengthCache;
73
74 /// The MIME type of the message.
75 ///
76 /// This is parsed from the Content-Type header in [headers]. It contains only
77 /// the MIME type, without any Content-Type parameters.
78 ///
79 /// If [headers] doesn't have a Content-Type header, this will be `null`.
80 String get mimeType {
81 var contentType = _contentType;
82 if (contentType == null) return null;
83 return contentType.mimeType;
84 }
85
86 /// The encoding of the message body.
87 ///
88 /// This is parsed from the "charset" parameter of the Content-Type header in
89 /// [headers].
90 ///
91 /// If [headers] doesn't have a Content-Type header or it specifies an
92 /// encoding that [dart:convert] doesn't support, this will be `null`.
93 Encoding get encoding {
94 var contentType = _contentType;
95 if (contentType == null) return null;
96 if (!contentType.parameters.containsKey('charset')) return null;
97 return Encoding.getByName(contentType.parameters['charset']);
98 }
99
100 /// The parsed version of the Content-Type header in [headers].
101 ///
102 /// This is cached for efficient access.
103 MediaType get _contentType {
104 if (_contentTypeCache != null) return _contentTypeCache;
105 if (!headers.containsKey('content-type')) return null;
106 _contentTypeCache = new MediaType.parse(headers['content-type']);
107 return _contentTypeCache;
108 }
109 MediaType _contentTypeCache;
110
111 /// Returns a [Stream] representing the body.
112 ///
113 /// Can only be called once.
114 Stream<List<int>> read() => _body.read();
115
116 /// Returns a [Future] containing the body as a String.
117 ///
118 /// If [encoding] is passed, that's used to decode the body.
119 /// Otherwise the encoding is taken from the Content-Type header. If that
120 /// doesn't exist or doesn't have a "charset" parameter, UTF-8 is used.
121 ///
122 /// This calls [read] internally, which can only be called once.
123 Future<String> readAsString([Encoding encoding]) {
124 if (encoding == null) encoding = this.encoding;
125 if (encoding == null) encoding = UTF8;
126 return encoding.decodeStream(read());
127 }
128
129 /// Creates a new [Message] by copying existing values and applying specified
130 /// changes.
131 Message change({Map<String, String> headers, Map<String, Object> context,
132 body});
133 }
134
135 /// Adds information about [encoding] to [headers].
136 ///
137 /// Returns a new map without modifying [headers].
138 Map<String, String> _adjustHeaders(
139 Map<String, String> headers, Encoding encoding) {
140 if (headers == null) headers = const {};
141 if (encoding == null) return headers;
142 if (headers['content-type'] == null) {
143 return addHeader(headers, 'content-type',
144 'application/octet-stream; charset=${encoding.name}');
145 }
146
147 var contentType = new MediaType.parse(headers['content-type']).change(
148 parameters: {'charset': encoding.name});
149 return addHeader(headers, 'content-type', contentType.toString());
150 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698