2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 - 2023 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 ,  Kenneth  Myhra  < kennethmyhra @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 ,  Luke  Wilde  < lukew @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/Checked.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/GenericLexer.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/QuickSort.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/ScopeGuard.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-02-28 18:20:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/StringUtils.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-30 01:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Heap/Heap.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/VM.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibRegex/Regex.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-10 16:26:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibTextCodec/Decoder.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Fetch/Infrastructure/HTTP.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Fetch/Infrastructure/HTTP/Headers.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Fetch/Infrastructure/HTTP/Methods.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Infra/ByteSequences.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-24 09:23:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Loader/ResourceLoader.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/MimeSniff/MimeType.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 23:52:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web : : Fetch : : Infrastructure  {  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-06 10:16:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								JS_DEFINE_ALLOCATOR ( HeaderList ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								requires ( IsSameIgnoringCV < T ,  u8 > )  struct  CaseInsensitiveBytesTraits  :  public  Traits < Span < T > >  {  
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:18:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    static  constexpr  bool  equals ( Span < T >  const &  a ,  Span < T >  const &  b ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  StringView  {  a  } . equals_ignoring_ascii_case ( StringView  {  b  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:18:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    static  constexpr  unsigned  hash ( Span < T >  const &  span ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( span . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  AK : : case_insensitive_string_hash ( reinterpret_cast < char  const * > ( span . data ( ) ) ,  span . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Header  Header : : from_string_pair ( StringView  name ,  StringView  value )  
						 
					
						
							
								
									
										
										
										
											2022-10-24 09:16:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Header  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        . name  =  MUST ( ByteBuffer : : copy ( name . bytes ( ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        . value  =  MUST ( ByteBuffer : : copy ( value . bytes ( ) ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 09:16:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 01:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								JS : : NonnullGCPtr < HeaderList >  HeaderList : : create ( JS : : VM &  vm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-12-14 17:40:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  vm . heap ( ) . allocate_without_realm < HeaderList > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 01:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 21:40:30 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// Non-standard
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < ByteBuffer >  HeaderList : : unique_names ( )  const  
						 
					
						
							
								
									
										
										
										
											2023-08-01 21:40:30 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ByteBuffer >  header_names_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    HashTable < ReadonlyBytes ,  CaseInsensitiveBytesTraits < u8  const > >  header_names_seen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  header  :  * this )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( header_names_seen . contains ( header . name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        header_names_seen . set ( header . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        header_names_set . append ( MUST ( ByteBuffer : : copy ( header . name ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 21:40:30 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  header_names_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#header-list-contains
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  HeaderList : : contains ( ReadonlyBytes  name )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A header list list contains a header name name if list contains a header whose name is a byte-case-insensitive match for name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  any_of ( * this ,  [ & ] ( auto  const &  header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  StringView  {  header . name  } . equals_ignoring_ascii_case ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-get
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < ByteBuffer >  HeaderList : : get ( ReadonlyBytes  name )  const  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To get a header name name from a header list list, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If list does not contain name, then return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! contains ( name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Return the values of all headers in list whose name is a byte-case-insensitive match for name, separated from each other by 0x2C 0x20, in order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ByteBuffer  buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  header  :  * this )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! StringView  {  header . name  } . equals_ignoring_ascii_case ( name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            buffer . append ( 0x2c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            buffer . append ( 0x20 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        buffer . append ( header . value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Vector < String > >  HeaderList : : get_decode_and_split ( ReadonlyBytes  name )  const  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To get, decode, and split a header name name from header list list, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let value be the result of getting name from list.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  value  =  get ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If value is null, then return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! value . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Return the result of getting, decoding, and splitting value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  get_decode_and_split_header_value ( * value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#header-value-get-decode-and-split
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Vector < String > >  get_decode_and_split_header_value ( ReadonlyBytes  value )  
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To get, decode, and split a header value value, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let input be the result of isomorphic decoding value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  input  =  StringView  {  value  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let position be a position variable for input, initially pointing at the start of input.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  lexer  =  GenericLexer  {  input  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-25 21:19:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let values be a list of strings, initially « ».
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 23:26:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < String >  values ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Let temporaryValue be the empty string.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StringBuilder  temporary_value_builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-25 21:19:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. While true:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Append the result of collecting a sequence of code points that are not U+0022 (") or U+002C (,) from input, given position, to temporaryValue.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: The result might be the empty string.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        temporary_value_builder . append ( lexer . consume_until ( is_any_of ( " \" , " sv ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-25 21:19:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If position is not past the end of input and the code point at position within input is U+0022 ("):
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! lexer . is_eof ( )  & &  lexer . peek ( )  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 1. Append the result of collecting an HTTP quoted string from input, given position, to temporaryValue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            temporary_value_builder . append ( collect_an_http_quoted_string ( lexer ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 2. If position is not past the end of input, then continue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! lexer . is_eof ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Remove all HTTP tab or space from the start and end of temporaryValue.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  temporary_value  =  MUST ( String : : from_utf8 ( temporary_value_builder . string_view ( ) . trim ( HTTP_TAB_OR_SPACE ,  TrimMode : : Both ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. Append temporaryValue to values.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        values . append ( move ( temporary_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 5. Set temporaryValue to the empty string.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        temporary_value_builder . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-25 21:19:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 6. If position is past the end of input, then return values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( lexer . is_eof ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 7. Assert: the code point at position within input is U+002C (,).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( lexer . peek ( )  = =  ' , ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 8. Advance position by 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        lexer . ignore ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-append
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  HeaderList : : append ( Header  header )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To append a header (name, value) to a header list list, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Can't use structured bindings captured in the lambda due to https://github.com/llvm/llvm-project/issues/48582
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  name  =  header . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 1. If list contains name, then set name to the first such header’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: This reuses the casing of the name of the header already in list, if any. If there are multiple matched headers their names will all be identical.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( contains ( name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  matching_header  =  first_matching ( [ & ] ( auto  const &  existing_header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  StringView  {  existing_header . name  } . equals_ignoring_ascii_case ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        name . overwrite ( 0 ,  matching_header - > name . data ( ) ,  matching_header - > name . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Append (name, value) to list.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Header > : : append ( move ( header ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-delete
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  HeaderList : : delete_ ( ReadonlyBytes  name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To delete a header name name from a header list list, remove all headers whose name is a byte-case-insensitive match for name from list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    remove_all_matching ( [ & ] ( auto  const &  header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  StringView  {  header . name  } . equals_ignoring_ascii_case ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-set
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  HeaderList : : set ( Header  header )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To set a header (name, value) in a header list list, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Can't use structured bindings captured in the lambda due to https://github.com/llvm/llvm-project/issues/48582
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  name  =  header . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  value  =  header . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If list contains name, then set the value of the first such header to value and remove the others.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( contains ( name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  matching_index  =  find_if ( [ & ] ( auto  const &  existing_header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  StringView  {  existing_header . name  } . equals_ignoring_ascii_case ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) . index ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  matching_header  =  at ( matching_index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        matching_header . value  =  MUST ( ByteBuffer : : copy ( value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        size_t  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_all_matching ( [ & ] ( auto  const &  existing_header )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ScopeGuard  increment_i  =  [ & ] ( )  {  i + + ;  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( i  < =  matching_index ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  StringView  {  existing_header . name  } . equals_ignoring_ascii_case ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Otherwise, append header (name, value) to list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        append ( move ( header ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-combine
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  HeaderList : : combine ( Header  header )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To combine a header (name, value) in a header list list, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Can't use structured bindings captured in the lambda due to https://github.com/llvm/llvm-project/issues/48582
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  name  =  header . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  value  =  header . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If list contains name, then set the value of the first such header to its value, followed by 0x2C 0x20, followed by value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( contains ( name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  matching_header  =  first_matching ( [ & ] ( auto  const &  existing_header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  StringView  {  existing_header . name  } . equals_ignoring_ascii_case ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        matching_header - > value . append ( 0x2c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        matching_header - > value . append ( 0x20 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        matching_header - > value . append ( value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Otherwise, append (name, value) to list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        append ( move ( header ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:19:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < Header >  HeaderList : : sort_and_combine ( )  const  
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:19:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To sort and combine a header list list, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let headers be an empty list of headers with the key being the name and value the value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Header >  headers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let names be the result of convert header names to a sorted-lowercase set with all the names of the headers in list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ReadonlyBytes >  names_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    names_list . ensure_capacity ( size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:19:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  header  :  * this ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        names_list . unchecked_append ( header . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  names  =  convert_header_names_to_a_sorted_lowercase_set ( names_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:19:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:29:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. For each name of names:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:19:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  name  :  names )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If name is `set-cookie`, then:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name  = =  " set-cookie " sv . bytes ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 1. Let values be a list of all values of headers in list whose name is a byte-case-insensitive match for name, in order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 2. For each value of values:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  const &  [ header_name ,  value ]  :  * this )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( StringView  {  header_name  } . equals_ignoring_ascii_case ( name ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    // 1. Append (name, value) to headers.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  header  =  Header : : from_string_pair ( name ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    headers . append ( move ( header ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Otherwise:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 1. Let value be the result of getting name from list.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  value  =  get ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 2. Assert: value is not null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( value . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 3. Append (name, value) to headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  header  =  Header  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . name  =  move ( name ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  value . release_value ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            headers . append ( move ( header ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 22:02:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 00:19:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Return headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  headers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 18:20:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#header-list-extract-a-length
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								HeaderList : : ExtractLengthResult  HeaderList : : extract_length ( )  const  
						 
					
						
							
								
									
										
										
										
											2023-02-28 18:20:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let values be the result of getting, decoding, and splitting `Content-Length` from headers.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  values  =  get_decode_and_split ( " Content-Length " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 18:20:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If values is null, then return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! values . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let candidateValue be null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < String >  candidate_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. For each value of values:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  value  :  * values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If candidateValue is null, then set candidateValue to value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! candidate_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            candidate_value  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Otherwise, if value is not candidateValue, return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( candidate_value . value ( )  ! =  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ExtractLengthFailure  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If candidateValue is the empty string or has a code point that is not an ASCII digit, then return null.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-23 15:59:14 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: to_number does this for us.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 18:20:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. Return candidateValue, interpreted as decimal number.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: The spec doesn't say anything about trimming here, so we don't trim. If it contains a space, step 5 will cause us to return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This will return an empty Optional if it cannot fit into a u64, is this correct?
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-23 15:59:14 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  conversion_result  =  candidate_value . value ( ) . to_number < u64 > ( TrimWhitespace : : No ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 18:20:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! conversion_result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  ExtractLengthResult  {  conversion_result . release_value ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < MimeSniff : : MimeType >  HeaderList : : extract_mime_type ( )  const  
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let charset be null.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 23:26:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < String >  charset ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let essence be null.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 23:26:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < String >  essence ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let mimeType be null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < MimeSniff : : MimeType >  mime_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Let values be the result of getting, decoding, and splitting `Content-Type` from headers.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  values  =  get_decode_and_split ( " Content-Type " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If values is null, then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! values . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. For each value of values:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  value  :  * values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let temporaryMimeType be the result of parsing value.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-14 11:18:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  temporary_mime_type  =  MimeSniff : : MimeType : : parse ( value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If temporaryMimeType is failure or its essence is "*/*", then continue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! temporary_mime_type . has_value ( )  | |  temporary_mime_type - > essence ( )  = =  " */* " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Set mimeType to temporaryMimeType.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        mime_type  =  temporary_mime_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 4. If mimeType’  
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 23:26:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! essence . has_value ( )  | |  ( mime_type - > essence ( )  ! =  essence - > bytes_as_string_view ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // 1. Set charset to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            charset  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // 2. If mimeType’ ’  
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 23:26:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  it  =  mime_type - > parameters ( ) . find ( " charset " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( it  ! =  mime_type - > parameters ( ) . end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-03 09:27:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                charset  =  it - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // 3. Set essence to mimeType’  
							 
						 
					
						
							
								
									
										
										
										
											2023-03-03 09:27:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            essence  =  mime_type - > essence ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 5. Otherwise, if mimeType’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( ! mime_type - > parameters ( ) . contains ( " charset " sv )  & &  charset . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-14 11:06:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            mime_type - > set_parameter ( " charset " _string ,  charset . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 17:47:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. If mimeType is null, then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 8. Return mimeType.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  mime_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 16:26:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#legacy-extract-an-encoding
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								StringView  legacy_extract_an_encoding ( Optional < MimeSniff : : MimeType >  const &  mime_type ,  StringView  fallback_encoding )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If mimeType is failure, then return fallbackEncoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! mime_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  fallback_encoding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If mimeType["charset"] does not exist, then return fallbackEncoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  charset  =  mime_type - > parameters ( ) . get ( " charset " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! charset . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  fallback_encoding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let tentativeEncoding be the result of getting an encoding from mimeType["charset"].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tentative_encoding  =  TextCodec : : get_standardized_encoding ( * charset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. If tentativeEncoding is failure, then return fallbackEncoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tentative_encoding . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  fallback_encoding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Return tentativeEncoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  * tentative_encoding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#convert-header-names-to-a-sorted-lowercase-set
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								OrderedHashTable < ByteBuffer >  convert_header_names_to_a_sorted_lowercase_set ( Span < ReadonlyBytes >  header_names )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To convert header names to a sorted-lowercase set, given a list of names headerNames, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let headerNamesSet be a new ordered set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ByteBuffer >  header_names_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    HashTable < ReadonlyBytes ,  CaseInsensitiveBytesTraits < u8  const > >  header_names_seen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. For each name of headerNames, append the result of byte-lowercasing name to headerNamesSet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  name  :  header_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( header_names_seen . contains ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  bytes  =  MUST ( ByteBuffer : : copy ( name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Infra : : byte_lowercase ( bytes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 21:58:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        header_names_seen . set ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        header_names_set . append ( move ( bytes ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Return the result of sorting headerNamesSet in ascending order with byte less than.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    quick_sort ( header_names_set ,  [ ] ( auto  const &  a ,  auto  const &  b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  StringView  {  a  }  <  StringView  {  b  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    OrderedHashTable < ByteBuffer >  ordered  {  header_names_set . size ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  name  :  header_names_set )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  result  =  ordered . set ( move ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( result  = =  AK : : HashSetResult : : InsertedNewEntry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  ordered ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_header_name ( ReadonlyBytes  header_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A header name is a byte sequence that matches the field-name token production.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Regex < ECMA262Parser >  regex  {  R " ~~~(^[A-Za-z0-9!#$%&'*+ \ -.^_`|~]+$)~~~ "  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  regex . has_match ( StringView  {  header_name  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#header-value
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_header_value ( ReadonlyBytes  header_value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A header value is a byte sequence that matches the following conditions:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - Has no leading or trailing HTTP tab or space bytes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - Contains no 0x00 (NUL) or HTTP newline bytes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( header_value . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  first_byte  =  header_value [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  last_byte  =  header_value [ header_value . size ( )  -  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( HTTP_TAB_OR_SPACE_BYTES . span ( ) . contains_slow ( first_byte )  | |  HTTP_TAB_OR_SPACE_BYTES . span ( ) . contains_slow ( last_byte ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  ! any_of ( header_value ,  [ ] ( auto  byte )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  byte  = =  0x00  | |  HTTP_NEWLINE_BYTES . span ( ) . contains_slow ( byte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#concept-header-value-normalize
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ByteBuffer  normalize_header_value ( ReadonlyBytes  potential_value )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To normalize a byte sequence potentialValue, remove any leading and trailing HTTP whitespace bytes from potentialValue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( potential_value . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  trimmed  =  StringView  {  potential_value  } . trim ( HTTP_WHITESPACE ,  TrimMode : : Both ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  MUST ( ByteBuffer : : copy ( trimmed . bytes ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_cors_safelisted_request_header ( Header  const &  header )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To determine whether a header (name, value) is a CORS-safelisted request-header, run these steps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  value  =  header . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 1. If value’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . size ( )  >  128 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Byte-lowercase name and switch on the result:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  name  =  StringView  {  header . name  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `accept`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( name . equals_ignoring_ascii_case ( " accept " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // If value contains a CORS-unsafe request-header byte, then return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( any_of ( value . span ( ) ,  is_cors_unsafe_request_header_byte ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `accept-language`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `content-language`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( name . is_one_of_ignoring_ascii_case ( " accept-language " sv ,  " content-language " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // If value contains a byte that is not in the range 0x30 (0) to 0x39 (9), inclusive, is not in the range 0x41 (A) to 0x5A (Z), inclusive, is not in the range 0x61 (a) to 0x7A (z), inclusive, and is not 0x20 (SP), 0x2A (*), 0x2C (,), 0x2D (-), 0x2E (.), 0x3B (;), or 0x3D (=), then return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( any_of ( value . span ( ) ,  [ ] ( auto  byte )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-12 16:31:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ! ( is_ascii_digit ( byte )  | |  is_ascii_alpha ( byte )  | |  "  *,-.;= " sv . contains ( static_cast < char > ( byte ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `content-type`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( name . equals_ignoring_ascii_case ( " content-type " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If value contains a CORS-unsafe request-header byte, then return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( any_of ( value . span ( ) ,  is_cors_unsafe_request_header_byte ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:17:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Let mimeType be the result of parsing the result of isomorphic decoding value.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-14 11:18:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  mime_type  =  MimeSniff : : MimeType : : parse ( StringView  {  value  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. If mimeType is failure, then return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! mime_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 4. If mimeType’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! mime_type - > essence ( ) . is_one_of ( " application/x-www-form-urlencoded " sv ,  " multipart/form-data " sv ,  " text/plain " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `range`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( name . equals_ignoring_ascii_case ( " range " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let rangeValue be the result of parsing a single range header value given value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  range_value  =  parse_single_range_header_value ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If rangeValue is failure, then return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! range_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. If rangeValue[0] is null, then return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: As web browsers have historically not emitted ranges such as `bytes=-500` this algorithm does not safelist them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! range_value - > start . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_cors_unsafe_request_header_byte ( u8  byte )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A CORS-unsafe request-header byte is a byte byte for which one of the following is true:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - byte is less than 0x20 and is not 0x09 HT
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - byte is 0x22 ("), 0x28 (left parenthesis), 0x29 (right parenthesis), 0x3A (:), 0x3C (<), 0x3E (>), 0x3F (?), 0x40 (@), 0x5B ([), 0x5C (\), 0x5D (]), 0x7B ({), 0x7D (}), or 0x7F DEL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  ( byte  <  0x20  & &  byte  ! =  0x09 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  ( Array < u8 ,  14 >  {  0x22 ,  0x28 ,  0x29 ,  0x3A ,  0x3C ,  0x3E ,  0x3F ,  0x40 ,  0x5B ,  0x5C ,  0x5D ,  0x7B ,  0x7D ,  0x7F  } . span ( ) . contains_slow ( byte ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#cors-unsafe-request-header-names
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								OrderedHashTable < ByteBuffer >  get_cors_unsafe_header_names ( HeaderList  const &  headers )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The CORS-unsafe request-header names, given a header list headers, are determined as follows:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let unsafeNames be a new list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ReadonlyBytes >  unsafe_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let potentiallyUnsafeNames be a new list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ReadonlyBytes >  potentially_unsafe_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let safelistValueSize be 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Checked < size_t >  safelist_value_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. For each header of headers:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  header  :  headers )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 1. If header is not a CORS-safelisted request-header, then append header’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! is_cors_safelisted_request_header ( header ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            unsafe_names . append ( header . name . span ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 2. Otherwise, append header’ ’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            potentially_unsafe_names . append ( header . name . span ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            safelist_value_size  + =  header . value . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If safelistValueSize is greater than 1024, then for each name of potentiallyUnsafeNames, append name to unsafeNames.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( safelist_value_size . has_overflow ( )  | |  safelist_value_size . value ( )  >  1024 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  name  :  potentially_unsafe_names ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            unsafe_names . append ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. Return the result of convert header names to a sorted-lowercase set with unsafeNames.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  convert_header_names_to_a_sorted_lowercase_set ( unsafe_names . span ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_cors_non_wildcard_request_header_name ( ReadonlyBytes  header_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A CORS non-wildcard request-header name is a header name that is a byte-case-insensitive match for `Authorization`.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StringView  {  header_name  } . equals_ignoring_ascii_case ( " Authorization " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#privileged-no-cors-request-header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_privileged_no_cors_request_header_name ( ReadonlyBytes  header_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A privileged no-CORS request-header name is a header name that is a byte-case-insensitive match for one of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Range`.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StringView  {  header_name  } . equals_ignoring_ascii_case ( " Range " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_cors_safelisted_response_header_name ( ReadonlyBytes  header_name ,  Span < ReadonlyBytes >  list )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A CORS-safelisted response-header name, given a list of header names list, is a header name that is a byte-case-insensitive match for one of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Cache-Control`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Language`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Length`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Type`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Expires`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Last-Modified`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Pragma`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - Any item in list that is not a forbidden response-header name.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StringView  {  header_name  } . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Cache-Control " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Content-Language " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Content-Length " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Content-Type " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Expires " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Last-Modified " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								               " Pragma " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  any_of ( list ,  [ & ] ( auto  list_header_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								               return  StringView  {  header_name  } . equals_ignoring_ascii_case ( list_header_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                   & &  ! is_forbidden_response_header_name ( list_header_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								           } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#no-cors-safelisted-request-header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_no_cors_safelisted_request_header_name ( ReadonlyBytes  header_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A no-CORS-safelisted request-header name is a header name that is a byte-case-insensitive match for one of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Accept`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Accept-Language`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Language`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Type`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StringView  {  header_name  } . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Accept " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Accept-Language " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Content-Language " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Content-Type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#no-cors-safelisted-request-header
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_no_cors_safelisted_request_header ( Header  const &  header )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:14:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To determine whether a header (name, value) is a no-CORS-safelisted request-header, run these steps:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:14:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If name is not a no-CORS-safelisted request-header name, then return false.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! is_no_cors_safelisted_request_header_name ( header . name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:14:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Return whether (name, value) is a CORS-safelisted request-header.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  is_cors_safelisted_request_header ( header ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#forbidden-header-name
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_forbidden_request_header ( Header  const &  header )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // A header (name, value) is forbidden request-header if these steps return true:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  name  =  StringView  {  header . name  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If name is a byte-case-insensitive match for one of:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [...]
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // then return true.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( name . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            " Accept-Charset " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Accept-Encoding " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Access-Control-Request-Headers " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Access-Control-Request-Method " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Connection " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Content-Length " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Cookie " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Cookie2 " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Date " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " DNT " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Expect " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Host " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Keep-Alive " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Origin " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Referer " sv , 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:52:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            " Set-Cookie " sv , 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            " TE " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Trailer " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Transfer-Encoding " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Upgrade " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Via " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If name when byte-lowercased starts with `proxy-` or `sec-`, then return true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( name . starts_with ( " proxy- " sv ,  CaseSensitivity : : CaseInsensitive ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  name . starts_with ( " sec- " sv ,  CaseSensitivity : : CaseInsensitive ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If name is a byte-case-insensitive match for one of:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `X-HTTP-Method`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `X-HTTP-Method-Override`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `X-Method-Override`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // then:
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( name . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            " X-HTTP-Method " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " X-HTTP-Method-Override " sv , 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:53:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            " X-Method-Override " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let parsedValues be the result of getting, decoding, and splitting value.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parsed_values  =  get_decode_and_split_header_value ( header . value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:29:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. For each method of parsedValues: if the isomorphic encoding of method is a forbidden method, then return true.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 18:16:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parsed_values . has_value ( )  & &  any_of ( * parsed_values ,  [ ] ( auto  method )  {  return  is_forbidden_method ( method . bytes ( ) ) ;  } ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Return false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#forbidden-response-header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_forbidden_response_header_name ( ReadonlyBytes  header_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A forbidden response-header name is a header name that is a byte-case-insensitive match for one of:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Set-Cookie`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Set-Cookie2`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StringView  {  header_name  } . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Set-Cookie " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Set-Cookie2 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#request-body-header-name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_request_body_header_name ( ReadonlyBytes  header_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A request-body-header name is a header name that is a byte-case-insensitive match for one of:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Encoding`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Language`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Location`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // - `Content-Type`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StringView  {  header_name  } . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Content-Encoding " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Content-Language " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Content-Location " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " Content-Type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#extract-header-values
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Vector < ByteBuffer > >  extract_header_values ( Header  const &  header )  
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // FIXME: 1. If parsing header’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // FIXME: 2. Return one or more values resulting from parsing header’ ’  
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 22:00:28 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // For now we only parse some headers that are of the ABNF list form "#something"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( StringView  {  header . name  } . is_one_of_ignoring_ascii_case ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Access-Control-Request-Headers " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Access-Control-Expose-Headers " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Access-Control-Allow-Headers " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Access-Control-Allow-Methods " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        & &  ! header . value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  split_values  =  StringView  {  header . value  } . split_view ( ' , ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Vector < ByteBuffer >  trimmed_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  value  :  split_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  trimmed_value  =  value . trim ( "   \t " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  trimmed_value_as_byte_buffer  =  MUST ( ByteBuffer : : copy ( trimmed_value . bytes ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            trimmed_values . append ( move ( trimmed_value_as_byte_buffer ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-01 22:00:28 +12:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  trimmed_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // This always ignores the ABNF rules for now and returns the header value as a single list item.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Vector  {  MUST ( ByteBuffer : : copy ( header . value ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#extract-header-list-values
  
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Variant < Vector < ByteBuffer > ,  ExtractHeaderParseFailure ,  Empty >  extract_header_list_values ( ReadonlyBytes  name ,  HeaderList  const &  list )  
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If list does not contain name, then return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! list . contains ( name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 23:32:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Empty  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: 2. If the ABNF for name allows a single header and list contains more than one, then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: If different error handling is needed, extract the desired header first.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let values be an empty list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  values  =  Vector < ByteBuffer >  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. For each header header list contains whose name is name:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  header  :  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! StringView  {  header . name  } . equals_ignoring_ascii_case ( name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let extract be the result of extracting header values from header.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:24:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  extract  =  extract_header_values ( header ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If extract is failure, then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! extract . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-08 23:32:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ExtractHeaderParseFailure  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-25 23:02:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Append each value in extract, in order, to values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        values . extend ( extract . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Return values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#simple-range-header-value
  
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < RangeHeaderValue >  parse_single_range_header_value ( ReadonlyBytes  value )  
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let data be the isomorphic decoding of value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  data  =  StringView  {  value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If data does not start with "bytes=", then return failure.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! data . starts_with ( " bytes= " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let position be a position variable for data, initially pointing at the 6th code point of data.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  lexer  =  GenericLexer  {  data  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    lexer . ignore ( 6 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Let rangeStart be the result of collecting a sequence of code points that are ASCII digits, from data given position.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  range_start  =  lexer . consume_while ( is_ascii_digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Let rangeStartValue be rangeStart, interpreted as decimal number, if rangeStart is not the empty string; otherwise null.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-23 15:59:14 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  range_start_value  =  range_start . to_number < u64 > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. If the code point at position within data is not U+002D (-), then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Advance position by 1.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! lexer . consume_specific ( ' - ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 8. Let rangeEnd be the result of collecting a sequence of code points that are ASCII digits, from data given position.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  range_end  =  lexer . consume_while ( is_ascii_digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 9. Let rangeEndValue be rangeEnd, interpreted as decimal number, if rangeEnd is not the empty string; otherwise null.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-23 15:59:14 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  range_end_value  =  range_end . to_number < u64 > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 10. If position is not past the end of data, then return failure.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! lexer . is_eof ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 11. If rangeEndValue and rangeStartValue are null, then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! range_end_value . has_value ( )  & &  ! range_start_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 12. If rangeStartValue and rangeEndValue are numbers, and rangeStartValue is greater than rangeEndValue, then return failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( range_start_value . has_value ( )  & &  range_end_value . has_value ( )  & &  * range_start_value  >  * range_end_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 00:39:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 13. Return (rangeStartValue, rangeEndValue).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: The range end or start can be omitted, e.g., `bytes=0-` or `bytes=-500` are valid ranges.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  RangeHeaderValue  {  move ( range_start_value ) ,  move ( range_end_value )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 09:23:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://fetch.spec.whatwg.org/#default-user-agent-value
  
						 
					
						
							
								
									
										
										
										
											2023-12-27 11:43:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ByteBuffer  default_user_agent_value ( )  
						 
					
						
							
								
									
										
										
										
											2022-10-24 09:23:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A default `User-Agent` value is an implementation-defined header value for the `User-Agent` header.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-27 11:43:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  MUST ( ByteBuffer : : copy ( ResourceLoader : : the ( ) . user_agent ( ) . bytes ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 09:23:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 21:42:14 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}