9 июня 2014 в 17:55

Баг на миллион долларов

Голландский программист Жак Матти (Jacques Mattheij) — владелец сайта ww.com и один из первых людей, кто организовал прямые трансляции с веб-камер в интернете. Он обращает внимание на баг в HTTP, благодаря которому можно заметно ускорить работу множества веб-приложений и обычных веб-сайтов.

HTTP (RFC 1945) формально является синхронным протоколом. В стандарте чётко прописано, что HTTP-ответ может быть отправлен только после получения соответствующего HTTP-запроса. На практике же всё работает иначе.

На форуме StackOverflow ещё пару лет назад обсуждалась эта тема. Действительно, сайт может выслать HTTP-ответ раньше, чем получил запрос.

Жак Матти пишет, что благодаря эксплуатации этого бага много лет назад ему удалось в десяток раз увеличить фреймрейт при трансляциях с веб-камер. Если следовать спецификациям HTTP, то скорость передачи была в районе 1 FPS, но при использовании асинхронного режима ему удалось повысить скорость до 15 FPS. Все браузеры отлично работают в асинхронном режиме, нарушая спецификации и принимая ответ от сайта до отправки запроса.

Жак говорит, что до сих пор нервничает каждый раз при выходе новых версий браузера, но напрасно: браузеры продолжают работать в обход спецификаций. Более того, новый стандарт SPDY может узаконить такой режим работы.

P.S. Матти заработал не один миллион долларов, используя этот баг, который он обнаружил раньше конкурентов.
Анатолий Ализар @alizar
карма
750,5
рейтинг 40,6
Пользователь
Похожие публикации
Самое читаемое Разработка

