1010use alloc:: string:: { String , ToString } ;
1111use core:: ffi:: c_void;
1212use core:: fmt;
13+ use core:: num:: NonZero ;
1314use core:: pin:: Pin ;
1415use core:: ptr:: NonNull ;
1516use core:: task:: { Context , Poll , Waker } ;
@@ -37,8 +38,6 @@ pub enum Error {
3738 Resolver ( ResolverError , String ) ,
3839 /// Allocation failed
3940 AllocationFailed ,
40- /// Unexpected error
41- Unexpected ( String ) ,
4241}
4342
4443impl fmt:: Display for Error {
@@ -47,7 +46,6 @@ impl fmt::Display for Error {
4746 Error :: NoResolver => write ! ( f, "No resolver configured" ) ,
4847 Error :: Resolver ( err, context) => write ! ( f, "{err}: resolving `{context}`" ) ,
4948 Error :: AllocationFailed => write ! ( f, "Allocation failed" ) ,
50- Error :: Unexpected ( err) => write ! ( f, "Unexpected error: {err}" ) ,
5149 }
5250 }
5351}
@@ -88,19 +86,17 @@ impl fmt::Display for ResolverError {
8886}
8987impl core:: error:: Error for ResolverError { }
9088
91- /// Convert from the NGX_RESOLVE_ error codes. Fails if code was success.
92- impl TryFrom < isize > for ResolverError {
93- type Error = ( ) ;
94- fn try_from ( code : isize ) -> Result < ResolverError , Self :: Error > {
95- match code as u32 {
96- 0 => Err ( ( ) ) ,
97- NGX_RESOLVE_FORMERR => Ok ( ResolverError :: FormErr ) ,
98- NGX_RESOLVE_SERVFAIL => Ok ( ResolverError :: ServFail ) ,
99- NGX_RESOLVE_NXDOMAIN => Ok ( ResolverError :: NXDomain ) ,
100- NGX_RESOLVE_NOTIMP => Ok ( ResolverError :: NotImp ) ,
101- NGX_RESOLVE_REFUSED => Ok ( ResolverError :: Refused ) ,
102- NGX_RESOLVE_TIMEDOUT => Ok ( ResolverError :: TimedOut ) ,
103- _ => Ok ( ResolverError :: Unknown ( code) ) ,
89+ /// Convert from the NGX_RESOLVE_ error codes.
90+ impl From < NonZero < isize > > for ResolverError {
91+ fn from ( code : NonZero < isize > ) -> ResolverError {
92+ match code. get ( ) as u32 {
93+ NGX_RESOLVE_FORMERR => ResolverError :: FormErr ,
94+ NGX_RESOLVE_SERVFAIL => ResolverError :: ServFail ,
95+ NGX_RESOLVE_NXDOMAIN => ResolverError :: NXDomain ,
96+ NGX_RESOLVE_NOTIMP => ResolverError :: NotImp ,
97+ NGX_RESOLVE_REFUSED => ResolverError :: Refused ,
98+ NGX_RESOLVE_TIMEDOUT => ResolverError :: TimedOut ,
99+ _ => ResolverError :: Unknown ( code. get ( ) ) ,
104100 }
105101 }
106102}
@@ -197,18 +193,16 @@ impl<'a> Resolution<'a> {
197193 // will be called later by nginx when it gets a dns response or a
198194 // timeout.
199195 let ret = unsafe { ngx_resolve_name ( ctx. as_ptr ( ) ) } ;
200- if ret != 0 {
201- return Err ( Error :: Resolver (
202- ResolverError :: try_from ( ret) . expect ( "nonzero, checked above" ) ,
203- name. to_string ( ) ,
204- ) ) ;
196+ if let Some ( e) = NonZero :: new ( ret) {
197+ return Err ( Error :: Resolver ( ResolverError :: from ( e) , name. to_string ( ) ) ) ;
205198 }
206199
207200 Ok ( this)
208201 }
209202
210203 // Nginx will call this handler when name resolution completes. If the
211- // result is cached, this could be
204+ // result is in the cache, this could be called from inside ngx_resolve_name.
205+ // Otherwise, it will be called later on the event loop.
212206 unsafe extern "C" fn handler ( ctx : * mut ngx_resolver_ctx_t ) {
213207 let mut data = unsafe { NonNull :: new_unchecked ( ( * ctx) . data as * mut Resolution ) } ;
214208 let this: & mut Resolution = unsafe { data. as_mut ( ) } ;
@@ -225,38 +219,36 @@ impl<'a> Resolution<'a> {
225219 }
226220
227221 /// Take the results in a ctx and make an owned copy as a
228- /// Result<Vec<ngx_addr_t>, Error>, where both the Vec and internals of
229- /// the ngx_addr_t are allocated on the given Pool
222+ /// Result<Vec<ngx_addr_t>, Error>, where the internals of the ngx_addr_t
223+ /// are allocated on the given Pool
230224 fn resolve_result ( ctx : * mut ngx_resolver_ctx_t , pool : & Pool ) -> Res {
231225 let ctx = unsafe { ctx. as_ref ( ) . unwrap ( ) } ;
232- let s = ctx. state ;
233- if s != 0 {
226+ if let Some ( e) = NonZero :: new ( ctx. state ) {
234227 return Err ( Error :: Resolver (
235- ResolverError :: try_from ( s ) . expect ( "nonzero, checked above" ) ,
228+ ResolverError :: from ( e ) ,
236229 ctx. name . to_string ( ) ,
237230 ) ) ;
238231 }
239232 if ctx. addrs . is_null ( ) {
240233 Err ( Error :: AllocationFailed ) ?;
241234 }
242- let mut out = Vec :: new ( ) ;
243- for i in 0 ..ctx. naddrs {
244- out. push ( Self :: copy_resolved_addr ( unsafe { ctx. addrs . add ( i) } , pool) ?) ;
235+
236+ if ctx. naddrs > 0 {
237+ unsafe { core:: slice:: from_raw_parts ( ctx. addrs , ctx. naddrs ) }
238+ . iter ( )
239+ . map ( |addr| Self :: copy_resolved_addr ( addr, pool) )
240+ . collect :: < Result < Vec < _ > , _ > > ( )
241+ } else {
242+ Ok ( Vec :: new ( ) )
245243 }
246- Ok ( out)
247244 }
248245
249246 /// Take the contents of an ngx_resolver_addr_t and make an owned copy as
250247 /// an ngx_addr_t, using the Pool for allocation of the internals.
251248 fn copy_resolved_addr (
252- addr : * mut nginx_sys:: ngx_resolver_addr_t ,
249+ addr : & nginx_sys:: ngx_resolver_addr_t ,
253250 pool : & Pool ,
254251 ) -> Result < ngx_addr_t , Error > {
255- let addr = NonNull :: new ( addr) . ok_or ( Error :: Unexpected (
256- "null ngx_resolver_addr_t in ngx_resolver_ctx_t.addrs" . to_string ( ) ,
257- ) ) ?;
258- let addr = unsafe { addr. as_ref ( ) } ;
259-
260252 let sockaddr = pool. alloc ( addr. socklen as usize ) as * mut nginx_sys:: sockaddr ;
261253 if sockaddr. is_null ( ) {
262254 Err ( Error :: AllocationFailed ) ?;
0 commit comments