@@ -159,6 +159,37 @@ pub mod proto {
159159
160160 #[ error( "missing {0}" ) ]
161161 Missing ( & ' static str ) ,
162+
163+ #[ error( transparent) ]
164+ Timeout ( #[ from] InvalidTimeouts ) ,
165+
166+ #[ error( transparent) ]
167+ Retry ( #[ from] InvalidRetry ) ,
168+ }
169+
170+ #[ derive( Debug , thiserror:: Error ) ]
171+ pub enum InvalidRetry {
172+ #[ error( "invalid max-retries: {0}" ) ]
173+ MaxRetries ( u32 ) ,
174+
175+ #[ error( "invalid condition" ) ]
176+ Condition ,
177+
178+ #[ error( "invalid timeout: {0}" ) ]
179+ Timeout ( #[ from] prost_types:: DurationError ) ,
180+
181+ #[ error( "invalid backoff: {0}" ) ]
182+ Backoff ( #[ from] crate :: proto:: InvalidBackoff ) ,
183+ }
184+
185+ #[ derive( Debug , thiserror:: Error ) ]
186+ pub enum InvalidTimeouts {
187+ #[ error( "invalid response timeout: {0}" ) ]
188+ Response ( prost_types:: DurationError ) ,
189+ #[ error( "invalid idle timeout: {0}" ) ]
190+ Idle ( prost_types:: DurationError ) ,
191+ #[ error( "invalid request timeout: {0}" ) ]
192+ Request ( prost_types:: DurationError ) ,
162193 }
163194
164195 #[ derive( Debug , thiserror:: Error ) ]
@@ -247,6 +278,9 @@ pub mod proto {
247278 matches,
248279 backends,
249280 filters,
281+ timeouts,
282+ retry,
283+ allow_l5d_request_headers,
250284 request_timeout,
251285 } = proto;
252286
@@ -264,8 +298,9 @@ pub mod proto {
264298 . ok_or ( InvalidHttpRoute :: Missing ( "distribution" ) ) ?
265299 . try_into ( ) ?;
266300
267- let mut params = RouteParams :: default ( ) ;
268- params. timeouts . request = request_timeout. map ( TryInto :: try_into) . transpose ( ) ?;
301+ let mut params = RouteParams :: try_from_proto ( timeouts, retry, allow_l5d_request_headers) ?;
302+ let legacy = request_timeout. map ( TryInto :: try_into) . transpose ( ) ?;
303+ params. timeouts . request = params. timeouts . request . or ( legacy) ;
269304
270305 Ok ( Rule {
271306 matches,
@@ -278,6 +313,85 @@ pub mod proto {
278313 } )
279314 }
280315
316+ impl RouteParams {
317+ fn try_from_proto (
318+ timeouts : Option < linkerd2_proxy_api:: http_route:: Timeouts > ,
319+ retry : Option < http_route:: Retry > ,
320+ _allow_l5d_request_headers : bool ,
321+ ) -> Result < Self , InvalidHttpRoute > {
322+ Ok ( Self {
323+ retry : retry. map ( Retry :: try_from) . transpose ( ) ?,
324+ timeouts : timeouts
325+ . map ( Timeouts :: try_from)
326+ . transpose ( ) ?
327+ . unwrap_or_default ( ) ,
328+ } )
329+ }
330+ }
331+
332+ impl TryFrom < linkerd2_proxy_api:: http_route:: Timeouts > for Timeouts {
333+ type Error = InvalidTimeouts ;
334+ fn try_from (
335+ timeouts : linkerd2_proxy_api:: http_route:: Timeouts ,
336+ ) -> Result < Self , Self :: Error > {
337+ Ok ( Self {
338+ response : timeouts
339+ . response
340+ . map ( time:: Duration :: try_from)
341+ . transpose ( )
342+ . map_err ( InvalidTimeouts :: Response ) ?,
343+ idle : timeouts
344+ . idle
345+ . map ( time:: Duration :: try_from)
346+ . transpose ( )
347+ . map_err ( InvalidTimeouts :: Response ) ?,
348+ request : timeouts
349+ . request
350+ . map ( time:: Duration :: try_from)
351+ . transpose ( )
352+ . map_err ( InvalidTimeouts :: Request ) ?,
353+ } )
354+ }
355+ }
356+
357+ impl TryFrom < outbound:: http_route:: Retry > for Retry {
358+ type Error = InvalidRetry ;
359+ fn try_from ( retry : outbound:: http_route:: Retry ) -> Result < Self , Self :: Error > {
360+ fn range (
361+ r : outbound:: http_route:: retry:: conditions:: StatusRange ,
362+ ) -> Result < RangeInclusive < u16 > , InvalidRetry > {
363+ let Ok ( start) = u16:: try_from ( r. start ) else {
364+ return Err ( InvalidRetry :: Condition ) ;
365+ } ;
366+ let Ok ( end) = u16:: try_from ( r. end ) else {
367+ return Err ( InvalidRetry :: Condition ) ;
368+ } ;
369+ if start == 0 || end == 0 || end > 599 || start > end {
370+ return Err ( InvalidRetry :: Condition ) ;
371+ }
372+ Ok ( start..=end)
373+ }
374+
375+ let status_ranges = StatusRanges (
376+ retry
377+ . conditions
378+ . ok_or ( InvalidRetry :: Condition ) ?
379+ . status_ranges
380+ . into_iter ( )
381+ . map ( range)
382+ . collect :: < Result < _ , _ > > ( ) ?,
383+ ) ;
384+ Ok ( Self {
385+ status_ranges,
386+ max_retries : u16:: try_from ( retry. max_retries )
387+ . map_err ( |_| InvalidRetry :: MaxRetries ( retry. max_retries ) ) ?,
388+ max_request_bytes : retry. max_request_bytes as _ ,
389+ backoff : retry. backoff . map ( crate :: proto:: try_backoff) . transpose ( ) ?,
390+ timeout : retry. timeout . map ( time:: Duration :: try_from) . transpose ( ) ?,
391+ } )
392+ }
393+ }
394+
281395 impl TryFrom < http_route:: Distribution > for RouteDistribution < Filter > {
282396 type Error = InvalidDistribution ;
283397 fn try_from ( distribution : http_route:: Distribution ) -> Result < Self , Self :: Error > {
0 commit comments