@@ -42,10 +42,12 @@ use bytes::Bytes;
4242 feature = "ffi"
4343) ) ]
4444use http:: header:: HeaderName ;
45+ #[ cfg( all( feature = "http1" , feature = "ffi" ) ) ]
46+ use http:: header:: IntoHeaderName ;
4547#[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
4648use http:: header:: InvalidHeaderName ;
4749#[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
48- use http:: header:: { HeaderMap , IntoHeaderName , ValueIter } ;
50+ use http:: header:: { HeaderMap , ValueIter } ;
4951#[ cfg( feature = "ffi" ) ]
5052use std:: collections:: HashMap ;
5153#[ cfg( feature = "http2" ) ]
@@ -183,24 +185,65 @@ impl HeaderCaseMap {
183185
184186 /// Inserts a header spelling, replacing any existing ones associated with that header name.
185187 #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
186- pub fn insert ( & mut self , name : HeaderName , orig : Bytes ) -> Result < ( ) , InvalidHeaderName > {
187- HeaderName :: from_bytes ( & orig) ?;
188- self . 0 . insert ( name, orig) ;
188+ pub fn insert ( & mut self , name : CasedHeaderName ) -> Result < ( ) , InvalidHeaderName > {
189+ self . 0 . insert ( name. 0 , name. 1 ) ;
189190 Ok ( ( ) )
190191 }
191192
192193 /// Inserts a header spelling in addition to any existing ones associated with that header name.
193194 #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
194- pub fn append < N > ( & mut self , name : N , orig : Bytes ) -> Result < ( ) , InvalidHeaderName >
195- where
196- N : IntoHeaderName ,
197- {
198- HeaderName :: from_bytes ( & orig) ?;
199- self . 0 . append ( name, orig) ;
195+ pub fn append ( & mut self , name : CasedHeaderName ) -> Result < ( ) , InvalidHeaderName > {
196+ self . 0 . append ( name. 0 , name. 1 ) ;
200197 Ok ( ( ) )
201198 }
202199}
203200
201+ /// An error converting a header name spelling to a [`CasedHeaderName`].
202+ #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
203+ #[ derive( Debug ) ]
204+ pub enum CasedHeaderNameError {
205+ /// Error parsing the header name
206+ Invalid ( InvalidHeaderName ) ,
207+ /// The parsed header name doesn't match the spelling's
208+ NoMatch ,
209+ }
210+
211+ /// A header casing representation, guaranteed to be a valid [`http::HeaderName`].
212+ #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
213+ #[ derive( Debug ) ]
214+ pub struct CasedHeaderName ( HeaderName , Bytes ) ;
215+
216+ #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
217+ impl CasedHeaderName {
218+ /// Constructs a header casing representation.
219+ pub fn new ( name : HeaderName , orig : Bytes ) -> Result < Self , CasedHeaderNameError > {
220+ let orig_parsed =
221+ HeaderName :: from_bytes ( & orig) . map_err ( |err| CasedHeaderNameError :: Invalid ( err) ) ?;
222+
223+ if orig_parsed != name {
224+ Err ( CasedHeaderNameError :: NoMatch )
225+ } else {
226+ Ok ( CasedHeaderName ( name. into ( ) , orig) )
227+ }
228+ }
229+ }
230+
231+ #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
232+ impl TryFrom < Bytes > for CasedHeaderName {
233+ type Error = InvalidHeaderName ;
234+
235+ fn try_from ( orig : Bytes ) -> Result < Self , Self :: Error > {
236+ HeaderName :: from_bytes ( & orig) . map ( |name| CasedHeaderName ( name, orig) )
237+ }
238+ }
239+
240+ #[ cfg( all( any( feature = "client" , feature = "server" ) , feature = "http1" ) ) ]
241+ impl From < CasedHeaderName > for HeaderName {
242+ fn from ( value : CasedHeaderName ) -> Self {
243+ value. 0
244+ }
245+ }
246+
204247#[ cfg( feature = "ffi" ) ]
205248#[ derive( Clone , Debug ) ]
206249/// Hashmap<Headername, numheaders with that name>
0 commit comments