fix download large file for map download

This commit is contained in:
Beu
2025-07-25 21:49:05 +02:00
parent 1fb7c87925
commit ee0b0ac166
6 changed files with 222 additions and 134 deletions

View File

@@ -6,7 +6,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
class Request extends EventDispatcher implements RequestInterface
{
/**
* @var resource cURL handler
* @var \CurlHandle cURL handler
*/
protected $ch;
@@ -19,6 +19,11 @@ class Request extends EventDispatcher implements RequestInterface
* @var Options Object containing options for current request
*/
protected $options = null;
/**
* @var array Response Headers feed by the CURLOPT_HEADERFUNCTION callback
*/
protected $responseHeaders;
/**
* Create new cURL handle
@@ -30,6 +35,35 @@ class Request extends EventDispatcher implements RequestInterface
if ($url !== null) {
$this->getOptions()->set(CURLOPT_URL, $url);
}
$this->getOptions()->set(CURLOPT_HEADERFUNCTION, function($ch, $headerLine) {
$len = strlen($headerLine);
// Handle HTTP status lines (e.g., HTTP/1.1 200 OK)
if (preg_match('/^HTTP\/\d\.\d\s+\d+/', $headerLine)) {
$this->responseHeaders = []; // Reset on redirect or multiple responses
}
$parts = explode(':', $headerLine, 2);
if (count($parts) === 2) {
$key = strtolower(trim($parts[0]));
$value = trim($parts[1]);
// Handle multiple headers with same name
if (!isset($this->responseHeaders[$key])) {
$this->responseHeaders[$key] = $value;
} else {
if (is_array($this->responseHeaders[$key])) {
$this->responseHeaders[$key][] = $value;
} else {
$this->responseHeaders[$key] = [$this->responseHeaders[$key], $value];
}
}
}
return $len;
});
$this->ch = curl_init();
}
@@ -72,7 +106,7 @@ class Request extends EventDispatcher implements RequestInterface
/**
* Returns cURL raw resource
*
* @return resource cURL handle
* @return \CurlHandle cURL handle
*/
public function getHandle()
{
@@ -89,6 +123,16 @@ class Request extends EventDispatcher implements RequestInterface
{
return (int)$this->ch;
}
/**
* Get the response headers
*
* @return array
*/
public function getResponseHeaders()
{
return $this->responseHeaders;
}
/**
* Perform a cURL session.
@@ -108,6 +152,7 @@ class Request extends EventDispatcher implements RequestInterface
$content = curl_exec($this->ch);
$response = new Response($this, $content);
$response->setHeaders($this->responseHeaders);
$errorCode = curl_errno($this->ch);
if ($errorCode !== CURLE_OK) {
$response->setError(new Error(curl_error($this->ch), $errorCode));

View File

@@ -11,7 +11,7 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, \
protected $defaultOptions = null;
/**
* @var resource cURL multi handler
* @var \CurlMultiHandle cURL multi handler
*/
protected $mh;
@@ -115,6 +115,7 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, \
$event = new Event();
$event->request = $request;
$event->response = new Response($request, curl_multi_getcontent($request->getHandle()));
$event->response->setHeaders($event->request->getResponseHeaders());
if ($result !== CURLE_OK) {
$event->response->setError(new Error(curl_error($request->getHandle()), $result));
}

View File

@@ -19,18 +19,7 @@ class Response
$this->ch = $request->getHandle();
if ($content != null) {
$header_size = $this->getInfo(CURLINFO_HEADER_SIZE);
foreach (explode("\r\n", substr($content, 0, $header_size)) as $value) {
if(false !== ($matches = explode(':', $value, 2))) {
if (count($matches) === 2) {
$headers_arr["{$matches[0]}"] = trim($matches[1]);
}
}
}
$this->headers = $headers_arr;
$this->content = substr($content, $header_size);
$this->content = $content;
}
}
@@ -89,6 +78,17 @@ class Response
return isset($this->error);
}
/**
* Sets headers
*
* @param array $error headers to set
* @return void
*/
public function setHeaders(array $headers)
{
$this->headers = $headers;
}
/**
* Returns headers of request
*