yumeng vor 1 Monat
Ursprung
Commit
8b9235c0a9

+ 5 - 1
src/main/java/com/adx/tencent/AppConfiguration.java

@@ -224,7 +224,11 @@ public class AppConfiguration {
 
     @Bean
     public AdxClient adxClient(AuctionPriceEncoder encoder, ObjectMapper objectMapper) {
-        return new AdxClient(props.getBaiduAdxEndpoint(), encoder, objectMapper);
+        return new AdxClient(
+                props.getBaiduAdxEndpoint(),
+                encoder,
+                objectMapper,
+                props.getBaiduTrackingMaxRedirects());
     }
 
     @Bean

+ 51 - 5
src/main/java/com/adx/tencent/baidu/AdxClient.java

@@ -14,6 +14,7 @@ import java.net.http.HttpResponse;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * 对应 Go internal/baidu/adx.go 的 ADXClient。
@@ -30,12 +31,16 @@ public class AdxClient {
     private final HttpClient httpClient;
     private final AuctionPriceEncoder priceEncoder;
     private final ObjectMapper objectMapper;
+    private final int trackingMaxRedirects;
 
-    public AdxClient(String endpoint, AuctionPriceEncoder priceEncoder, ObjectMapper objectMapper) {
+    public AdxClient(String endpoint, AuctionPriceEncoder priceEncoder, ObjectMapper objectMapper, int trackingMaxRedirects) {
         this.endpoint = endpoint;
         this.priceEncoder = priceEncoder;
-        this.httpClient = HttpClient.newHttpClient();
+        this.httpClient = HttpClient.newBuilder()
+                .followRedirects(HttpClient.Redirect.NEVER)
+                .build();
         this.objectMapper = objectMapper;
+        this.trackingMaxRedirects = Math.max(0, trackingMaxRedirects);
     }
 
     /**
@@ -115,16 +120,57 @@ public class AdxClient {
             throws IOException, InterruptedException {
         List<TrackingResult> results = new ArrayList<>();
         for (String url : trackingUrls) {
+            results.add(reportTrackingUrl(url));
+        }
+        return results;
+    }
+
+    private TrackingResult reportTrackingUrl(String originalUrl)
+            throws IOException, InterruptedException {
+        String currentUrl = originalUrl;
+        int redirectCount = 0;
+        while (true) {
             HttpRequest req = HttpRequest.newBuilder()
-                    .uri(URI.create(url))
+                    .uri(URI.create(currentUrl))
                     .GET()
                     .header("User-Agent", BAIDU_USER_AGENT)
                     .build();
             HttpResponse<Void> resp = httpClient.send(req, HttpResponse.BodyHandlers.discarding());
             int status = resp.statusCode();
-            results.add(new TrackingResult(url, status, status >= 200 && status < 400));
+            if (status == 200) {
+                log.info("[百度监测][请求成功] originalUrl={} finalUrl={} status={} redirects={}",
+                        originalUrl, currentUrl, status, redirectCount);
+                return new TrackingResult(originalUrl, status, true);
+            }
+            if (status != 302) {
+                log.warn("[百度监测][请求失败] originalUrl={} finalUrl={} status={} redirects={}",
+                        originalUrl, currentUrl, status, redirectCount);
+                return new TrackingResult(originalUrl, status, false);
+            }
+
+            Optional<String> location = resp.headers().firstValue("location");
+            if (location.isEmpty() || location.get().isBlank()) {
+                log.warn("[百度监测][302跟随失败] originalUrl={} currentUrl={} status={} redirects={} reason=missing_location",
+                        originalUrl, currentUrl, status, redirectCount);
+                return new TrackingResult(originalUrl, status, false);
+            }
+            if (redirectCount >= trackingMaxRedirects) {
+                log.warn("[百度监测][302跟随失败] originalUrl={} currentUrl={} location={} status={} redirects={} maxRedirects={} reason=redirect_limit_exceeded",
+                        originalUrl, currentUrl, location.get(), status, redirectCount, trackingMaxRedirects);
+                return new TrackingResult(originalUrl, status, false);
+            }
+
+            String nextUrl = resolveRedirectUrl(currentUrl, location.get());
+            redirectCount++;
+            log.info("[百度监测][302跟随] originalUrl={} currentUrl={} location={} nextUrl={} status={} redirects={}/{}",
+                    originalUrl, currentUrl, location.get(), nextUrl, status, redirectCount, trackingMaxRedirects);
+            currentUrl = nextUrl;
         }
-        return results;
+    }
+
+    private static String resolveRedirectUrl(String currentUrl, String location) {
+        URI current = URI.create(currentUrl);
+        return current.resolve(location).toString();
     }
 
     // ─── 默认价格编码(不加密,直接 URL encode 数字字符串)───────────────

+ 9 - 0
src/main/java/com/adx/tencent/config/AppProperties.java

@@ -37,6 +37,7 @@ public class AppProperties {
     private List<String> baiduIosTagIds = new ArrayList<>();
     private long baiduBidFloor = 0;
     private int baiduActionType = 1;
+    private int baiduTrackingMaxRedirects = 20;
 
     // Honor Callback
     private String honorConversionBaseUrl = "https://ads-drcn.platform.hihonorcloud.com";
@@ -301,6 +302,14 @@ public class AppProperties {
         this.baiduActionType = v;
     }
 
+    public int getBaiduTrackingMaxRedirects() {
+        return baiduTrackingMaxRedirects;
+    }
+
+    public void setBaiduTrackingMaxRedirects(int v) {
+        this.baiduTrackingMaxRedirects = v;
+    }
+
     public String getHonorConversionBaseUrl() {
         return honorConversionBaseUrl;
     }

+ 1 - 0
src/main/resources/application-dev.yml

@@ -24,6 +24,7 @@ adx:
   baidu-conversion-base-url: "https://media-interact.baidu.com"
   baidu-customer-name: dingzhaoming111
   baidu-secret: gk780scz3oi2
+  baidu-tracking-max-redirects: 20
 
   # --- Tencent API ---
   tencent-api-base-url: "https://api.e.qq.com/v3.0"

+ 1 - 0
src/main/resources/application-prod.yml

@@ -24,6 +24,7 @@ adx:
   baidu-conversion-base-url: "https://media-interact.baidu.com"
   baidu-customer-name: "dingzhaoming111"
   baidu-secret: "gk780scz3oi2"
+  baidu-tracking-max-redirects: 20
 
   # --- Tencent API ---
   tencent-access-token-redis-key: "adq:access_token:78578478"

+ 1 - 0
src/main/resources/application-test.yml

@@ -24,6 +24,7 @@ adx:
   baidu-conversion-base-url: "https://media-interact-test.baidu.com"
   baidu-customer-name: dingzhaoming111
   baidu-secret: gk780scz3oi2
+  baidu-tracking-max-redirects: 20
 
   # --- Tencent API ---
   tencent-api-base-url: "https://api.e.qq.com/v3.0"