11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4+ using System . Collections . ObjectModel ;
45using System . ComponentModel ;
56using System . Linq ;
67using Titanium . Web . Proxy . Models ;
@@ -10,23 +11,29 @@ namespace Titanium.Web.Proxy.Http
1011 [ TypeConverter ( typeof ( ExpandableObjectConverter ) ) ]
1112 public class HeaderCollection : IEnumerable < HttpHeader >
1213 {
14+ private readonly Dictionary < string , HttpHeader > headers ;
15+
16+ private readonly Dictionary < string , List < HttpHeader > > nonUniqueHeaders ;
17+
1318 /// <summary>
1419 /// Unique Request header collection
1520 /// </summary>
16- public Dictionary < string , HttpHeader > Headers { get ; }
21+ public ReadOnlyDictionary < string , HttpHeader > Headers { get ; }
1722
1823 /// <summary>
1924 /// Non Unique headers
2025 /// </summary>
21- public Dictionary < string , List < HttpHeader > > NonUniqueHeaders { get ; }
26+ public ReadOnlyDictionary < string , List < HttpHeader > > NonUniqueHeaders { get ; }
2227
2328 /// <summary>
2429 /// Initializes a new instance of the <see cref="HeaderCollection"/> class.
2530 /// </summary>
2631 public HeaderCollection ( )
2732 {
28- Headers = new Dictionary < string , HttpHeader > ( StringComparer . OrdinalIgnoreCase ) ;
29- NonUniqueHeaders = new Dictionary < string , List < HttpHeader > > ( StringComparer . OrdinalIgnoreCase ) ;
33+ headers = new Dictionary < string , HttpHeader > ( StringComparer . OrdinalIgnoreCase ) ;
34+ nonUniqueHeaders = new Dictionary < string , List < HttpHeader > > ( StringComparer . OrdinalIgnoreCase ) ;
35+ Headers = new ReadOnlyDictionary < string , HttpHeader > ( headers ) ;
36+ NonUniqueHeaders = new ReadOnlyDictionary < string , List < HttpHeader > > ( nonUniqueHeaders ) ;
3037 }
3138
3239 /// <summary>
@@ -36,7 +43,7 @@ public HeaderCollection()
3643 /// <returns></returns>
3744 public bool HeaderExists ( string name )
3845 {
39- return Headers . ContainsKey ( name ) || NonUniqueHeaders . ContainsKey ( name ) ;
46+ return headers . ContainsKey ( name ) || nonUniqueHeaders . ContainsKey ( name ) ;
4047 }
4148
4249 /// <summary>
@@ -47,32 +54,32 @@ public bool HeaderExists(string name)
4754 /// <returns></returns>
4855 public List < HttpHeader > GetHeaders ( string name )
4956 {
50- if ( Headers . ContainsKey ( name ) )
57+ if ( headers . ContainsKey ( name ) )
5158 {
5259 return new List < HttpHeader >
5360 {
54- Headers [ name ]
61+ headers [ name ]
5562 } ;
5663 }
5764
58- if ( NonUniqueHeaders . ContainsKey ( name ) )
65+ if ( nonUniqueHeaders . ContainsKey ( name ) )
5966 {
60- return new List < HttpHeader > ( NonUniqueHeaders [ name ] ) ;
67+ return new List < HttpHeader > ( nonUniqueHeaders [ name ] ) ;
6168 }
6269
6370 return null ;
6471 }
6572
6673 public HttpHeader GetFirstHeader ( string name )
6774 {
68- if ( Headers . TryGetValue ( name , out var header ) )
75+ if ( headers . TryGetValue ( name , out var header ) )
6976 {
7077 return header ;
7178 }
7279
73- if ( NonUniqueHeaders . TryGetValue ( name , out var headers ) )
80+ if ( nonUniqueHeaders . TryGetValue ( name , out var h ) )
7481 {
75- return headers . FirstOrDefault ( ) ;
82+ return h . FirstOrDefault ( ) ;
7683 }
7784
7885 return null ;
@@ -86,8 +93,8 @@ public List<HttpHeader> GetAllHeaders()
8693 {
8794 var result = new List < HttpHeader > ( ) ;
8895
89- result . AddRange ( Headers . Select ( x => x . Value ) ) ;
90- result . AddRange ( NonUniqueHeaders . SelectMany ( x => x . Value ) ) ;
96+ result . AddRange ( headers . Select ( x => x . Value ) ) ;
97+ result . AddRange ( nonUniqueHeaders . SelectMany ( x => x . Value ) ) ;
9198
9299 return result ;
93100 }
@@ -108,26 +115,29 @@ public void AddHeader(string name, string value)
108115 /// <param name="newHeader"></param>
109116 public void AddHeader ( HttpHeader newHeader )
110117 {
111- if ( NonUniqueHeaders . ContainsKey ( newHeader . Name ) )
118+ // if header exist in non-unique header collection add it there
119+ if ( nonUniqueHeaders . ContainsKey ( newHeader . Name ) )
112120 {
113- NonUniqueHeaders [ newHeader . Name ] . Add ( newHeader ) ;
121+ nonUniqueHeaders [ newHeader . Name ] . Add ( newHeader ) ;
114122 return ;
115123 }
116124
117- if ( Headers . ContainsKey ( newHeader . Name ) )
125+ // if header is already in unique header collection then move both to non-unique collection
126+ if ( headers . ContainsKey ( newHeader . Name ) )
118127 {
119- var existing = Headers [ newHeader . Name ] ;
120- Headers . Remove ( newHeader . Name ) ;
128+ var existing = headers [ newHeader . Name ] ;
129+ headers . Remove ( newHeader . Name ) ;
121130
122- NonUniqueHeaders . Add ( newHeader . Name , new List < HttpHeader >
131+ nonUniqueHeaders . Add ( newHeader . Name , new List < HttpHeader >
123132 {
124133 existing ,
125134 newHeader
126135 } ) ;
127136 }
128137 else
129138 {
130- Headers . Add ( newHeader . Name , newHeader ) ;
139+ // add to unique header collection
140+ headers . Add ( newHeader . Name , newHeader ) ;
131141 }
132142 }
133143
@@ -195,10 +205,10 @@ public void AddHeaders(IEnumerable<KeyValuePair<string, HttpHeader>> newHeaders)
195205 /// False if no header exists with given name</returns>
196206 public bool RemoveHeader ( string headerName )
197207 {
198- bool result = Headers . Remove ( headerName ) ;
208+ bool result = headers . Remove ( headerName ) ;
199209
200210 // do not convert to '||' expression to avoid lazy evaluation
201- if ( NonUniqueHeaders . Remove ( headerName ) )
211+ if ( nonUniqueHeaders . Remove ( headerName ) )
202212 {
203213 result = true ;
204214 }
@@ -212,17 +222,17 @@ public bool RemoveHeader(string headerName)
212222 /// <param name="header">Returns true if header exists and was removed </param>
213223 public bool RemoveHeader ( HttpHeader header )
214224 {
215- if ( Headers . ContainsKey ( header . Name ) )
225+ if ( headers . ContainsKey ( header . Name ) )
216226 {
217- if ( Headers [ header . Name ] . Equals ( header ) )
227+ if ( headers [ header . Name ] . Equals ( header ) )
218228 {
219- Headers . Remove ( header . Name ) ;
229+ headers . Remove ( header . Name ) ;
220230 return true ;
221231 }
222232 }
223- else if ( NonUniqueHeaders . ContainsKey ( header . Name ) )
233+ else if ( nonUniqueHeaders . ContainsKey ( header . Name ) )
224234 {
225- if ( NonUniqueHeaders [ header . Name ] . RemoveAll ( x => x . Equals ( header ) ) > 0 )
235+ if ( nonUniqueHeaders [ header . Name ] . RemoveAll ( x => x . Equals ( header ) ) > 0 )
226236 {
227237 return true ;
228238 }
@@ -236,13 +246,13 @@ public bool RemoveHeader(HttpHeader header)
236246 /// </summary>
237247 public void Clear ( )
238248 {
239- Headers . Clear ( ) ;
240- NonUniqueHeaders . Clear ( ) ;
249+ headers . Clear ( ) ;
250+ nonUniqueHeaders . Clear ( ) ;
241251 }
242252
243253 internal string GetHeaderValueOrNull ( string headerName )
244254 {
245- if ( Headers . TryGetValue ( headerName , out var header ) )
255+ if ( headers . TryGetValue ( headerName , out var header ) )
246256 {
247257 return header . Value ;
248258 }
@@ -252,13 +262,13 @@ internal string GetHeaderValueOrNull(string headerName)
252262
253263 internal void SetOrAddHeaderValue ( string headerName , string value )
254264 {
255- if ( Headers . TryGetValue ( headerName , out var header ) )
265+ if ( headers . TryGetValue ( headerName , out var header ) )
256266 {
257267 header . Value = value ;
258268 }
259269 else
260270 {
261- Headers . Add ( headerName , new HttpHeader ( headerName , value ) ) ;
271+ headers . Add ( headerName , new HttpHeader ( headerName , value ) ) ;
262272 }
263273 }
264274
@@ -285,7 +295,7 @@ internal void FixProxyHeaders()
285295 /// </returns>
286296 public IEnumerator < HttpHeader > GetEnumerator ( )
287297 {
288- return Headers . Values . Concat ( NonUniqueHeaders . Values . SelectMany ( x => x ) ) . GetEnumerator ( ) ;
298+ return headers . Values . Concat ( nonUniqueHeaders . Values . SelectMany ( x => x ) ) . GetEnumerator ( ) ;
289299 }
290300
291301 IEnumerator IEnumerable . GetEnumerator ( )
0 commit comments