11use core:: ffi:: c_void;
22use core:: fmt;
3+ use core:: slice:: from_raw_parts;
34use core:: str:: FromStr ;
45
56use crate :: core:: * ;
@@ -394,13 +395,13 @@ impl Request {
394395 }
395396
396397 /// Iterate over headers_in
397- /// each header item is (String, String ) (copied )
398+ /// each header item is (&str, &str ) (borrowed )
398399 pub fn headers_in_iterator ( & self ) -> NgxListIterator {
399400 unsafe { list_iterator ( & self . 0 . headers_in . headers ) }
400401 }
401402
402403 /// Iterate over headers_out
403- /// each header item is (String, String ) (copied )
404+ /// each header item is (&str, &str ) (borrowed )
404405 pub fn headers_out_iterator ( & self ) -> NgxListIterator {
405406 unsafe { list_iterator ( & self . 0 . headers_out . headers ) }
406407 }
@@ -424,62 +425,60 @@ impl fmt::Debug for Request {
424425/// Iterator for [`ngx_list_t`] types.
425426///
426427/// Implementes the core::iter::Iterator trait.
427- pub struct NgxListIterator {
428- done : bool ,
429- part : * const ngx_list_part_t ,
430- h : * const ngx_table_elt_t ,
428+ pub struct NgxListIterator < ' a > {
429+ part : Option < ListPart < ' a > > ,
431430 i : ngx_uint_t ,
432431}
432+ struct ListPart < ' a > {
433+ raw : & ' a ngx_list_part_t ,
434+ arr : & ' a [ ngx_table_elt_t ] ,
435+ }
436+ impl < ' a > From < & ' a ngx_list_part_t > for ListPart < ' a > {
437+ fn from ( raw : & ' a ngx_list_part_t ) -> Self {
438+ let arr = if let Some ( elts) = unsafe { raw. elts . cast :: < ngx_table_elt_t > ( ) . as_ref ( ) } {
439+ unsafe { from_raw_parts ( elts, raw. nelts ) }
440+ } else {
441+ & [ ]
442+ } ;
443+ Self { raw, arr }
444+ }
445+ }
433446
434447/// Creates new HTTP header iterator
435448///
436449/// # Safety
437450///
438451/// The caller has provided a valid [`ngx_str_t`] which can be dereferenced validly.
439- pub unsafe fn list_iterator ( list : * const ngx_list_t ) -> NgxListIterator {
440- let part: * const ngx_list_part_t = & ( * list) . part ;
441-
452+ pub unsafe fn list_iterator ( list : & ngx_list_t ) -> NgxListIterator {
442453 NgxListIterator {
443- done : false ,
444- part,
445- h : ( * part) . elts as * const ngx_table_elt_t ,
454+ part : Some ( ( & list. part ) . into ( ) ) ,
446455 i : 0 ,
447456 }
448457}
449458
450459// iterator for ngx_list_t
451- impl Iterator for NgxListIterator {
452- // type Item = (&str,&str);
453- // TODO: try to use str instead of string
460+ impl < ' a > Iterator for NgxListIterator < ' a > {
461+ // TODO: try to use struct instead of &str pair
454462 // something like pub struct Header(ngx_table_elt_t);
455463 // then header would have key and value
456464
457- type Item = ( String , String ) ;
465+ type Item = ( & ' a str , & ' a str ) ;
458466
459467 fn next ( & mut self ) -> Option < Self :: Item > {
460- unsafe {
461- if self . done {
462- None
468+ let part = self . part . as_mut ( ) ?;
469+ if self . i >= part. arr . len ( ) {
470+ if let Some ( next_part_raw) = unsafe { part. raw . next . as_ref ( ) } {
471+ // loop back
472+ * part = next_part_raw. into ( ) ;
473+ self . i = 0 ;
463474 } else {
464- if self . i >= ( * self . part ) . nelts {
465- if ( * self . part ) . next . is_null ( ) {
466- self . done = true ;
467- return None ;
468- }
469-
470- // loop back
471- self . part = ( * self . part ) . next ;
472- self . h = ( * self . part ) . elts as * mut ngx_table_elt_t ;
473- self . i = 0 ;
474- }
475-
476- let header: * const ngx_table_elt_t = self . h . add ( self . i ) ;
477- let header_name: ngx_str_t = ( * header) . key ;
478- let header_value: ngx_str_t = ( * header) . value ;
479- self . i += 1 ;
480- Some ( ( header_name. to_string ( ) , header_value. to_string ( ) ) )
475+ self . part = None ;
476+ return None ;
481477 }
482478 }
479+ let header = & part. arr [ self . i ] ;
480+ self . i += 1 ;
481+ Some ( ( header. key . to_str ( ) , header. value . to_str ( ) ) )
483482 }
484483}
485484
0 commit comments