Страницы

Поиск по вопросам

Показаны сообщения с ярлыком http-заголовки. Показать все сообщения
Показаны сообщения с ярлыком http-заголовки. Показать все сообщения

понедельник, 6 января 2020 г.

Получение всех HTTP заголовков страницы

#php #http #curl #http_заголовки


Всем привет. Допустим, есть сайт site.ru. С помощью данного скрипта я могу получить
лишь сам адрес страницы:

if( $curl = curl_init() ) {
curl_setopt($curl,CURLOPT_URL,'http://site.ru');
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_NOBODY,true);
curl_setopt($curl,CURLOPT_HEADER,true);
$out = curl_exec($curl);
echo $out;
curl_close($curl);
}


В браузере вижу следующее:

HTTP/1.1 301 Moved Permanently
Date: Sun, 14 May 2017 09:54:15 GMT
Server: Apache/2.4.7 (Ubuntu)
Location: http://site.ru/
Content-Type: text/html; charset=iso-8859-1


Как получить все заголовки, получаемые в инструментах разработчика (F12->Network)?
(Кто знает расширение для хрома Creative Tester - Live HTTP Headers(логотип круга салатового
цвета) - результат нужен примерно такой же, вернее, нужны только ссылки)

    


Ответы

Ответ 1



Возможно, get_headers():

Ответ 2



$raw_headers = ''; curl_setopt($curl, CURLOPT_HEADERFUNCTION, '__write_header'); public function __write_header($curl, $bytes) { $GLOBALS['raw_headers'] .= $bytes; return strlen($bytes); } CURLOPT_HEADERFUNCTION Callback-функция принимает два параметра. Первым параметром является дескриптор cURL, вторым параметром является строка с записываемыми заголовками. Заголовки должны быть записаны с помощью данной callback-функции. Должна возвратить количество записанных байт. описание взято отсюда

среда, 19 июня 2019 г.

Вернуть правильное значение Content-Length при HEAD запросе к WCF службе

Есть self-hosted WCF служба со следующим контрактом:
[ServiceContract] interface IMyService { [OperationContract] [WebInvoke(Method = "HEAD", UriTemplate = "Files/{fileName}")] void GetFileInfo(string fileName);
[OperationContract] [WebGet(UriTemplate = "Files/{fileName}")] Stream StreamFile(string fileName); }
Упрощённая реализация её такова:
class MyService : IMyService { public void GetFileInfo(string fileName) { string filePath = Path.Combine("Files", fileName); FileInfo fi = new FileInfo(filePath);
var response = WebOperationContext.Current.OutgoingResponse; response.ContentType = "application/octet-stream"; response.ContentLength = fi.Length; response.StatusCode = HttpStatusCode.OK; response.SuppressEntityBody = true; }
public Stream StreamFile(string fileName) { ... } }
Проблема в методе GetFileInfo. Когда происходит HEAD запрос к службе (например, с помощью WebRequest):
var uri = new Uri("http://localhost:8733/MyService/Files/test.dat"); var req = WebRequest.Create(uri); req.Method = "HEAD"; using (var resp = req.GetResponse() as HttpWebResponse) { Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription); foreach (string header in resp.Headers) Console.WriteLine("{0}: {1}", header, resp.Headers[header]); }
то в ответ приходит:
HTTP/1.1 200 OK Content-Length: 1234 Content-Type: application/octet-stream Date: Wed, 22 Jun 2016 10:17:38 GMT Server: Microsoft-HTTPAPI/2.0
но это в случае, если длина запрашиваемого файла не превышает int.MaxValue. Если же длина файла превышает int.MaxValue то Content-Length в ответе имеет значение 0:
Content-Length: 0
Как это победить? Как заставить возвращать нормальную длину для больших файлов?
Конфигурация WCF-службы (если это важно):


Ответ

Похоже, что это ошибка в коде System.ServiceModel, а конкретно - вот в этом участке. Интересно то, что проблема сохраняется и при хостинге сервиса в IIS.
Как вариант исправления - создать кастомный байндинг, наследующий от WebHttpBinding, с кастомным transport channel, и в нем организовать правильную расстановку заголовков у HttpListener (этот класс используется при self-хостинге сервисов с http-транспортом).
IMHO, это неоправданно сложно. Проще пойти на нарушение принципов RESTful-архитектуры и сделать запрос размера файла через POST с результатом в теле ответа. Или отправлять длину в другом заголовке.

Проблемные участки кода
// HttpChannelHelpers.cs, line 2988 if (string.Compare(name, "content-length", StringComparison.OrdinalIgnoreCase) == 0) { int contentLength = -1; if (httpMethodIsHead && int.TryParse(value, out contentLength)) { this.SetContentLength(contentLength); } // else //this will be taken care of by System.Net when we write to the content }
и
// HttpChannelHelpers.cs, line 3061 protected override void SetContentLength(int contentLength) { listenerResponse.ContentLength64 = contentLength; }