@@ -877,6 +877,129 @@ LT_BEGIN_AUTO_TEST(authentication_suite, auth_multiple_skip_paths)
877877 ws.stop();
878878LT_END_AUTO_TEST (auth_multiple_skip_paths)
879879
880+ // Test skip path for root "/"
881+ LT_BEGIN_AUTO_TEST(authentication_suite, auth_skip_path_root)
882+ webserver ws = create_webserver(PORT)
883+ .auth_handler(centralized_auth_handler)
884+ .auth_skip_paths({" /" });
885+
886+ simple_resource sr;
887+ LT_ASSERT_EQ (true , ws.register_resource(" /" , &sr, true ));
888+ ws.start(false );
889+
890+ curl_global_init (CURL_GLOBAL_ALL);
891+ std::string s;
892+ CURL *curl = curl_easy_init();
893+ CURLcode res;
894+ long http_code = 0 ; // NOLINT(runtime/int)
895+
896+ // Root path should be skipped
897+ curl_easy_setopt (curl, CURLOPT_URL, " localhost:" PORT_STRING " /" );
898+ curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L );
899+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc);
900+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s);
901+ res = curl_easy_perform(curl);
902+ curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
903+ LT_ASSERT_EQ (res, 0 );
904+ LT_CHECK_EQ (http_code, 200 );
905+ LT_CHECK_EQ (s, " SUCCESS" );
906+ curl_easy_cleanup (curl);
907+
908+ ws.stop();
909+ LT_END_AUTO_TEST (auth_skip_path_root)
910+
911+ // Test wildcard path matching "/pub/*"
912+ LT_BEGIN_AUTO_TEST(authentication_suite, auth_skip_path_wildcard)
913+ webserver ws = create_webserver(PORT)
914+ .auth_handler(centralized_auth_handler)
915+ .auth_skip_paths({" /pub/*" });
916+
917+ simple_resource sr;
918+ LT_ASSERT_EQ (true , ws.register_resource(" pub/anything" , &sr));
919+ LT_ASSERT_EQ (true , ws.register_resource(" pub/nested/path" , &sr));
920+ LT_ASSERT_EQ (true , ws.register_resource(" private/secret" , &sr));
921+ ws.start(false );
922+
923+ curl_global_init (CURL_GLOBAL_ALL);
924+ CURL *curl;
925+ CURLcode res;
926+ long http_code = 0 ; // NOLINT(runtime/int)
927+ std::string s;
928+
929+ // /pub/anything should be skipped (matches /pub/*)
930+ curl = curl_easy_init();
931+ s = " " ;
932+ curl_easy_setopt (curl, CURLOPT_URL, " localhost:" PORT_STRING " /pub/anything" );
933+ curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L );
934+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc);
935+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s);
936+ res = curl_easy_perform(curl);
937+ curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
938+ LT_ASSERT_EQ (res, 0 );
939+ LT_CHECK_EQ (http_code, 200 );
940+ curl_easy_cleanup (curl);
941+
942+ // /pub/nested/path should also be skipped (matches /pub/*)
943+ curl = curl_easy_init();
944+ s = " " ;
945+ http_code = 0 ;
946+ curl_easy_setopt (curl, CURLOPT_URL, " localhost:" PORT_STRING " /pub/nested/path" );
947+ curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L );
948+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc);
949+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s);
950+ res = curl_easy_perform(curl);
951+ curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
952+ LT_ASSERT_EQ (res, 0 );
953+ LT_CHECK_EQ (http_code, 200 );
954+ curl_easy_cleanup (curl);
955+
956+ // /private/secret should NOT be skipped (doesn't match /pub/*)
957+ curl = curl_easy_init();
958+ s = " " ;
959+ http_code = 0 ;
960+ curl_easy_setopt (curl, CURLOPT_URL, " localhost:" PORT_STRING " /private/secret" );
961+ curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L );
962+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc);
963+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s);
964+ res = curl_easy_perform(curl);
965+ curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
966+ LT_ASSERT_EQ (res, 0 );
967+ LT_CHECK_EQ (http_code, 401 ); // Should require auth
968+ curl_easy_cleanup (curl);
969+
970+ ws.stop();
971+ LT_END_AUTO_TEST (auth_skip_path_wildcard)
972+
973+ // Test empty skip paths (should require auth for everything)
974+ LT_BEGIN_AUTO_TEST(authentication_suite, auth_empty_skip_paths)
975+ webserver ws = create_webserver(PORT)
976+ .auth_handler(centralized_auth_handler)
977+ .auth_skip_paths({}); // Empty skip paths
978+
979+ simple_resource sr;
980+ LT_ASSERT_EQ (true , ws.register_resource(" test" , &sr));
981+ ws.start(false );
982+
983+ curl_global_init (CURL_GLOBAL_ALL);
984+ std::string s;
985+ CURL *curl = curl_easy_init();
986+ CURLcode res;
987+ long http_code = 0 ; // NOLINT(runtime/int)
988+
989+ // Should require auth
990+ curl_easy_setopt (curl, CURLOPT_URL, " localhost:" PORT_STRING " /test" );
991+ curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L );
992+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc);
993+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s);
994+ res = curl_easy_perform(curl);
995+ curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
996+ LT_ASSERT_EQ (res, 0 );
997+ LT_CHECK_EQ (http_code, 401 );
998+ curl_easy_cleanup (curl);
999+
1000+ ws.stop();
1001+ LT_END_AUTO_TEST (auth_empty_skip_paths)
1002+
8801003LT_BEGIN_AUTO_TEST_ENV()
8811004 AUTORUN_TESTS()
8821005LT_END_AUTO_TEST_ENV()
0 commit comments