<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">чт, 26 дек. 2019 г. в 01:13, Maxim Dounin <<a href="mailto:mdounin@mdounin.ru">mdounin@mdounin.ru</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello!<br>
<br>
On Thu, Dec 26, 2019 at 12:32:04AM +0500, Илья Шипицин wrote:<br>
<br>
> ср, 25 дек. 2019 г. в 23:20, Maxim Dounin <<a href="mailto:mdounin@mdounin.ru" target="_blank">mdounin@mdounin.ru</a>>:<br>
> <br>
> > Hello!<br>
> ><br>
> > On Wed, Dec 25, 2019 at 02:58:15PM +0500, Илья Шипицин wrote:<br>
> ><br>
> > > ср, 25 дек. 2019 г. в 14:38, Sergey Kandaurov <<a href="mailto:pluknet@nginx.com" target="_blank">pluknet@nginx.com</a>>:<br>
> > ><br>
> > > ><br>
> > > > > On 24 Dec 2019, at 23:35, Илья Шипицин <<a href="mailto:chipitsine@gmail.com" target="_blank">chipitsine@gmail.com</a>> wrote:<br>
> > > > ><br>
> > > > > привет!<br>
> > > > ><br>
> > > > > допустим, такая ситуация. есть POST запрос, у него есть хедеры и,<br>
> > > > собственно, тело запроса. мы отправили хедеры на бекенд, тело не успели<br>
> > > > отправить, и бекенд нам сделал TCP RST.<br>
> > > > ><br>
> > > > > должен ли такой POST повторно отправляться, если не указан<br>
> > > > non_idempotent ? (судя по моим экспериментам - не отправляется. но ведь<br>
> > > > тело не было отправлено ? значит мы должны попасть под условие, что<br>
> > такой<br>
> > > > запрос можно отправить повторно ?)<br>
> > > ><br>
> > > > Как только мы успешно установили соединение и перешли к отправке<br>
> > запроса<br>
> > > > (не важно, успели начать отправку тела или нет), запрос считается<br>
> > > > отправленным,<br>
> > > > т.к. в общем случае мы не знаем, был ли он обработан или нет.<br>
> > > ><br>
> > ><br>
> > > я предлагаю такую логику.<br>
> > > бекенд умеет отличать полностью полученный запрос от неполного запроса<br>
> > > (например, по Content-Length)<br>
> > > навряд ли бекенд будет обрабатывать неполностью полученный запрос<br>
> > ><br>
> > > и считать отправленными только полностью отправленные запросы<br>
> ><br>
> > Считать-то можно, но у бекенда может быть своё мнение по этому<br>
> > вопросу.  Каких-либо явных утверждений в RFC 2616 / RFC 7231,<br>
> > которые бы говорили о том, что так можно - я в своё время не<br>
> > нашёл.  И по факту так скорее всего нельзя, так как на тело<br>
> > бекенду во многих случаях может быть наплевать.<br>
> ><br>
> <br>
> есть достаточно странный кейс, когда отправляется POST без тела. не<br>
> конкретно в наших приложениях, а в принципе.<br>
> я по некоторым разбирался, зачем так делают (ну то есть, можно же GET, но<br>
> специально сделали POST). ответ меня поразил -<br>
> по RFC нельзя кешировать POST. ну и чтобы наверняка без кеша, мы выбрали<br>
> POST )) ну а тело ... надо не надо было<br>
> <br>
> в описанном выше случае, действительно, тело (запроса) не предполагалось.<br>
> <br>
> если тело предполагается, но не было отправлено, допустим бекенд вменяемый,<br>
> что вполне может быть. он запрос не обработал.<br>
> можно ретраить.<br>
> <br>
> каких-то явных противоречий в этом не вижу<br>
<br>
Явных противоречий тут и нет: скорее всего бекенд смотрит на тело, <br>
и в тех немногих случаях, когда мы точно знаем, что оно отправлено <br>
не полностью - скорее всего можно ретраить. <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Однако проблем тут две:<br>
<br>
- "Скорее всего можно" - не значит "точно можно", наступить на <br>
  ситуацию, когда бекенд на тело не смотрит - на практике вполне <br>
  можно.  И каких-либо явных причин требовать от бекенда, чтобы <br>
  смотрел - я, как я уже писал выше, не вижу, и если у такого <br>
  бекенда вдруг что-то пойдёт не так - виноват будет nginx.  (Если эти <br>
  причины вдруг есть - с удовольствием ознакомлюсь с соответствующей <br>
  цитатой из RFC.)<br>
<br>
- Условие "когда мы точно знаем" не выполняется приблизительно <br>
  никогда: в подавляющем большинстве случаев тело вместе с <br>
  запросом уже сложено в буфер сокета, и что там с ним стало <br>
  дальше - узнать невозможно.  То есть мы про микрооптимизацию <br>
  оцень небольшого процента запросов.<br>
<br></blockquote><div><br></div><div>ну вот у меня ситуация, когда я знаю, что можно.</div><div>рассказываю.</div><div><br></div><div>берем IIS. на нем хостим <a href="http://ASP.NET">ASP.NET</a></div><div><a href="http://ASP.NET">ASP.NET</a> хостится в т.н. AppPool, у этого пула есть режим "пул остановлен"</div><div><br></div><div>можно настроить пул на HttpLevel, либо на TcpLevel, в первом случае остановленный пул отдает 503, во втором tcp rst.</div><div><br></div><div>вы хотели RFC ? оно есть у меня. смотрите, есть такой хидер Expect. смотрим RFC, там сказано, что он End-to-End.</div><div>итак, рассмотрим цепочку</div><div><br></div><div>Браузер --> nginx --> IIS</div><div><br></div><div>браузер посылает Expect: 100-Continue, по RFC nginx должен его доставить до IIS ? но этого не происходит.</div><div>IIS (и http.sys под капотом) ответил бы Expect, и у nginx была бы инфа, что запрос не успел отправиться</div><div><br></div><div>но nginx не отправляет Expect.</div><div><br></div><div>и POST улелает в остановленный пул. если пул настроен на HttpLEvel, то пул отдает 503 уже после отправки (были бы Expect-ы, отдал бы до).</div><div><br></div><div>ок, меняем режим пула на TcpLevel, пул должен сделать tcp rst. и он его сделает. но! нюанс. после отправки хидеров. <br></div><div>объяснение простое, на порту, на котором слушает IIS, могут быть несколько приложений (пулов), чтобы понять, в какой именно пул мы попали, нужно поле Host.</div><div><br></div><div>но я точно знаю, что tcp rst идет до отправки тела. и nginx это точно знает.</div><div><br></div><div><br></div><div><br></div><div>а разработчики, которые пишут идеальные приложения ... ну я тоже люблю фантазировать.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Вместе эти две проблемы привели меня в своё время к выводу, что не  <br>
стоит тут пытаться что-то наоптимизировать, кому надо - сделают <br>
правильно с защитой на уровне приложения, кому не надо - получают <br>
гарантированно корректное поведение из коробки.<br>
<br>
-- <br>
Maxim Dounin<br>
<a href="http://mdounin.ru/" rel="noreferrer" target="_blank">http://mdounin.ru/</a><br>
_______________________________________________<br>
nginx-ru mailing list<br>
<a href="mailto:nginx-ru@nginx.org" target="_blank">nginx-ru@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-ru" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-ru</a></blockquote></div></div>