Я не совсем уверен, что здесь происходит. Некоторое время назад я сделал небольшую вещь в Интернете, которая создает HTTP-запросы, которые выглядят так:
POST /update.py HTTP/1.1
Host: iot.example.com
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: [...]
iv=[...]&msg=base64(encrypted_msg)
И соответствующий скрипт python на стороне сервера, который извлекал информацию из данных POST. Недавно я изменил обратный прокси-сервер своего брандмауэра с squid на HAProxy, и внезапно Apache возвращается HTTP 400
статусы, по-видимому, до того, как IOT-устройство даже получит возможность отправить данные POST. Вот TCP-поток wirehark одного из этих взаимодействий:
POST /update.py HTTP/1.1
Host: iot.example.com
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
X-Forwarded-Proto: http
X-Forwarded-For: xx.xx.xx.xx
HTTP/1.1 400 Bad Request
Date: Sat, 17 Jun 2017 22:29:45 GMT
Server: Apache/2.4.25 (FreeBSD) mod_wsgi/4.5.15 Python/2.7
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
iv=En98cormFMA7NO5e-4qh2Q==&msg=ek_JDRJPqPUvNlztUVH6FTtfVVdHgODWMimBcZklos2XntlMOM1RweBjsp5z-zY=
HTTP/1.1 400 Bad Request
и </html>
это ответы сервера, все остальное - это то, что сервер получает. Заголовки X-Forwarded * были установлены HAProxy. Насколько я знаю, Squid не использовал этиДействительно странно то, что Apache отвечает еще до того, как получит данные POST. Сервер отлично отвечает на GET
запросов, и я запускаю некоторые другие серверы Apache за тем же брандмауэром, которые, похоже, работают. Единственная реальная разница, о которой я могу думать, заключается в том, что эти HTTP-запросы в значительной степени жестко запрограммированы для микроконтроллера, с которого они исходят, и, возможно, они не совсем правильны с самого начала. Любые предложения были бы очень признательны. Заранее спасибо!
Оказывается, проблема заключалась в окончании строк в моих HTTP-запросах. Я отправлял смесь LF и CRLF. RFC2616 требует, чтобы HTTP / 1.1 использовал только CRLF, но также заявляет, что серверы должны реализовать «положение о допуске». Однако Apache> = 2.4.25 по умолчанию HttpProtocolOptions Strict
который возвращает HTTP/1.1 400
status для всех искаженных заголовков.
FreeBSD поставляет Apache 2.4.25 с декабря, но я предполагаю, что Squid упорядочивал для меня заголовки, потому что тогда он не сломался. Я предполагаю, что HAProxy более свободен, поэтому при переходе с Squid на HAProxy сервер столкнулся с моей старой ошибкой прошивки.
Правильным решением будет перепрошить микроконтроллер исправленной прошивкой, но это хлопотно. Быстрый и грязный обходной путь - попросить Apache расслабиться. Добавление HttpProtocolOptions Unsafe
к httpd.conf
это быстрое "исправление" и, по крайней мере, на данный момент восстанавливается и работает регистрация данных.