Комментарии (41)

  • +45
    А где миллион долларов?
    • +16
      В оригинальной статье автор говорит о нескольких миллионах долларов (The Several Million Dollar Bug) и он рассказывает, что их софт для трансляции потокового видео с камер далеко оставил конкурентов позади, поднял продажи и компания таким образом заработала.
      • +31
        Еще бы автор репоста хотя бы слово об этом упомянул.

        Уже бесить начинают его статьи. Ни о чем, без каких-либо технических подробностей. Хотя источник зачастую развернуто и подробно описывает эту сторону. Видел где то расширение, которое скрывало его посты, жаль ссылку потерял, ведь не всегда обращаешь внимание на имя автора.
        • +7
          Мне уже начинает казаться что alizar — рузультат экспериментов яндекса с самообучающимися системами. Уже очень порой напоминает Яндекс.Рефераты. Вроде и слова правильные и по делу, но все вместе вызывает лютую ненависть.
          • 0
            Скорее, эксперимент с генетическими алгоритмами.
            • 0
              Ватсон, перелогинтесь :-)
        • 0
          Вот расширение (хром), которое подсвечивает посты. Был еще фильтр, но ссылка на Userscripts.org не открывается. Видимо автор забросил проект.
          • –1
            Хм, похоже что-то сломалось
          • 0
            Что то расширение не работает. Может из-за редизайна слетело? Но все равно спасибо.
            • 0
              Накидал юзерскрипт
              Если вдруг пригодится…
              Красит заголовок, скрывает текст поста, при клике по желтому заголовку поста — показывает контент…

              Есть возможность самостоятельно расширять список авторов, хранится в куке…

  • +5
    > сайт может выслать HTTP-ответ раньше, чем получил запрос

    Я не понял как это работает. Речь идёт об уже установленном keep-alive соединении?
    • +6
      Порядок работы по rfc HTTP такой:
      1) устанавливается TCP(?) соединение
      2) клиент отправлет HTTP заголовок (полный или краткий) + опционально тело (для POST/PUT)
      3) сервер получив весь заголовок и тело формирует ответ.

      так вот между установкой соедения и получением всего заголовка проходит какоето время. Соответственно время ответа можно уменьшить если отправлять ответ сразу после установки соединения (когда ответ не зависит от заголовка) или после получения части заголовка (когда ответ, например, зависит только от первой строчки)
    • 0
      На Stack Overflow такой пример:
      Есть HTML-страница index.html, в которой размещена картинка img.jpg. Может ли сервер отправлять картинку сразу после запроса HTML-страницы, чтобы сэкономить время?

      Правда, в ответе, который помечен как лучший, сказано, что клиент может и не ожидать этих данных.
      То есть тот факт, что браузеры не падают, а компьютеры не взрываются от этого, зависит лишь от багнутости конкретной реализации. Проще говоря, сегодня они все нормально на это реагируют, а завтра Safari будет падать, а Firefox, например, жрать сотни памяти.
      • +22
        а Firefox, например, жрать сотни памяти.

        он этим спокойно занимается и без подобных хаков ;-)
        • +1
          В принципе, вы правы. Тогда поправлюсь:
          а Firefox, например, жрать сотни тысяч памяти
        • +3
          Ага, все американцы тупые, а русские пьют с медведями на балалаечном заводе.
          Уважаемый, у нас тут 2014й год на дворе.
          www.ghacks.net/2014/01/02/chrome-34-firefox-29-internet-explorer-11-memory-use-2014/
  • +2
    Речь об HTTP pipelining что ли? Тоже мне баг.
    • 0
      Эта штука даже в RFC описана, секция «8.1.2.2 Pipelining».
      • 0
        Похоже, нет. Предположим, у нас есть сервер на 80 порту, который отдает html, и на 81, который отдает картинку. Так вот, как только клиент подключается по TCP к 81 порту, ему сразу же летит картинка, еще до отправки запроса на нее.
        • 0
          Где вы это увидели? Не сочтите за наезд, просто хочется убедиться.
          • 0
            Нигде, это моя догадка. В оригинальной статье о самом способе тоже умалчивают, но я не знаю, как это еще можно сделать.
            • 0
              По описанию похоже на обычный HTTP pipelining.
              • 0
                Вы учитывайте год и то, что он не поддерживается нигде, кроме Оперы.
                • 0
                  Год 2009-й: jacquesmattheij.com/content/story-behind-wwcom-camaradescom

                  Он просто рассказал об этом в 2014-м.
                  • 0
                    Ну вот. IE6 еще распространен, картинка 320×240, во всех браузерах, кроме оперы, pipelining либо отсутствует, либо отключен.
                    • –2
                      IE тут причём? Он это не поддерживает. А для FF на сайте вполне могла быть инструкция как конвеер включить. А Хром был не более 3% и, можно считать, не существовал.
                      • +1
                        В том то и дело, что IE не поддерживает, а в 2009 его еще более-менее широко использовали. Мне версия с TCP-ответом сразу после подключения кажется наиболее реальной, хоть и могу ошибаться.
                        • 0
                          Трудно сказать, на редкость туманная статья (я об оригинале).
  • 0
    Что-то я не понимаю. Он шлет ответ на неотправленный запрос? До того как получил ack?
    А как же seq/ack последовательности?
    Или речь только о трансляции? Когда манипуляция происходит только внутри одного запроса? Там впринципе сиквенсы можно и предсказать. Тогда уж это баг не в http а в tcp.
    Непонятная спорная какая-то статья без подробностей.
    • –1
      Почитал оригинал.
      Осмелюсь предположить, что хитрость в том что бы не дожидаться ack-ов во время отправки пакетов одного большого ответа в пределах одного запроса, а слать пакеты без остановки. А работает все только потому, что к моменту приезда к клиенту, последний уже успел отправить подтверждение и поэтому его переваривает как положено. Cобственно все.

      Это даже не tcp — это манипулирование на уровне пакетов. Подойдет только для вещания или передачи действительно очень больших объемов по сети. Ну и требует работы на низком уровне. Для китайских камер самое оно, а вот для серьезных решений не уверен, что подойдет.

      Автору следует бояться роутеров, которые проверяют консистентность трафика, а не обновлений браузера.
      A spdy асинхронен совершенно по другому приниципу.
      • 0
        Лично мне всё ещё кажется, что он использует HTTP pipelining, но не понимает как это работает. Косвенное подтверждение этому — его слова, что это поведение узаконено в SPDY.
        • 0
          Автор четко пишет:
          set the TCP buffer size to roughly the size of a frame.
          установить размер TCP-буфера равным размеру кадра.

          Не иначе как, для отправки по одному кадру в пакете не дожидаясь на ack.
          Про асинхронные запросы тут и речи нет.
          • 0
            Хотелось бы больше подробностей, конечно. Автор может и не помнить подробности, пять лет прошло всё-таки, а мог не сам это придумать/программировать. Сложно мне сказать. Иначем мне неясно почему он говорит:
            HTTP may be designed as a synchronous protocol but it is not implemented as a synchronous protocol!
            • +1
              Да все понятно. Автор и переводчик сливаясь в экстазе явно путаются в терминологии, сохраняя при этом умный вид и переступая через абстракции наводят тень на плетень, cшибая по дороге плюсики с лайками.
  • 0
    Сама по себе новость довольно интересная…
    Только вот нет этой самой новости, где хотя бы общее описание реализации? Хотя бы принцип?
    Что это?
    Я полагаю, автор написал свой сервер, который не дожидаясь запроса строит и отправляет ожидаемые от него ответы.

    То есть:
    1. Клиент устанавливает соединение
    2. Сервер начинает слать ответ
    3. Клиент отправляет запрос, ждет ответа
    4. Приходят первые байты ответа, браузер не заметил подвоха

    То есть выигрыш достигается за счет отсутствия задержки между 3 и 4…
    Но тут нас подстерегает опасность, что 4 начнется раньше завершения 3(при очень быстрой сети), что в принципе можно частично регулировать дополнительной задержкой на стороне сервера…

    У кого нибудь есть другие предположения, о чем эта статья?
    • 0
      Всё именно так, а статья о том, что даже на очень быстрой LAN, где 4 может произойти раньше, чем 3 всё отлично работает.
      • 0
        потому что клиент тупо не читает сокет, пока не закончит с запросом? получается из-за буфера это работает?
        • +1
          Угу. Запрос обычно влазит в TCP буфер на стороне браузера, так что «отослав» его браузер переходит к разбору того, что пришло в ответ. А то, что то, что пришло в ответ, в ядре появилось ещё до того, как браузер послал запрос — его не волнует.

          Как в оригинале написано: им бы пришлось написать кучу кода, чтобы заставить браузер работать строго по стандарту, а выигрыша от этого не было бы никому и никакого.
  • 0
    Ох… Боян всем боянам бойан! Гугол ужо сто лет такой хак использует, подробности — blog.benstrong.com/2010/11/google-and-microsoft-cheat-on-slow.html?m=1

    З.Ы. почему в мобильной версии хабра нельзя оставлять комментарии и не видно их сразу?
    • 0
      Гугл всё-таки дожидается запроса, а тут речь идёт о том, чтобы сразу после TCP-handshake'а выслать ответ не дожидаясь запроса! Грубо говоря если у нас есть web-камера и на одном порту (или IP) у нас UI, а на другом — только текущая картинка, то запрос туда может быть только на эту картинку и больше ни на что — вот её и будем отдавать как только сможем, а запрос… запрос просто проигнорируем.

  • НЛО прилетело и опубликовало эту надпись здесь

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