Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

fixed removing handled header parts from response header #6691

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions library/Zend/Http/Client/Adapter/Curl.php
Original file line number Diff line number Diff line change
Expand Up @@ -421,19 +421,26 @@ public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $bo
throw new AdapterException\RuntimeException("Error in cURL request: " . curl_error($this->curl));
}

// separating header from body because it is dangerous to accidentially replace strings in the body
$responseHeaderSize = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE);
$responseHeaders = substr($this->response, 0, $responseHeaderSize);

// cURL automatically decodes chunked-messages, this means we have to disallow the Zend\Http\Response to do it again
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I separated header from body, to be sure that i don't manipulate the body. Possible test:
Textfile with Transfer-Encoding: chunked\r\n inside AND the webserver must not make use of chunking.
In the old version the assert that the file is the same would probably fail.

if (stripos($this->response, "Transfer-Encoding: chunked\r\n")) {
$this->response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $this->response);
}
$responseHeaders = preg_replace("/Transfer-Encoding:\s*chunked\\r\\n/", "", $responseHeaders);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In most cases the Transfer-Encoding:*whitespace*chunked is true, but I found some cases (at that time back than buzzfeed.com for example) where there was no whitespace between the two parts. Problem: I was not able to send a header without that whitespace. Maybe the server or php corrects the header before sending.

// cURL can automatically handle content encoding; prevent double-decoding from occurring
if (isset($this->config['curloptions'][CURLOPT_ENCODING])
&& '' == $this->config['curloptions'][CURLOPT_ENCODING]
&& stripos($this->response, "Content-Encoding: gzip\r\n")
) {
$this->response = str_ireplace("Content-Encoding: gzip\r\n", '', $this->response);
$responseHeaders = preg_replace("/Content-Encoding:\s*gzip\\r\\n/", "", $responseHeaders);
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above


// cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string:
$responseHeaders = preg_replace("/HTTP\/1.0\s*200\s*Connection\s*established\\r\\n\\r\\n/", "", $responseHeaders);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just changed the position and also use a regexp for the same reasons as above

// replace old header with new, cleaned up, header
$this->response = substr_replace($this->response, $responseHeaders, 0, $responseHeaderSize);

// Eliminate multiple HTTP responses.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

traded old header part against the new, cleaned up, version

do {
$parts = preg_split('|(?:\r?\n){2}|m', $this->response, 2);
Expand All @@ -445,11 +452,6 @@ public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $bo
}
} while ($again);

// cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string:
if (stripos($this->response, "HTTP/1.0 200 Connection established\r\n\r\n") !== false) {
$this->response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $this->response);
}

return $request;
}

Expand Down