#python
#python
Вопрос:
У меня есть следующий код python:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("example.com", 443))
client.send(b'POST /api HTTPS/1.1rnHost: example.comrnUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0rnAccept-Encoding: gzip, deflaternAccept: application/jsonrnConnection: keep-alivernContent-Type: application/jsonrnAuthoriation: aarnContent-Length: 22rnrn')
client.send(b'{"jsonPostData": "aaa"}')
response = client.recv(4096)
response = repr(response)
Но он возвращает ошибку 400 bad request без содержимого, я пробовал одни и те же заголовки и json с запросами и aiohttp, и в обоих случаях это работает, есть идеи о том, что я делаю неправильно?
Комментарии:
1. Обычно, используя pypi.org/project/requests это гораздо проще. Вы решили использовать
socket
его специально? Если нет: w3schools.com/python/ref_requests_post.asp2. Я использую его специально, так как это быстрее или с несколькими запросами
3. используете ли вы пулы / сеансы соединений с aiohttp / запросами?
4. Почему вы говорите, что это быстрее для нескольких запросов? Вы пытаетесь отправлять запросы на очень удаленный сервер? Например, запрашивать сервер США из Азии? Если это так, у меня есть некоторый опыт использования запросов в этом контексте. Как уже упоминалось, пулы и сеансы очень полезны. Есть несколько других советов
Ответ №1:
Никогда не пишите свой собственный http-клиент, если вы не являетесь экспертом по TCP, TLS, HTTP (S) и API-дизайну, это не будет ни надежным, ни удобным.
Что касается вашего фрагмента кода — вы не можете использовать простые сокеты для безопасных подключений, вы должны использовать безопасные сокеты.
import socket
import ssl
def request(sock):
sock.sendall(
b'POST /post HTTP/1.1rn'
b'host: postman-echo.comrn'
b'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0rn'
# b'Accept-Encoding: gzip, deflatern' # do you really want to handle it?
b'accept: application/jsonrn'
b'connection: keep-alivern'
b'content-type: application/jsonrn'
b'content-length: 14rn'
b'rn'
b'{"qwe": "rty"}'
)
return sock.recv(4096)
if __name__ == "__main__":
tls = True # toggle
context = ssl.create_default_context()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
if not tls:
sock.connect(("postman-echo.com", 80))
response = request(sock)
else:
with context.wrap_socket(sock, server_hostname="postman-echo.com") as ssock:
ssock.connect(("postman-echo.com", 443))
response = request(ssock)
print(response)
Из ответа
"json": {"qwe":"rty"}
Комментарии:
1. Спасибо за ответ, но я все равно получаю тот же плохой ответ на запрос.
2. Код из ответа работает как есть? Если вы ничего не измените.
3. Да, моя ошибка, неправильно обработал текст сообщения
Ответ №2:
Вы пытаетесь подключиться к SSL-порту, используя не SSL-соединение.
Попробуйте использовать библиотеку запросов. Попробуйте подключиться к порту 80.
Комментарии:
1. Он автоматически переключается на HTTPS, я отредактирую комментарий, но это не проблема.
2. что автоматически переключается на HTTPS?
socket
модуль очень низкоуровневый, в нем нет ничего автоматического3. Веб-сервер перенаправляет меня на https