13
13
// limitations under the License.
14
14
//
15
15
16
+ using System . Text ;
17
+ using System . Text . RegularExpressions ;
18
+
16
19
namespace RestSharp ;
17
20
18
- public record HeaderParameter : Parameter {
21
+ public partial record HeaderParameter : Parameter {
19
22
/// <summary>
20
23
/// Instantiates a header parameter
21
24
/// </summary>
22
- /// <param name="name">Parameter name</param>
23
- /// <param name="value">Parameter value</param>
24
- public HeaderParameter ( string name , string value )
25
+ /// <param name="name">Header name</param>
26
+ /// <param name="value">Header value</param>
27
+ /// <param name="encode">Set to true to encode header value according to RFC 2047. Default is false.</param>
28
+ public HeaderParameter ( string name , string value , bool encode = false )
25
29
: base (
26
- Ensure . NotEmptyString ( name , nameof ( name ) ) ,
27
- Ensure . NotNull ( value , nameof ( value ) ) ,
30
+ EnsureValidHeaderString ( Ensure . NotEmptyString ( name , nameof ( name ) ) , "name" ) ,
31
+ EnsureValidHeaderValue ( name , value , encode ) ,
28
32
ParameterType . HttpHeader ,
29
33
false
30
34
) { }
31
35
32
36
public new string Name => base . Name ! ;
33
37
public new string Value => ( string ) base . Value ! ;
38
+
39
+ static string EnsureValidHeaderValue ( string name , string value , bool encode ) {
40
+ CheckAndThrowsForInvalidHost ( name , value ) ;
41
+
42
+ return EnsureValidHeaderString ( GetValue ( Ensure . NotNull ( value , nameof ( value ) ) , encode ) , "value" ) ;
43
+ }
44
+
45
+ static string EnsureValidHeaderString ( string value , string type )
46
+ => ! IsInvalidHeaderString ( value ) ? value : throw new ArgumentException ( $ "Invalid character found in header { type } : { value } ") ;
47
+
48
+ static string GetValue ( string value , bool encode ) => encode ? GetBase64EncodedHeaderValue ( value ) : value ;
49
+
50
+ static string GetBase64EncodedHeaderValue ( string value ) => $ "=?UTF-8?B?{ Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( value ) ) } ?=";
51
+
52
+ static bool IsInvalidHeaderString ( string stringValue ) {
53
+ // ReSharper disable once ForCanBeConvertedToForeach
54
+ for ( var i = 0 ; i < stringValue . Length ; i ++ ) {
55
+ switch ( stringValue [ i ] ) {
56
+ case '\t ' :
57
+ case '\r ' :
58
+ case '\n ' :
59
+ return true ;
60
+ }
61
+ }
62
+
63
+ return false ;
64
+ }
65
+
66
+ static readonly Regex PortSplitRegex = PartSplit ( ) ;
67
+
68
+ static void CheckAndThrowsForInvalidHost ( string name , string value ) {
69
+ if ( name == KnownHeaders . Host && InvalidHost ( value ) )
70
+ throw new ArgumentException ( "The specified value is not a valid Host header string." , nameof ( value ) ) ;
71
+
72
+ return ;
73
+
74
+ static bool InvalidHost ( string host ) => Uri . CheckHostName ( PortSplitRegex . Split ( host ) [ 0 ] ) == UriHostNameType . Unknown ;
75
+ }
76
+
77
+ #if NET7_0_OR_GREATER
78
+ [ GeneratedRegex ( @":\d+" ) ]
79
+ private static partial Regex PartSplit ( ) ;
80
+ #else
81
+ static Regex PartSplit ( ) => new ( @":\d+" ) ;
82
+ #endif
34
83
}
0 commit comments