@@ -306,8 +306,8 @@ impl VerifierClient {
306306
307307 /// Auto-detect and set the API version
308308 ///
309- /// Attempts to determine the verifier's API version by first trying the `/version` endpoint.
310- /// If that fails, it tries each supported API version from oldest to newest until one works .
309+ /// Attempts to determine the verifier's API version by testing endpoint availability .
310+ /// For API v3.0+, the /version endpoint was removed, so we test the versioned endpoints directly .
311311 /// This follows the same pattern used in the rust-keylime agent's registrar client.
312312 ///
313313 /// # Returns
@@ -317,8 +317,8 @@ impl VerifierClient {
317317 ///
318318 /// # Behavior
319319 ///
320- /// 1. First tries `/version ` endpoint to get current and supported versions
321- /// 2. If `/version` fails, tries API versions from newest to oldest
320+ /// 1. For v3.0+: Tests `/v3.0/ ` endpoint availability directly (/version endpoint was removed)
321+ /// 2. For v2.x: First tries `/version` endpoint, then falls back to endpoint testing
322322 /// 3. On success, caches the detected version for future requests
323323 /// 4. On complete failure, leaves default version unchanged
324324 ///
@@ -339,28 +339,39 @@ impl VerifierClient {
339339 pub async fn detect_api_version (
340340 & mut self ,
341341 ) -> Result < ( ) , KeylimectlError > {
342- // Try to get version from /version endpoint first
343- match self . get_verifier_api_version ( ) . await {
344- Ok ( version) => {
345- info ! ( "Detected verifier API version: {version}" ) ;
346- self . api_version = version;
347- return Ok ( ( ) ) ;
348- }
349- Err ( e) => {
350- debug ! ( "Failed to get version from /version endpoint: {e}" ) ;
351- // Continue with fallback approach
352- }
353- }
354-
355- // Fallback: try each supported version from newest to oldest
342+ // Test each supported version from newest to oldest
356343 for & api_version in SUPPORTED_API_VERSIONS . iter ( ) . rev ( ) {
357344 info ! ( "Trying verifier API version {api_version}" ) ;
358345
359- // Test this version by making a simple request (list agents)
360- if self . test_api_version ( api_version) . await . is_ok ( ) {
361- info ! ( "Successfully detected verifier API version: {api_version}" ) ;
362- self . api_version = api_version. to_string ( ) ;
363- return Ok ( ( ) ) ;
346+ // For v3.0+, test the versioned root endpoint directly since /version was removed
347+ if api_version. starts_with ( "3." ) {
348+ if self . test_api_version_v3 ( api_version) . await . is_ok ( ) {
349+ info ! ( "Successfully detected verifier API version: {api_version}" ) ;
350+ self . api_version = api_version. to_string ( ) ;
351+ return Ok ( ( ) ) ;
352+ }
353+ } else {
354+ // For v2.x, try /version endpoint first for better version info
355+ if api_version. starts_with ( "2." ) {
356+ match self . get_verifier_api_version ( ) . await {
357+ Ok ( version) => {
358+ info ! ( "Detected verifier API version from /version endpoint: {version}" ) ;
359+ self . api_version = version;
360+ return Ok ( ( ) ) ;
361+ }
362+ Err ( e) => {
363+ debug ! ( "Failed to get version from /version endpoint: {e}" ) ;
364+ // Fall back to endpoint testing for this version
365+ }
366+ }
367+ }
368+
369+ // Test this version by making a simple request
370+ if self . test_api_version ( api_version) . await . is_ok ( ) {
371+ info ! ( "Successfully detected verifier API version: {api_version}" ) ;
372+ self . api_version = api_version. to_string ( ) ;
373+ return Ok ( ( ) ) ;
374+ }
364375 }
365376 }
366377
@@ -410,7 +421,38 @@ impl VerifierClient {
410421 Ok ( resp. results . current_version )
411422 }
412423
413- /// Test if a specific API version works by making a simple request
424+ /// Test if a specific API version v3.0+ works by testing the versioned root endpoint
425+ /// In API v3.0+, the /version endpoint was removed, so we test endpoint availability directly
426+ async fn test_api_version_v3 (
427+ & self ,
428+ api_version : & str ,
429+ ) -> Result < ( ) , KeylimectlError > {
430+ let url = format ! ( "{}/v{}/" , self . base. base_url, api_version) ;
431+
432+ debug ! ( "Testing verifier API version {api_version} with root endpoint: {url}" ) ;
433+
434+ let response = self
435+ . base
436+ . client
437+ . get_request ( Method :: GET , & url)
438+ . send ( )
439+ . await
440+ . with_context ( || {
441+ format ! ( "Failed to test API version {api_version}" )
442+ } ) ?;
443+
444+ if response. status ( ) . is_success ( ) {
445+ Ok ( ( ) )
446+ } else {
447+ Err ( KeylimectlError :: api_error (
448+ response. status ( ) . as_u16 ( ) ,
449+ format ! ( "API version {api_version} not supported" ) ,
450+ None ,
451+ ) )
452+ }
453+ }
454+
455+ /// Test if a specific API version v2.x works by making a simple request
414456 async fn test_api_version (
415457 & self ,
416458 api_version : & str ,
@@ -1995,16 +2037,35 @@ mod tests {
19952037
19962038 // Should try 3.0 first, then 2.3, then 2.2, then 2.1, then 2.0
19972039 assert_eq ! ( attempted_versions[ 0 ] , "3.0" ) ;
1998- assert_eq ! ( attempted_versions[ 1 ] , "2.3" ) ;
1999- assert_eq ! ( attempted_versions[ 2 ] , "2.2" ) ;
2000- assert_eq ! ( attempted_versions[ 3 ] , "2.1" ) ;
2001- assert_eq ! ( attempted_versions[ 4 ] , "2.0" ) ;
2040+ }
20022041
2003- // Should try all supported versions
2004- assert_eq ! (
2005- attempted_versions. len( ) ,
2006- SUPPORTED_API_VERSIONS . len( )
2007- ) ;
2042+ #[ test]
2043+ fn test_v3_endpoint_detection_logic ( ) {
2044+ // Test the logic for detecting v3.0+ vs v2.x behavior
2045+
2046+ // v3.0+ should use root endpoint testing
2047+ let v3_versions = [ "3.0" , "3.1" ] ;
2048+ for version in v3_versions {
2049+ assert ! ( version. starts_with( "3." ) ) ;
2050+ }
2051+
2052+ // v2.x should use /version endpoint first
2053+ let v2_versions = [ "2.0" , "2.1" , "2.2" , "2.3" ] ;
2054+ for version in v2_versions {
2055+ assert ! ( version. starts_with( "2." ) ) ;
2056+ }
2057+ }
2058+
2059+ #[ test]
2060+ fn test_v3_test_url_format ( ) {
2061+ // Test that v3 test URLs are formatted correctly
2062+ let base_url = "https://localhost:8881" ;
2063+ let api_version = "3.0" ;
2064+ let expected_url = format ! ( "{base_url}/v{api_version}/" ) ;
2065+
2066+ assert_eq ! ( expected_url, "https://localhost:8881/v3.0/" ) ;
2067+ assert ! ( expected_url. ends_with( "/" ) ) ;
2068+ assert ! ( !expected_url. contains( "/agents" ) ) ;
20082069 }
20092070 }
20102071}
0 commit comments