PageRenderTime 12ms CodeModel.GetById 3ms app.highlight 7ms RepoModel.GetById 0ms app.codeStats 0ms

/WCFWebApi/src/System.Net.Http/System/Net/Http/Headers/HttpGeneralHeaders.cs

#
C# | 243 lines | 216 code | 22 blank | 5 comment | 29 complexity | fbfbe59b1584aa61d4715239cd88fc09 MD5 | raw file
  1using System.Collections.Generic;
  2using System.Diagnostics.Contracts;
  3
  4namespace System.Net.Http.Headers
  5{
  6    // The purpose of this type is to extract the handling of general headers in one place rather than duplicating
  7    // functionality in both HttpRequestHeaders and HttpResponseHeaders. The original approach was to have these two
  8    // types derive from HttpGeneralHeaders. However, in order to keep the public API surface small, it was preferred
  9    // to have HttpRequestHeaders & HttpResponseHeaders derive from HttpHeaders.
 10    internal sealed class HttpGeneralHeaders
 11    {
 12        private HttpHeaderValueCollection<string> connection;
 13        private HttpHeaderValueCollection<string> trailer;
 14        private HttpHeaderValueCollection<TransferCodingHeaderValue> transferEncoding;
 15        private HttpHeaderValueCollection<ProductHeaderValue> upgrade;
 16        private HttpHeaderValueCollection<ViaHeaderValue> via;
 17        private HttpHeaderValueCollection<WarningHeaderValue> warning;
 18        private HttpHeaderValueCollection<NameValueHeaderValue> pragma;
 19        private HttpHeaders parent;
 20        private bool transferEncodingChunkedSet;
 21        private bool connectionCloseSet;
 22
 23        public CacheControlHeaderValue CacheControl
 24        {
 25            get { return (CacheControlHeaderValue)parent.GetParsedValues(HttpKnownHeaderNames.CacheControl); }
 26            set { parent.SetOrRemoveParsedValue(HttpKnownHeaderNames.CacheControl, value); }
 27        }
 28
 29        public HttpHeaderValueCollection<string> Connection
 30        {
 31            get { return ConnectionCore; }
 32        }
 33
 34        public bool? ConnectionClose
 35        {
 36            get
 37            {
 38                if (ConnectionCore.IsSpecialValueSet)
 39                {
 40                    return true;
 41                }
 42                if (connectionCloseSet)
 43                {
 44                    return false;
 45                }
 46                return null;
 47            }
 48            set
 49            {
 50                if (value == true)
 51                {
 52                    connectionCloseSet = true;
 53                    ConnectionCore.SetSpecialValue();
 54                }
 55                else
 56                {
 57                    connectionCloseSet = value != null;
 58                    ConnectionCore.RemoveSpecialValue();
 59                }
 60            }
 61        }
 62
 63        public DateTimeOffset? Date
 64        {
 65            get { return HeaderUtilities.GetDateTimeOffsetValue(HttpKnownHeaderNames.Date, parent); }
 66            set { parent.SetOrRemoveParsedValue(HttpKnownHeaderNames.Date, value); }
 67        }
 68
 69        public HttpHeaderValueCollection<NameValueHeaderValue> Pragma
 70        {
 71            get
 72            {
 73                if (pragma == null)
 74                {
 75                    pragma = new HttpHeaderValueCollection<NameValueHeaderValue>(HttpKnownHeaderNames.Pragma, parent);
 76                }
 77                return pragma;
 78            }
 79        }
 80
 81        public HttpHeaderValueCollection<string> Trailer
 82        {
 83            get
 84            {
 85                if (trailer == null)
 86                {
 87                    trailer = new HttpHeaderValueCollection<string>(HttpKnownHeaderNames.Trailer,
 88                        parent, HeaderUtilities.TokenValidator);
 89                }
 90                return trailer;
 91            }
 92        }
 93
 94        public HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncoding
 95        {
 96            get { return TransferEncodingCore; }
 97        }
 98
 99        public bool? TransferEncodingChunked
100        {
101            get
102            {
103                if (TransferEncodingCore.IsSpecialValueSet)
104                {
105                    return true;
106                }
107                if (transferEncodingChunkedSet)
108                {
109                    return false;
110                }
111                return null;
112            }
113            set
114            {
115                if (value == true)
116                {
117                    transferEncodingChunkedSet = true;
118                    TransferEncodingCore.SetSpecialValue();
119                }
120                else
121                {
122                    transferEncodingChunkedSet = value != null;
123                    TransferEncodingCore.RemoveSpecialValue();
124                }
125            }
126        }
127
128        public HttpHeaderValueCollection<ProductHeaderValue> Upgrade
129        {
130            get
131            {
132                if (upgrade == null)
133                {
134                    upgrade = new HttpHeaderValueCollection<ProductHeaderValue>(HttpKnownHeaderNames.Upgrade, parent);
135                }
136                return upgrade;
137            }
138        }
139
140        public HttpHeaderValueCollection<ViaHeaderValue> Via
141        {
142            get
143            {
144                if (via == null)
145                {
146                    via = new HttpHeaderValueCollection<ViaHeaderValue>(HttpKnownHeaderNames.Via, parent);
147                }
148                return via;
149            }
150        }
151
152        public HttpHeaderValueCollection<WarningHeaderValue> Warning
153        {
154            get
155            {
156                if (warning == null)
157                {
158                    warning = new HttpHeaderValueCollection<WarningHeaderValue>(HttpKnownHeaderNames.Warning, parent);
159                }
160                return warning;
161            }
162        }
163
164        private HttpHeaderValueCollection<string> ConnectionCore
165        {
166            get
167            {
168                if (connection == null)
169                {
170                    connection = new HttpHeaderValueCollection<string>(HttpKnownHeaderNames.Connection,
171                        parent, HeaderUtilities.ConnectionClose, HeaderUtilities.TokenValidator);
172                }
173                return connection;
174            }
175        }
176
177        private HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncodingCore
178        {
179            get
180            {
181                if (transferEncoding == null)
182                {
183                    transferEncoding = new HttpHeaderValueCollection<TransferCodingHeaderValue>(
184                        HttpKnownHeaderNames.TransferEncoding, parent, HeaderUtilities.TransferEncodingChunked);
185                }
186                return transferEncoding;
187            }
188        }
189
190        internal HttpGeneralHeaders(HttpHeaders parent)
191        {
192            Contract.Requires(parent != null);
193
194            this.parent = parent;
195        }
196
197        internal static void AddParsers(Dictionary<string, HttpHeaderParser> parserStore)
198        {
199            Contract.Requires(parserStore != null);
200
201            parserStore.Add(HttpKnownHeaderNames.CacheControl, CacheControlHeaderParser.Parser);
202            parserStore.Add(HttpKnownHeaderNames.Connection, GenericHeaderParser.TokenListParser);
203            parserStore.Add(HttpKnownHeaderNames.Date, DateHeaderParser.Parser);
204            parserStore.Add(HttpKnownHeaderNames.Pragma, GenericHeaderParser.MultipleValueNameValueParser);
205            parserStore.Add(HttpKnownHeaderNames.Trailer, GenericHeaderParser.TokenListParser);
206            parserStore.Add(HttpKnownHeaderNames.TransferEncoding, TransferCodingHeaderParser.MultipleValueParser);
207            parserStore.Add(HttpKnownHeaderNames.Upgrade, GenericHeaderParser.MultipleValueProductParser);
208            parserStore.Add(HttpKnownHeaderNames.Via, GenericHeaderParser.MultipleValueViaParser);
209            parserStore.Add(HttpKnownHeaderNames.Warning, GenericHeaderParser.MultipleValueWarningParser);
210        }
211
212        internal static void AddKnownHeaders(HashSet<string> headerSet)
213        {
214            Contract.Requires(headerSet != null);
215
216            headerSet.Add(HttpKnownHeaderNames.CacheControl);
217            headerSet.Add(HttpKnownHeaderNames.Connection);
218            headerSet.Add(HttpKnownHeaderNames.Date);
219            headerSet.Add(HttpKnownHeaderNames.Pragma);
220            headerSet.Add(HttpKnownHeaderNames.Trailer);
221            headerSet.Add(HttpKnownHeaderNames.TransferEncoding);
222            headerSet.Add(HttpKnownHeaderNames.Upgrade);
223            headerSet.Add(HttpKnownHeaderNames.Via);
224            headerSet.Add(HttpKnownHeaderNames.Warning);
225        }
226
227        internal void AddSpecialsFrom(HttpGeneralHeaders sourceHeaders)
228        {
229            // Copy special values, but do not overwrite
230            bool? chunked = TransferEncodingChunked;
231            if (!chunked.HasValue)
232            {
233                TransferEncodingChunked = sourceHeaders.TransferEncodingChunked;
234            }
235
236            bool? close = ConnectionClose;
237            if (!close.HasValue)
238            {
239                ConnectionClose = sourceHeaders.ConnectionClose;
240            }
241        }
242    }
243}