9

Я ищу инструмент (возможно, в Linux), который позволил бы мне сделать ручной запрос HTTP или HTTPS. Под руководством я действительно имею в виду: я должен быть в состоянии передать ему текстовый файл, который выглядит как

POST /foo HTTP/1.1
Host: www.example.com
Accept: text/xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-gb,en;q=0.5
Content-Type: text/plain
Content-Length: 11

Hello world

и целевой URL (www.example.com/foo) и отправьте запрос на URL. Самое большее, было бы полезно, если бы заголовок Content_Length вычислялся автоматически.

Я мог бы написать такой инструмент, используя некоторую библиотеку, такую как httplib в Python, но сама причина, по которой мне это нужно, - это проводить ручное исследование, когда что-то не так с такими библиотеками.

5 ответов5

9

У wget есть опция --post-file, которая должна работать на вас.

Изменить: Кроме того, есть Ncat, который вы бы использовали аналогично предложению Рэндольфа Ричардсона Telnet, за исключением того, что он также поддерживает SSL/HTTPS:

ncat -C --ssl www.example.com 443 < input.txt > output.txt
6

Для HTTP (не HTTPS) одна альтернатива команде "wget", которая приходит на ум, - это использовать telnet следующим образом:

  • имя хоста telnet 80 <input.txt> output.txt

Файл "input.txt" представляет собой список предварительно заданных команд, которые вы хотите передать хосту по имени хоста, а файл "output.txt" будет хранить ответ.

1

Вы можете отправить запрос GET с помощью OpenSSL:

openssl s_client -quiet -connect cdn.sstatic.net:443 <<eof
GET /stackexchange/js/universal-login.js HTTP/1.1
Connection: close
Host: cdn.sstatic.net

eof

Обратите внимание, что вы также можете использовать «HTTP /2», но будьте осторожны, потому что некоторые серверы (например, github.com) не поддерживают его.

0

Для меня это сработало создание файла запроса (Пример: request.txt)

POST /foo HTTP/1.1
Host: www.example.com
Accept: text/xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-gb,en;q=0.5
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: close

Hello world

А затем вызовите команду openssl s_client :

cat request.txt | openssl s_client -quiet -connect www.example.com:443

Однако будьте осторожны с некоторыми моментами:

  • Файл должен быть правильно закодирован , особенно текстовое содержимое. Лучше, если вы включите заголовок Content-type: text/plain; charset=utf-8 если файл имеет кодировку utf-8.
  • Концы строк для заголовков должны быть CR/LF. Только с LF веб-сервер может вернуть HTTP/1.1 505 HTTP Version Not Supported , потому что стандартный протокол HTTP использует CR/LF для окончания строки (https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html), Вы можете использовать команду unix2dos чтобы сделать это преобразование.
  • Добавьте заголовок Connection: close чтобы завершить запрос и вернуться из вызова. В противном случае команда будет ожидать взаимодействия с пользователем, если сервер обычно отвечает заголовком Connection: keep-alive .
-1

Я удивлен, что никто не упомянул cURL. Это сделано именно для того, что вы хотите сделать. И это доступно практически на любой платформе (включая Windows).

Итак, для вашего примера все, что вам нужно сделать, это:

curl -H 'Content-Type: text/plain' -d 'Hello World' www.example.com

Который пойман с Wireshark будет вам чистым:

POST / HTTP/1.1
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: www.example.com
Accept: */*
Content-Type: text/plain
Content-Length: 11

Hello world

Вы можете легко изменить заголовки, если захотите делать все что угодно (например, изменять агента пользователя и т.д.).

Изменить: не заметил требование "из файла". Вы также можете сделать это, либо в простом ascii, либо в двоичных файлах. Вы просто указываете имя файла с символом @

-d @/tmp/HelloWorldFile

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .