Форвард проксито чете реда на заявката и заглавките, препраща ги и след това чака в select POST тяло. Клиентът вече го е изпратил. И двете страни изглежда чакат другата.

При BaseHTTPRequestHandler на Python четенето на заглавките минава през rfile — буфериран входен поток. Този поток може да чете напред и да задържа байтове, принадлежащи на тялото. Чакането на подлежащия сокет пита само дали файловият му дескриптор е готов; не пита дали потокът на Python вече съдържа използваеми данни.

Следвайте буфера, който прочете заглавките

Четете тялото също през self.rfile. Не преминавайте към self.connection.recv след разбор на заглавките с буферирания поток. Иначе кодът може да прескочи байтове, които потокът вече пази, и да чака данни, които никога няма да бъдат изпратени отново.

Подаването на самия rfile към select не кара select да прегледа неговия буфер в Python. API за готовност работи през файловия дескриптор на обекта.

За заявка с един валиден Content-Length и без Transfer-Encoding изразходвайте точно обявения брой байтове, като обработвате преждевременен край на входа и вашите ограничения за размер и време. Не четете до EOF: клиент с постоянна връзка може да остави връзката отворена след приключване на заявката.

Направете рамкирането явна част от проксито

Chunked телата на заявки се нуждаят от поддръжка на chunked рамкиране. Те не могат да се четат чрез търсене на липсващ Content-Length. Двусмислените метаданни за дължина се нуждаят от дефиниран път за отхвърляне, вместо избор на заглавката, която изглежда удобна.

Блокиращ обработчик може да продължи да използва интерфейса си за поток с ограничени четения. Прокси, управлявано от събития, се нуждае от модел на буфер, който интегрира предварителното четене на парсера с управлението на готовността. Промяната на таймаут няма да примири два независими консуматора на един и същ сокет.

Тази диагноза е специфична за това къде се задържат входящите байтове. След като проксито изразходва правилното тяло, то все още трябва да препрати това тяло с последователно HTTP рамкиране. Стандартният обработчик http.server е полезно място за разбиране на механизма, но не е производствена реализация на форвард прокси.

Подобни статии