1313// limitations under the License.
1414//
1515
16+ using System . Text ;
17+ using System . Text . RegularExpressions ;
18+
1619namespace RestSharp ;
1720
18- public record HeaderParameter : Parameter {
21+ public partial record HeaderParameter : Parameter {
1922 /// <summary>
2023 /// Instantiates a header parameter
2124 /// </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 )
2529 : 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 ) ,
2832 ParameterType . HttpHeader ,
2933 false
3034 ) { }
3135
3236 public new string Name => base . Name ! ;
3337 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
3483}
0 commit comments