diff --git a/.gitlab/generate-appsec.php b/.gitlab/generate-appsec.php index 62acc18ffc..5f1021e9cb 100644 --- a/.gitlab/generate-appsec.php +++ b/.gitlab/generate-appsec.php @@ -191,7 +191,6 @@ - test8.1-release - test8.3-debug - test8.4-release-zts - - test8.5-release-musl "helper-rust build and test": stage: test diff --git a/appsec/src/extension/configuration.h b/appsec/src/extension/configuration.h index c1da7f4074..5ad968bf77 100644 --- a/appsec/src/extension/configuration.h +++ b/appsec/src/extension/configuration.h @@ -28,7 +28,11 @@ extern bool runtime_config_first_init; #define DD_BASE(path) "/opt/datadog-php/" path +#if PHP_VERSION_ID >= 80500 +#define DD_APPSEC_HELPER_RUST_REDIRECTION_DEFAULT "true" +#else #define DD_APPSEC_HELPER_RUST_REDIRECTION_DEFAULT "false" +#endif // clang-format off #define DD_CONFIGURATION_GENERAL \ diff --git a/appsec/tests/integration/build.gradle b/appsec/tests/integration/build.gradle index cf973ee018..9b5ec0977f 100644 --- a/appsec/tests/integration/build.gradle +++ b/appsec/tests/integration/build.gradle @@ -639,6 +639,9 @@ def runMainTask = { String phpVersion, String variant -> dependsOn 'buildHelperRustWithCoverage' } else if (project.hasProperty('useHelperRust')) { dependsOn 'buildHelperRust' + } else if (phpVersion == '8.5') { + // PHP 8.5+ uses Rust helper by default via DD_APPSEC_HELPER_RUST_REDIRECTION + dependsOn 'buildHelperRust' } } } @@ -710,6 +713,9 @@ def runMainTask = { String phpVersion, String variant -> dependsOn 'buildHelperRustWithCoverage' } else if (project.hasProperty('useHelperRust')) { dependsOn 'buildHelperRust' + } else if (phpVersion == '8.5') { + // PHP 8.5+ uses Rust helper by default via DD_APPSEC_HELPER_RUST_REDIRECTION + dependsOn 'buildHelperRust' } if (phpVersion in ['7.0', '7.1']) { diff --git a/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy b/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy index fc8b265321..8df2a9c2a5 100644 --- a/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy +++ b/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy @@ -491,6 +491,11 @@ class AppSecContainer> extends GenericContain } } withEnv 'USE_HELPER_RUST', '1' + } else { + // Mount helper-rust volume so enable_extensions.sh can copy the binary + // for the redirection mechanism (DD_APPSEC_HELPER_RUST_REDIRECTION + // defaults to true on PHP 8.5+) + addVolumeMount('php-helper-rust', '/helper-rust') } String fullWorkVolume = "php-workvol-$workVolume-$phpVersion-$phpVariant" diff --git a/appsec/tests/integration/src/test/bin/enable_extensions.sh b/appsec/tests/integration/src/test/bin/enable_extensions.sh index a2ea5da095..37870c251e 100755 --- a/appsec/tests/integration/src/test/bin/enable_extensions.sh +++ b/appsec/tests/integration/src/test/bin/enable_extensions.sh @@ -11,6 +11,11 @@ HELPER_PATH=/appsec/libddappsec-helper.so if [[ -n $USE_HELPER_RUST ]]; then echo "Using Rust helper" >&2 HELPER_PATH=/helper-rust/libddappsec-helper.so +elif [[ -f /helper-rust/libddappsec-helper.so ]]; then + # Copy Rust helper for the redirection mechanism + # (DD_APPSEC_HELPER_RUST_REDIRECTION defaults to true on PHP >= 8.5) + ln -sf /helper-rust/libddappsec-helper.so \ + "$(dirname "$HELPER_PATH")/libddappsec-helper-rust.so" fi if [[ -n $USE_SSI ]]; then diff --git a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/CommonTests.groovy b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/CommonTests.groovy index cfc0e2cd1a..b8c4efd5b4 100644 --- a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/CommonTests.groovy +++ b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/CommonTests.groovy @@ -863,4 +863,34 @@ trait CommonTests { assert span.metrics."_dd.appsec.trace.integer" == 1729 assert span.meta."_dd.appsec.trace.agent" == "TraceTagging/v4" } + + @Test + void 'helper runtime default matches PHP version'() { + // This test verifies the default helper selection; skip when explicitly overridden + org.junit.jupiter.api.Assumptions.assumeTrue( + System.getProperty('USE_HELPER_RUST') == null, + 'Skipped: helper explicitly overridden via -PuseHelperRust') + + def trace = container.traceFromRequest('/phpinfo.php') { HttpResponse resp -> + assert resp.statusCode() == 200 + def content = resp.body().text + + if (TestParams.phpVersionAtLeast('8.5')) { + assert content.contains('Yes (Rust)') : + "PHP >= 8.5 should use Rust helper by default" + } else { + assert content.contains('Yes (C++)') : + "PHP < 8.5 should use C++ helper by default" + } + } + + Span span = trace.first() + if (TestParams.phpVersionAtLeast('8.5')) { + assert span.meta."_dd.appsec.helper_runtime" == 'rust' : + "PHP >= 8.5 should report helper_runtime=rust in span" + } else { + assert span.meta."_dd.appsec.helper_runtime" == null : + "PHP < 8.5 should not set helper_runtime span tag" + } + } } diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index f4a3c4d064..334fc3c0c8 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -104,9 +104,9 @@ ], "DD_APPSEC_HELPER_RUST_REDIRECTION": [ { - "implementation": "A", + "implementation": "B", "type": "boolean", - "default": "false" + "default": "true" } ], "DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML": [