Добрый день!
У меня возникла некоторая проблема с оправкой файлов в хранилище под управлением OpenStack, хотя оно тут не причем.
Суть: Мы конектимся к хранилищу и оправляем файл заданный строкой.
Кусок кода:$string = 'file_string'; // это тестовая строка из которой будет создан файл
$file_res = fopen('php://temp', 'w+b');
fwrite($file_res, $string);
fseek($file_res, 0);
$file_size = mb_strlen($string); // получаем размер файла
$file_md5 = md5($string); // это будет E-tag
$file_type = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $string); // пытаемся определить тип файла по строке
if($file_type === false) return false;
$headers = array();
$headers[] = 'X-Auth-Token: '.$auth_key; // ключ авторизации
$headers[] = 'ETag: '.$file_md5;
$headers[] = 'Content-Length: '.$file_size;
$headers[] = 'Content-Type: '.$file_type;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_USERAGENT, "MyAgent");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $file_res);
curl_setopt($ch, CURLOPT_INFILESIZE, $file_size);
$content = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
fclose($file_res);
И так. Под
Windows все отлично работает и файл создается в хранилище, но под Linux я получаю ошибку
400 Bad Request. Причем проверил я это на 5 разных хостинг площадках. Любая версия cURL под Linux получает 400 Bad Request.
Посмотрев, что за заголовки отправляются под Windows и под Linux я выяснил что:
1. Под Windows все правильно
2. Под Linux идет заголовок Content-Length 2 раза!
Если я не хочу что бы заголовок Content-Length шел 2 раза, я могу убрать из массива $headers добавление заголовка, но тогда это не будет работать на Winows версией.
Я могу отключить CURLOPT_INFILESIZE, на Windows не работает вообще, на Linux + ко всему добавляется Transfer-Encoding: chunked и заголовок Content-Length уже не учитывается - файл отправляется.
Вообщем что бы всё работало там и там в данный момент я не оправляю Content-Length и убрал CURLOPT_INFILESIZE, добавив Transfer-Encoding: chunked.
Вопрос: Что это за дела такие?