diff --git a/.changeset/cold-buckets-gzip.md b/.changeset/cold-buckets-gzip.md new file mode 100644 index 0000000..ed8438b --- /dev/null +++ b/.changeset/cold-buckets-gzip.md @@ -0,0 +1,5 @@ +--- +'posthog-php': patch +--- + +Fall back to uncompressed batch uploads when local gzip compression fails. diff --git a/lib/Consumer/ForkCurl.php b/lib/Consumer/ForkCurl.php index 4e91b91..425afca 100644 --- a/lib/Consumer/ForkCurl.php +++ b/lib/Consumer/ForkCurl.php @@ -62,14 +62,17 @@ public function flushBatch($messages) $cmd2 = "echo " . $payload . " | gzip > " . $tmpfname; exec($cmd2, $output, $exit); - if (0 != $exit) { + if (0 == $exit) { + $cmd .= " -H 'Content-Encoding: gzip'"; + $cmd .= " --data-binary '@" . $tmpfname . "'"; + } else { $this->handleError($exit, $output); - return self::FLUSH_BATCH_NON_RETRYABLE_FAILURE; + if (is_file($tmpfname)) { + unlink($tmpfname); + } + $tmpfname = ""; + $cmd .= " -d " . $payload; } - - $cmd .= " -H 'Content-Encoding: gzip'"; - - $cmd .= " --data-binary '@" . $tmpfname . "'"; } else { $cmd .= " -d " . $payload; } diff --git a/lib/Consumer/LibCurl.php b/lib/Consumer/LibCurl.php index 343fb33..ef6b91e 100644 --- a/lib/Consumer/LibCurl.php +++ b/lib/Consumer/LibCurl.php @@ -68,15 +68,26 @@ public function flushBatch($messages) return self::FLUSH_BATCH_NON_RETRYABLE_FAILURE; } + $isCompressed = false; if ($this->compress_request) { - $payload = gzencode($payload); + $compressedPayload = gzencode($payload); - if (false === $payload) { - return self::FLUSH_BATCH_NON_RETRYABLE_FAILURE; + if (false !== $compressedPayload) { + $payload = $compressedPayload; + $isCompressed = true; + } else { + $this->handleError(0, "Failed to gzip batch payload; sending uncompressed."); } } $shouldVerify = $this->options['verify_batch_events_request'] ?? true; + $requestOptions = [ + 'shouldVerify' => $shouldVerify, + ]; + if ($this->compress_request) { + $requestOptions['compressRequest'] = $isCompressed; + } + $response = $this->httpClient->sendRequest( '/batch/', $payload, @@ -84,9 +95,7 @@ public function flushBatch($messages) // Send user agent in the form of {library_name}/{library_version} as per RFC 7231. "User-Agent: {$this->userAgent()}", ], - [ - 'shouldVerify' => $shouldVerify, - ] + $requestOptions ); if (!$shouldVerify) { diff --git a/lib/Consumer/Socket.php b/lib/Consumer/Socket.php index b4e18e8..143f35d 100644 --- a/lib/Consumer/Socket.php +++ b/lib/Consumer/Socket.php @@ -196,15 +196,17 @@ private function createBody($host, $content) // Send user agent in the form of {library_name}/{library_version} as per RFC 7231. $req .= "User-Agent: " . $this->userAgent() . "\r\n"; - // Compress content if compress_request is true + // Compress content if compress_request is true. If local compression fails, + // keep sending the original uncompressed payload. if ($this->compress_request) { - $content = gzencode($content); + $compressedContent = gzencode($content); - if (false === $content) { - return false; + if (false !== $compressedContent) { + $content = $compressedContent; + $req .= "Content-Encoding: gzip\r\n"; + } else { + $this->handleError(0, "Failed to gzip batch payload; sending uncompressed."); } - - $req .= "Content-Encoding: gzip\r\n"; } $req .= "Content-length: " . strlen($content) . "\r\n"; diff --git a/lib/HttpClient.php b/lib/HttpClient.php index bbf78fd..908978e 100644 --- a/lib/HttpClient.php +++ b/lib/HttpClient.php @@ -84,7 +84,8 @@ public function __construct( * shouldRetry?: bool, * shouldVerify?: bool, * includeEtag?: bool, - * timeout?: int + * timeout?: int, + * compressRequest?: bool * } $requestOptions * @return HttpResponse */ @@ -98,6 +99,7 @@ public function sendRequest(string $path, ?string $payload, array $extraHeaders $shouldRetry = $requestOptions['shouldRetry'] ?? true; $shouldVerify = $requestOptions['shouldVerify'] ?? true; $includeEtag = $requestOptions['includeEtag'] ?? false; + $compressRequest = $requestOptions['compressRequest'] ?? $this->compressRequests; do { // open connection @@ -109,7 +111,7 @@ public function sendRequest(string $path, ?string $payload, array $extraHeaders $headers = []; $headers[] = 'Content-Type: application/json'; - if ($this->compressRequests) { + if ($compressRequest) { $headers[] = 'Content-Encoding: gzip'; }