1. JavaScript / Говнокод #28002

    +1

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    function test() {
        const ws = new WebSocket('ws://127.0.0.1:445');
        ws.addEventListener('close', event =>
            console.log('event.code = ', event.code, '; event.reason = ', event.reason)
        );
        ws.close(3500, 'some reason');
    }
    test();

    Кто угадает значения полей event.code и event.reason — тому два нихуя.
    Кто угадает значение одного из полей — тому одно нихуя.

    Запостил: ISO, 10 Февраля 2022

    Комментарии (85) RSS

    • Web — это просто и понятно.
      Ответить
    • 403 Access Denied? Ибо нехуй куда попало цепляться?
      Ответить
      • Вам достаётся ноль нихуя. Попробуйте ещё раз!

        UPD: в качестве подсказки разрешается почитать https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close.
        Ответить
        • Тогда вернётся что угодно, что сервер отправил в ответ? Ведь в close аргументы для отправки на сервер?
          Ответить
          • > Тогда вернётся что угодно, что сервер отправил в ответ?
            Нет.

            > Ведь в close аргументы для отправки на сервер?
            Нет.
            Ответить
            • 1000 Normal closure?
              Ответить
            • >> Ведь в close аргументы для отправки на сервер?
              > Нет.

              А для чего они тогда, если не для отправки Close Frame серваку?
              Ответить
              • Parameters
                code Optional
                A numeric value indicating the status code explaining why the connection is being closed.
                If this parameter is not specified, a default value of 1005 is assumed. See
                the list of status codes of CloseEvent for permitted values.
                
                reason Optional
                A human-readable string explaining why the connection is closing. This string
                must be no longer than 123 bytes of UTF-8 text (not characters).
                Ответить
                • > explaining why the connection is being closed

                  Explaining to whom? Не самому себе же?
                  Ответить
                  • Действительно, под вечер я уже совокупляюсь в глаза. Объясняет, конечно, серверу, однаку сути загадки Жака Фреско это не меняет (см. подсказку 1).
                    Ответить
                • >123 bytes of UTF-8 text
                  локализовать удобно

                  блядь, что за проблемы как в PHP в 1999м году?
                  Ответить
                  • > локализовать

                    Нинужно.

                    This data is not necessarily human readable but may be useful for debugging or passing information relevant to the script that opened the connection. As the data is not guaranteed to be human readable, clients MUST NOT show it to end users.
                    Ответить
                    • Ну ладно, а зачем тогда УТФ? А вдруг там путь типа
                      c:\users\Петаков Иван Петрович\Мои сайты на PHP\

                      ?


                      Кстати, за локализацию ошибок сотрудники Microsoft и авторы PostgreSQL будут гореть в аду миллард лет.
                      Ответить
                    • > A human-readable string
                      > This data is not necessarily human readable
                      Ответить
                      • RFC сильнее, чем дока к браузерной поебени, я думаю. Да и считать что она нечитаемая будет безопаснее.
                        Ответить
                        • Это просто показывает насколько наплевательски относятся к стандартам в вебе, насколько анскильные смузихлёбы его делают.
                          Ответить
    • ну блядь, ты прицеплся к порту SMB, там конечно же хуй лежит.

      Вангую
      https://github.com/Luka967/websocket-close-codes
      CLOSED_NO_STATUS або Unsupported payload ли CLOSE_PROTOCOL_ERROR
      Ответить
      • Ладно, ладно, это было отвлечение: вместо SMB поднят валидный WebSocket-сервер, каждые десять секунд просто отправляющий пинги.
        Ответить
    • Подсказка: функции test1() и test2() выведут разные сообщения.

      function test1() {
          const ws = new WebSocket('ws://ordinary-websocket-server');
          ws.addEventListener('close', event =>
              console.log('event.code = ', event.code, '; event.reason = ', event.reason)
          );
          ws.close(3500, 'some reason');
      }
      
      function test2() {
          const ws = new WebSocket('ws://ordinary-websocket-server');
          ws.addEventListener('close', event =>
              console.log('event.code = ', event.code, '; event.reason = ', event.reason)
          );
          setInterval(() => ws.close(3500, 'some reason'), 1000);
      }
      Ответить
      • Лол, забавно. Сразу обрывает с 1006 Abnormal Closure, даже не начиная хендшейк с серваком.
        Ответить
      • И да, аргументы close() улетают на сервер, а клиент в onclose() получает ответ от сервера. Т.е. никакой связи между ними нет.
        Ответить
        • > Т.е. никакой связи между ними нет.
          На самом деле есть, только эта связь — ID.

          Реальный пример:
          # docker run --name govno -p 8086:8010 --name web-socket-test ksdn117/web-socket-test

          function test2() {
              const ws = new WebSocket('ws://localhost:8086/');
              ws.addEventListener('close', event =>
                  console.log('event.code = ', event.code, '; event.reason = ', event.reason)
              );
              setInterval(() => ws.close(3500, 'some reason'), 1000);
          }
          test2();  // event.code =  3500 ; event.reason =  some reason


          Ничего не подозревающий веб-петух пишет логику для ручного разрыва вебсокетов, в функции для восстановления связи после обрыва проверяет, что обрыв не был ручным… А потом получает вечный цикл, потому что проверка работает только тогда, когда ручной разрыв происходит у уже подключённого сокета. И ведь в 99% случаях всё прекрасно работает, сука!
          Ответить
          • Почему бы при ручном разрыве не поставить какой-нибудь флажок, что больше реконнектиться не надо?

            Или под "ручным" имеется в виду разрыв со стороны сервера, когда сервак явно говорит "уходи и не возвращайся"?
            Ответить
            • Когда в системе происходят определённые события — необходимо разорвать существующий сокет и подключиться заново. В одном из сценариев разрыв сокета инициируется как раз таким определённым событием. Чтобы не допустить вечного цикла — авторы в обработчик закрытия сокета всунули проверку: если сокет разорван в результате определённого события, то переподключаться не надо: обработчик определённого события сам переподключит сокет. И это прекрасно работает ровно до того момента, когда определённое событие происходит в момент, когда вебсокет ещё не подключён. И вот тогда случается пиздец.

              И да, это не я писал, я в этом баг искал.
              Ответить
              • > прекрасно работает

                Ну х.з. как оно там прекрасно работает. Целый раундтрип должен пройти успешно чтобы разрыв зафиксировался. Любая проблема в любой промежуточной точке от отправки до получения -- добро пожаловать в вечный реконнект.

                И самое главное -- а нафиг всё это, если можно просто флаг заюзать?
                Ответить
                • > И самое главное -- а нафиг всё это, если можно просто флаг заюзать?
                  Потому что асинхронщина во все поля. Заебёшься с флагами.
                  Ответить
                  • Ну future/promise вместо флага... Хотя х.з. чем там асинхронщина мешает, если убитый инстанс не реюзать.
                    Ответить
                    • Потому что там параллельно вебсокетам хуева туча обычных запросов на сервер работают, каждый из которых может инициировать переподключения.
                      Ответить
          • > На самом деле есть, только эта связь — ID.

            Деталь реализации конкретного сервака ведь...
            Ответить
    • Пиздец протокол, конечно. Фрагментацию сообщений на ровном месте устроили... поверх TCP сокета. Или это просто аналог chunked, чтобы серваку не надо было весь ответ сразу высирать?
      Ответить
      • мультиплексирование вроде еще
        Ответить
        • Есть пруф, что кто-то юзает для этого фрагментацию на уровне самого вебсокета? А самый главный вопрос -- каким образом, если там во фреймах нету никаких айдишников.

          Т.е. для мультиплексирования всё равно будут какие-то внешние или внутренние хедера. И не было никакого смысла усложнять протокол.
          Ответить
          • расшырение есть
            https://datatracker.ietf.org/doc/html/draft-ietf-hybi-websocket-multiplexing
            Ответить
            • А, таки прихуячили channel id к фреймам если расширение согласовано.
              Ответить
              • Теперь осталось заставить клиента собирать их по частям если они приехали в случайном порядке. Потом научиться перезапрашивать потерянное сообщение. Потом потребовать подтверждения. Потом объединить их в такие окна, чтобы не подтверждать каждое. А там и до коджекш контрола не далеко
                Ответить
      • Ну так правильно устроили. Поток TCP — дерьмо сраное, каждому первому приходиться придумывать свои ёбанные велосипеды, как его бить на сообщения. Content-Type: multipart/form-data; boundary=GKQO----HUIGOVNO, блядь.
        Ответить
        • > как его бить на сообщения

          Дык там ещё и сами сообщения на фреймы побиты. Внутри потока, побитого на TLS фреймы, побитые на TCP фреймы. Интересно, насколько эффективно вся эта срань взаимодействует и не налетает ли она на какие-нибудь лаги в духе знаменитого send-send-receive.
          Ответить
          • у TCP не фреймы только, а секции
            Ответить
          • > TCP фреймы
            Сегменты же. Фреймы канают только на канальном уровне.
            Ответить
          • TLS — это опция, вебсокеты должны уметь работать поверх голого TCP.

            > TCP фреймы
            Дык к ним на уровне ОС доступа нет. Для пользователя (программы) TCP — это чистый поток байт.
            Ответить
            • Ну вот мне и интересно, насколько эффективно эта слоёная хуйня работает.
              Ответить
              • О качестве работы слоеной хуйни можно почитать в любой статье по Quic
                Кууууик
                Ответить
        • А причем mime бондари к TCP? Ты бы хотел поверх стрима TCP гонять сообщения типа как в UDP, но размером больше MTU и с гарантированной доставкой?
          Ответить
          • > Ты бы хотел поверх стрима TCP гонять сообщения типа как в UDP, но размером больше MTU и с гарантированной доставкой?
            Да. Собственно, «WebSocket» так и делает.

            > А причем mime бондари к TCP?
            Потому что mime бондари — это блядский костыль, возникший из-за того, что «HTTP» принципиально не умеет в разделение одного запроса на логические сообщения, а «HTTP» это не умеет в том числе и потому, что TCP — это ёбанный поток байт.
            Ответить
            • MIME возник когда никакой HTTP еще никого не ебал, и возник он для почты.

              Почтовое сообщение мало того, что должно быть семибитным, так еще и должно в этом тексте как-то передать сообщение и аттачи.

              https://datatracker.ietf.org/doc/html/rfc1521

              А уже оттуда он перекочевал в веб
              Ответить
              • > MIME возник когда никакой HTTP еще никого не ебал, и возник он для почты.
                Ладно, ладно, потому что mime бондари — это блядский костыль, возникший в «HTTP» из-за того, что «HTTP» принципиально
                Ответить
                • А в HTTP/2 можно же посылать параллельно 100500 запросов по одному коннекту и асинхронно собирать результат. Значит ли это, что там можно без Multipart Content-Type?
                  Ответить
                  • Нельзя.
                    Я всё ещё не могу без ёбанного мультипарта послать один POST на /crud/kurochka, в котором у меня будут лежать три фотографии курочки.
                    Ответить
                    • Так почему три не послать? Сессию лень делать?
                      Ответить
                      • Потому что это на порядок больше кода -- надо как-то хранить эти куски, надо понимать когда их можно удалить, надо не наделать гонок...

                        А один POST это как одна транзакция.
                        Ответить
                        • Ладно, апочему госта это ебет, если это говно должен разбирать веб фреймворк на заднем конце?

                          Ну то есть руками шукать бондари в куче говна не нужно, если ты не пишеш свой фреймворк
                          Ответить
                          • В джаве вроде руками разбирают... Вроде тут кто-то жаловался, что в спринге нету стандартного обработчика мультипартов.
                            Ответить
                            • вот это не оно?
                              https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/MultipartFile.html
                              Ответить
                              • Память меня подвела. Вот эта история про мультипарты: https://govnokod.ru/14399#comment212821
                                Ответить
                                • "wvxvw" не тот человек, которому нужно верить на слово, да и с 2014 могло кое-что измениться. Надо читать тред, и проверять.

                                  Всё таки "в джаве делают руками" может оказаться слишком сильным утверждением
                                  Ответить
                      • Потому что я хочу атомарно создать курочку с тремя фотками: спереди, сбоку и сверху.

                        Да, я могу послать эти три фотки тремя запросами, только вот:
                        1. На сервере вместо одной простой курочки появляется новая сущность — «незаконченная курочка». Её нельзя отдавать в GET, нужно обновлять через POST (привет, грубое нарушение сёмантики), и хуй знает, что делать, если клиент пошлёт PUT.
                        2. А где мы будем хранить незаконченных курочек — в БД (уродуем таблицы, добавляем флаги/нуллабельность/новые таблицы для незаконченных сущностей...) или в памяти сервера (нужно писать кучу дополнительного говна в репозиториях)?
                        3. А что мы будем делать с незаконченными курочками?
                        4. А как мы будем финализировать курочек?

                        Вместо простой и понятной модели — «один запрос — одна сущность» — у нас появляется море дерьма.
                        Ответить
                        • Ну HTTP не делался для CRUD же. CRUD потом смузихлёбы к нему прикрутили.

                          Если нужен протокол для создания курочек на сервере, то логично придумать ему расширение для посылки массива курочек
                          Ответить
                          • Совершенно верно, HTTP делался для просмотра HTML.

                            > Если нужен протокол для создания курочек на сервере, то логично придумать ему расширение для посылки массива курочек
                            Ну дык вот это мультидерьмо баундри — это оно и есть, расширение для посылки массива курочек.

                            И изначально я плевался на то, что сделанный в «TCP» «поток байт» — это никому не нужное дерьмо. Оно нужно разве что для педерачи аудиовизуальной информации, и то не нужно, потому что все вменяемые видеосерверы поток бьют на куски нужной длины. В реальности же 99.9% времени по сети гоняются сообщения переменной длины — HTTP-запросы, уебсокет-фреймы, you name it. И чтобы их передавать по ёбанному потоку байт — каждая макака придумывает свой протокол, один охуительнее другого. И именно поэтому я за «UDP» (был бы, если бы не ограничение на размер датаграм).

                            Только больному, душному, максимально оторванному от реальности деду могла прийти в голову мысль о том, что «поток байт» — это хорошая, годная высокоуровневая абсракция.
                            Ответить
                            • Дед в 70-е годы запилил для вас два вида говна: дейтаграммы (сообщения) и потоки (tcp).

                              Дед не виноват же, что все запутались во фрагментации, хакеры стали ее юзать для ddosа, и фрагментацию отменили, и теперь сообщения ширше MTU не пролазят.


                              А HTTP просто не по назначению юзают же
                              Ответить
                              • 1400 байт хватит всем.
                                Ответить
                                • Ну MTU дед не фиксировал, он зависит от канального уровня (точнее от самого узкого места между узлами).

                                  У проводного ethernet 1500, но если поверх него запустить VPN (некоторые провайдеры любят L2TP запустить) то он станет меньше..

                                  Так-то размер пакета максимальный вроде 64K (ну минус заголовки там всякие) но MTU, увы
                                  Ответить
                            • > И изначально я плевался на то, что сделанный в «TCP» «поток байт» — это никому не нужное дерьмо.

                              Деды просто любили городить уровни, и предполагали, что ты поверх потока байт запилишь т.н. ``framing protocol'', который эти байты разобьёт на логические сообщения неком способом, удобным для твоей бизнес логики. Это упрощает транспортный уровень, т.к. ему не нужно думать про размеры буферов в твоей рукоприкладной питушне. Решение вполне в духе многоуровневой модели.
                              TCP придумали в 80е, когда скорость арпанетов была в килобитах в секунду, и про оверхед такого решения никто не думал, скорее всего.
                              Ответить
                              • Т.е. нужно ещё спасибо сказать дедам, что они максимальный размер дикпика не ограничили 1024 байтами, как было бы, если бы фрейминг был частью протокола, придуманного в 80е, и твои одночлены не приходится разбивать на многочлены.
                                Ответить
                                • Запустите свой протокол поверх UDP, и теките на здоровье, в чем проблема?

                                  Деды так-то дали возможнасць вообще любой протокол поверх IP пулять, просто NAT сильно ограничил выбор протоколов

                                  >разбивать на многочлены.
                                  так-то MSS же, ТЦП это и делает. Толще MTU все равно ничего не пролезет. Знаете, сколько слез было пролито из за MTU blackhole, когда пинги идут, а сайты открываются наполовину?
                                  Ответить
                                  • Диды конечно наваивали гибкоты, но плохие бояре ограничили, чтобы был только срим и грам.
                                    Ответить
                        • > Потому что я хочу атомарно создать курочку с тремя фотками: спереди, сбоку и сверху.

                          Вы призвали летающую голову Fike.
                          Ответить
                          • Да, итке просил передать, что атомарного ничего не бывает, и вообще призрачно всё в нашем мире бушующем.

                            Что не отменяет того факта, что попытка создать курочку атомарно посредством HTTP это попытка закрутить гвоздь стамеской. Но смузихлёбы придумали, а программисты теперь страдают
                            Ответить
                            • Итке үйрөтүүнүн мыкты ыкмалары - Күчүгүңүздү үйрөтүүнүн туура жолун тандоо
                              Ответить
                        • > где мы будем хранить незаконченных курочек

                          S3 и аналоги всё стерпят. У меня почему-то такое ощущение, что всякие вконтакты и фейсбуки навсегда сохраняют загруженную фотку в хранилище даже если её потом передумают постить...
                          Ответить
                          • Ну в общем случае Госту придется делать свое говно стейтфул, а стейтфул всегда сложнее и тяжелее стейтлеса, и я понимаю его желание не связываться со стейтом
                            Ответить
                            • Если у нас есть возможность хранить фотки курочек вечно, то можно и стейтлесс.

                              Юзер заливает фотки по одной, а затем отдельным атомарным запросом постит их урлы и описание.
                              Ответить
                              • Это если данные иммутабельны. А если мутабельны? А если я хочу в одной транзакции заменить курочку на птичку, и подлить туда питушка? Я не могу частично же.
                                не городить же MVCC в хранилке
                                Ответить
                                • Сначала зальёшь новую фотку в хранилище, затем атомарно заменишь урл старой фотки на урл новой. Старая останется валяться на память.
                                  Ответить
                                  • ну то есть про MVCC можно было и без зеленого, да?
                                    Ответить
                      • Потому что $PHP_FORM_DATA[] поддерживает не более двух элементов типа image/cockpic
                        Ответить
                    • /creat/kurochka
                      Ответить
                  • Давай вспомним, зачем multipart притащили в HTTP (а точнее HTML). Чувакам захотелось заливать на сервак файлы. А файлы в urlencode не особо компактно кодируются. Вот они и взяли первое что под руку подвернулось на эту тему.
                    Ответить
              • > как-то передать сообщение и аттачи

                Причём не как-то, а чтобы юзер не охуел! Всё должно быть более-менее читаемо даже на старых клиентах, которые не умеют эти ваши MIME.

                Тащить всё это в HTTP, разумеется, не стоило.
                Ответить
    • websockets.exceptions.ConnectionClosedEr ror: no close frame received or sent

      Подключится не успели?
      Ответить

    Добавить комментарий