6
6
using System . Diagnostics . Contracts ;
7
7
using System . Globalization ;
8
8
using System . Text ;
9
+ using Microsoft . Extensions . Primitives ;
9
10
10
11
namespace Microsoft . Net . Http . Headers
11
12
{
@@ -32,10 +33,10 @@ public class CacheControlHeaderValue
32
33
private static readonly HttpHeaderParser < CacheControlHeaderValue > Parser
33
34
= new GenericHeaderParser < CacheControlHeaderValue > ( true , GetCacheControlLength ) ;
34
35
35
- private static readonly Action < string > CheckIsValidTokenAction = CheckIsValidToken ;
36
+ private static readonly Action < StringSegment > CheckIsValidTokenAction = CheckIsValidToken ;
36
37
37
38
private bool _noCache ;
38
- private ICollection < string > _noCacheHeaders ;
39
+ private ICollection < StringSegment > _noCacheHeaders ;
39
40
private bool _noStore ;
40
41
private TimeSpan ? _maxAge ;
41
42
private TimeSpan ? _sharedMaxAge ;
@@ -46,7 +47,7 @@ private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser
46
47
private bool _onlyIfCached ;
47
48
private bool _public ;
48
49
private bool _private ;
49
- private ICollection < string > _privateHeaders ;
50
+ private ICollection < StringSegment > _privateHeaders ;
50
51
private bool _mustRevalidate ;
51
52
private bool _proxyRevalidate ;
52
53
private IList < NameValueHeaderValue > _extensions ;
@@ -62,13 +63,13 @@ public bool NoCache
62
63
set { _noCache = value ; }
63
64
}
64
65
65
- public ICollection < string > NoCacheHeaders
66
+ public ICollection < StringSegment > NoCacheHeaders
66
67
{
67
68
get
68
69
{
69
70
if ( _noCacheHeaders == null )
70
71
{
71
- _noCacheHeaders = new ObjectCollection < string > ( CheckIsValidTokenAction ) ;
72
+ _noCacheHeaders = new ObjectCollection < StringSegment > ( CheckIsValidTokenAction ) ;
72
73
}
73
74
return _noCacheHeaders ;
74
75
}
@@ -134,13 +135,13 @@ public bool Private
134
135
set { _private = value ; }
135
136
}
136
137
137
- public ICollection < string > PrivateHeaders
138
+ public ICollection < StringSegment > PrivateHeaders
138
139
{
139
140
get
140
141
{
141
142
if ( _privateHeaders == null )
142
143
{
143
- _privateHeaders = new ObjectCollection < string > ( CheckIsValidTokenAction ) ;
144
+ _privateHeaders = new ObjectCollection < StringSegment > ( CheckIsValidTokenAction ) ;
144
145
}
145
146
return _privateHeaders ;
146
147
}
@@ -259,13 +260,13 @@ public override bool Equals(object obj)
259
260
}
260
261
261
262
if ( ! HeaderUtilities . AreEqualCollections ( _noCacheHeaders , other . _noCacheHeaders ,
262
- StringComparer . OrdinalIgnoreCase ) )
263
+ StringSegmentComparer . OrdinalIgnoreCase ) )
263
264
{
264
265
return false ;
265
266
}
266
267
267
268
if ( ! HeaderUtilities . AreEqualCollections ( _privateHeaders , other . _privateHeaders ,
268
- StringComparer . OrdinalIgnoreCase ) )
269
+ StringSegmentComparer . OrdinalIgnoreCase ) )
269
270
{
270
271
return false ;
271
272
}
@@ -299,15 +300,15 @@ public override int GetHashCode()
299
300
{
300
301
foreach ( var noCacheHeader in _noCacheHeaders )
301
302
{
302
- result = result ^ StringComparer . OrdinalIgnoreCase . GetHashCode ( noCacheHeader ) ;
303
+ result = result ^ StringSegmentComparer . OrdinalIgnoreCase . GetHashCode ( noCacheHeader ) ;
303
304
}
304
305
}
305
306
306
307
if ( ( _privateHeaders != null ) && ( _privateHeaders . Count > 0 ) )
307
308
{
308
309
foreach ( var privateHeader in _privateHeaders )
309
310
{
310
- result = result ^ StringComparer . OrdinalIgnoreCase . GetHashCode ( privateHeader ) ;
311
+ result = result ^ StringSegmentComparer . OrdinalIgnoreCase . GetHashCode ( privateHeader ) ;
311
312
}
312
313
}
313
314
@@ -322,7 +323,7 @@ public override int GetHashCode()
322
323
return result ;
323
324
}
324
325
325
- public static CacheControlHeaderValue Parse ( string input )
326
+ public static CacheControlHeaderValue Parse ( StringSegment input )
326
327
{
327
328
int index = 0 ;
328
329
// Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null.
@@ -334,7 +335,7 @@ public static CacheControlHeaderValue Parse(string input)
334
335
return result ;
335
336
}
336
337
337
- public static bool TryParse ( string input , out CacheControlHeaderValue parsedValue )
338
+ public static bool TryParse ( StringSegment input , out CacheControlHeaderValue parsedValue )
338
339
{
339
340
int index = 0 ;
340
341
// Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null.
@@ -346,13 +347,13 @@ public static bool TryParse(string input, out CacheControlHeaderValue parsedValu
346
347
return false ;
347
348
}
348
349
349
- private static int GetCacheControlLength ( string input , int startIndex , out CacheControlHeaderValue parsedValue )
350
+ private static int GetCacheControlLength ( StringSegment input , int startIndex , out CacheControlHeaderValue parsedValue )
350
351
{
351
352
Contract . Requires ( startIndex >= 0 ) ;
352
353
353
354
parsedValue = null ;
354
355
355
- if ( string . IsNullOrEmpty ( input ) || ( startIndex >= input . Length ) )
356
+ if ( StringSegment . IsNullOrEmpty ( input ) || ( startIndex >= input . Length ) )
356
357
{
357
358
return 0 ;
358
359
}
@@ -403,7 +404,7 @@ private static bool TrySetCacheControlValues(
403
404
switch ( name . Length )
404
405
{
405
406
case 6 :
406
- if ( string . Equals ( PublicString , name , StringComparison . OrdinalIgnoreCase ) )
407
+ if ( StringSegment . Equals ( PublicString , name , StringComparison . OrdinalIgnoreCase ) )
407
408
{
408
409
success = TrySetTokenOnlyValue ( nameValue , ref cc . _public ) ;
409
410
}
@@ -414,11 +415,11 @@ private static bool TrySetCacheControlValues(
414
415
break ;
415
416
416
417
case 7 :
417
- if ( string . Equals ( MaxAgeString , name , StringComparison . OrdinalIgnoreCase ) )
418
+ if ( StringSegment . Equals ( MaxAgeString , name , StringComparison . OrdinalIgnoreCase ) )
418
419
{
419
420
success = TrySetTimeSpan ( nameValue , ref cc . _maxAge ) ;
420
421
}
421
- else if ( string . Equals ( PrivateString , name , StringComparison . OrdinalIgnoreCase ) )
422
+ else if ( StringSegment . Equals ( PrivateString , name , StringComparison . OrdinalIgnoreCase ) )
422
423
{
423
424
success = TrySetOptionalTokenList ( nameValue , ref cc . _private , ref cc . _privateHeaders ) ;
424
425
}
@@ -429,15 +430,15 @@ private static bool TrySetCacheControlValues(
429
430
break ;
430
431
431
432
case 8 :
432
- if ( string . Equals ( NoCacheString , name , StringComparison . OrdinalIgnoreCase ) )
433
+ if ( StringSegment . Equals ( NoCacheString , name , StringComparison . OrdinalIgnoreCase ) )
433
434
{
434
435
success = TrySetOptionalTokenList ( nameValue , ref cc . _noCache , ref cc . _noCacheHeaders ) ;
435
436
}
436
- else if ( string . Equals ( NoStoreString , name , StringComparison . OrdinalIgnoreCase ) )
437
+ else if ( StringSegment . Equals ( NoStoreString , name , StringComparison . OrdinalIgnoreCase ) )
437
438
{
438
439
success = TrySetTokenOnlyValue ( nameValue , ref cc . _noStore ) ;
439
440
}
440
- else if ( string . Equals ( SharedMaxAgeString , name , StringComparison . OrdinalIgnoreCase ) )
441
+ else if ( StringSegment . Equals ( SharedMaxAgeString , name , StringComparison . OrdinalIgnoreCase ) )
441
442
{
442
443
success = TrySetTimeSpan ( nameValue , ref cc . _sharedMaxAge ) ;
443
444
}
@@ -448,15 +449,15 @@ private static bool TrySetCacheControlValues(
448
449
break ;
449
450
450
451
case 9 :
451
- if ( string . Equals ( MaxStaleString , name , StringComparison . OrdinalIgnoreCase ) )
452
+ if ( StringSegment . Equals ( MaxStaleString , name , StringComparison . OrdinalIgnoreCase ) )
452
453
{
453
454
success = ( ( nameValue . Value == null ) || TrySetTimeSpan ( nameValue , ref cc . _maxStaleLimit ) ) ;
454
455
if ( success )
455
456
{
456
457
cc . _maxStale = true ;
457
458
}
458
459
}
459
- else if ( string . Equals ( MinFreshString , name , StringComparison . OrdinalIgnoreCase ) )
460
+ else if ( StringSegment . Equals ( MinFreshString , name , StringComparison . OrdinalIgnoreCase ) )
460
461
{
461
462
success = TrySetTimeSpan ( nameValue , ref cc . _minFresh ) ;
462
463
}
@@ -467,7 +468,7 @@ private static bool TrySetCacheControlValues(
467
468
break ;
468
469
469
470
case 12 :
470
- if ( string . Equals ( NoTransformString , name , StringComparison . OrdinalIgnoreCase ) )
471
+ if ( StringSegment . Equals ( NoTransformString , name , StringComparison . OrdinalIgnoreCase ) )
471
472
{
472
473
success = TrySetTokenOnlyValue ( nameValue , ref cc . _noTransform ) ;
473
474
}
@@ -478,7 +479,7 @@ private static bool TrySetCacheControlValues(
478
479
break ;
479
480
480
481
case 14 :
481
- if ( string . Equals ( OnlyIfCachedString , name , StringComparison . OrdinalIgnoreCase ) )
482
+ if ( StringSegment . Equals ( OnlyIfCachedString , name , StringComparison . OrdinalIgnoreCase ) )
482
483
{
483
484
success = TrySetTokenOnlyValue ( nameValue , ref cc . _onlyIfCached ) ;
484
485
}
@@ -489,7 +490,7 @@ private static bool TrySetCacheControlValues(
489
490
break ;
490
491
491
492
case 15 :
492
- if ( string . Equals ( MustRevalidateString , name , StringComparison . OrdinalIgnoreCase ) )
493
+ if ( StringSegment . Equals ( MustRevalidateString , name , StringComparison . OrdinalIgnoreCase ) )
493
494
{
494
495
success = TrySetTokenOnlyValue ( nameValue , ref cc . _mustRevalidate ) ;
495
496
}
@@ -500,7 +501,7 @@ private static bool TrySetCacheControlValues(
500
501
break ;
501
502
502
503
case 16 :
503
- if ( string . Equals ( ProxyRevalidateString , name , StringComparison . OrdinalIgnoreCase ) )
504
+ if ( StringSegment . Equals ( ProxyRevalidateString , name , StringComparison . OrdinalIgnoreCase ) )
504
505
{
505
506
success = TrySetTokenOnlyValue ( nameValue , ref cc . _proxyRevalidate ) ;
506
507
}
@@ -538,7 +539,7 @@ private static bool TrySetTokenOnlyValue(NameValueHeaderValue nameValue, ref boo
538
539
private static bool TrySetOptionalTokenList (
539
540
NameValueHeaderValue nameValue ,
540
541
ref bool boolField ,
541
- ref ICollection < string > destination )
542
+ ref ICollection < StringSegment > destination )
542
543
{
543
544
Contract . Requires ( nameValue != null ) ;
544
545
@@ -582,10 +583,10 @@ private static bool TrySetOptionalTokenList(
582
583
583
584
if ( destination == null )
584
585
{
585
- destination = new ObjectCollection < string > ( CheckIsValidTokenAction ) ;
586
+ destination = new ObjectCollection < StringSegment > ( CheckIsValidTokenAction ) ;
586
587
}
587
588
588
- destination . Add ( valueString . Substring ( current , tokenLength ) ) ;
589
+ destination . Add ( valueString . Subsegment ( current , tokenLength ) ) ;
589
590
590
591
current = current + tokenLength ;
591
592
}
@@ -637,10 +638,10 @@ private static void AppendValueWithSeparatorIfRequired(StringBuilder sb, string
637
638
sb . Append ( value ) ;
638
639
}
639
640
640
- private static void AppendValues ( StringBuilder sb , IEnumerable < string > values )
641
+ private static void AppendValues ( StringBuilder sb , IEnumerable < StringSegment > values )
641
642
{
642
643
var first = true ;
643
- foreach ( string value in values )
644
+ foreach ( var value in values )
644
645
{
645
646
if ( first )
646
647
{
@@ -655,7 +656,7 @@ private static void AppendValues(StringBuilder sb, IEnumerable<string> values)
655
656
}
656
657
}
657
658
658
- private static void CheckIsValidToken ( string item )
659
+ private static void CheckIsValidToken ( StringSegment item )
659
660
{
660
661
HeaderUtilities . CheckValidToken ( item , nameof ( item ) ) ;
661
662
}
0 commit comments