cURL завис на 15 секунд при отправке HEAD-запросов - PullRequest
12 голосов
/ 28 ноября 2011

Фон

Я синхронизировал некоторые HTTP-запросы через CLI, используя time и такие инструменты, как wget и curl, следующим образом:

/usr/bin/time -v wget --spider http://localhost/index
/usr/bin/time -v curl http://localhost/index 2>&1 > /dev/null

Что я заметил, так это то, что при использовании curl я получал время отклика, аналогичное wget только для первого запроса, и гораздо меньшее время для последующих запросов, как будто ответыcurl были получены из кэша, а wget - нет.

После исследования я обнаружил, что при указании --spider, wget выдает запрос HEAD, как указано ниже, который может объяснить, почемукеш обходится с помощью wget:

Запрос

HEAD /index HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost
Connection: Keep-Alive

Ответ

HTTP/1.1 200 OK
Date: Mon, 28 Nov 2011 14:45:59 GMT
Server: Apache/2.2.14 (Ubuntu)
Content-Location: index.php
Vary: negotiate,Accept-Encoding
TCN: choice
X-Powered-By: PHP/5.3.2-1ubuntu4.10
Set-Cookie: SESS421aa90e079fa326b6494f812ad13e79=16oqmug3loekjlb1tlvmsrtcr2; expires=Wed, 21-Dec-2011 18:19:19 GMT; path=/
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Mon, 28 Nov 2011 14:45:59 GMT
Cache-Control: store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

Поскольку яделать более сложные вещи (писать тело и заголовки в отдельных файлах, публиковать данные, сохранять куки в jar ...) Мне нужно использовать curl вместо wget.Поэтому я пытаюсь эмулировать HEAD запрос с curl.

Issue

Мне удалось отправить HEAD запрос с curl следующим образом:

curl "http://localhost/index" --request "HEAD" -H "Connection: Keep-Alive" -0

Запрос

HEAD /index HTTP/1.0
User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
Host: localhost
Accept: */*
Connection: Keep-Alive

Ответ

HTTP/1.1 200 OK
Date: Mon, 28 Nov 2011 15:44:02 GMT
Server: Apache/2.2.14 (Ubuntu)
Content-Location: index.php
Vary: negotiate,Accept-Encoding
TCN: choice
X-Powered-By: PHP/5.3.2-1ubuntu4.10
Set-Cookie: SESS421aa90e079fa326b6494f812ad13e79=4001hcmhdbnkb9e2v8nok9lii1; expires=Wed, 21-Dec-2011 19:17:22 GMT; path=/
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Mon, 28 Nov 2011 15:44:02 GMT
Cache-Control: store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

Несмотря на то, что запрос / ответ кажутсяХорошо, когда я выполняю указанную выше команду curl во время сниффинга с tcpdump, я вижу, что сервер отвечает сразу, однако моя curl команда всегда висит ровно 15 секунд , что, очевидно, являетсябольшая проблема, так как я пытаюсь рассчитать время моей команды curl (к вашему сведению, прежде чем я получил curl: (18) transfer closed with 3 bytes remaining to read, когда сервер неправильно обрабатывал HEAD и возвращал Content-Length: 3 без возврата какого-либо контента, но не все выглядитОК).

Я попытался поиграть с аргументами --max-time и --speed-time, чтобы получить curl тайм-аут сразу после получения 200 OK, но это не имеет значения.

Q: Как я могу отправить запрос HEAD с curl так, как команда curlостанавливается сразу после получения ответа от сервера?

1 Ответ

22 голосов
/ 28 ноября 2011

Почему бы вам просто не использовать опцию -I?

-I/--head
    (HTTP/FTP/FILE) Fetch the HTTP-header only! HTTP-servers feature
    the command HEAD which this uses to get nothing but  the  header
    of  a  document.  When used on a FTP or FILE file, curl displays
    the file size and last modification time only
...