Skip to content

Failed to paste more than 2035 characters with libwebsockets >= 4.4.0 #1532

Open

Description

@erusc

Describe the bug
With Docker image tsl0922/ttyd:1.7.8, whenever I try to paste more than 2035 characters it just reconnect.

To Reproduce
Steps to reproduce the behavior:

  1. Just paste more than 2035 characters.
  2. See error
[2026/04/24 18:21:38:8866] E: [wsisrv|1|default|(null)|127.0.0.1]: lws_extension_callback_pm_deflate: rx buffer underflow

Expected behavior
It worked fine on 1.7.7.

Screenshots
If applicable, add screenshots to help explain your problem.

Environment:

  • OS: Windows, Linux
  • Browser: Chrome, Firefox

Additional context
It seems to be related to this commit: warmcat/libwebsockets@6a2542d
If I undo the commit or just build with a version (4.3.10 for example) without the commit, I can once again paste very-long text like in 1.7.7.

Activity

  1. changed the title [-]Failed to paste more than 2035 characters with libwebsockets > 4.4.0[/-] [+]Failed to paste more than 2035 characters with libwebsockets >= 4.4.0[/+] on Apr 25, 2026
  2. PvH-SPC commented on May 11, 2026

    @PvH-SPC

    Hi wondering what the plan is for this fix?

  3. erusc commented on May 12, 2026

    @erusc
    Author

    I think I found the fix without hacking libwebsockets.

    diff --git a/src/protocol.c b/src/protocol.c
    index adb7d63..cd5d40d 100644
    --- a/src/protocol.c
    +++ b/src/protocol.c
    @@ -252,6 +252,9 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
     
           lws_get_peer_simple(lws_get_network_wsi(wsi), pss->address, sizeof(pss->address));
           lwsl_notice("WS   %s - %s, clients: %d\n", pss->path, pss->address, server->client_count);
    +#ifndef LWS_WITHOUT_EXTENSIONS
    +      lws_set_extension_option(wsi, "permessage-deflate", "rx_buf_size", "31");
    +#endif
           break;
     
         case LWS_CALLBACK_SERVER_WRITEABLE:
    diff --git a/src/server.c b/src/server.c
    index 183fa3a..13b3e81 100644
    --- a/src/server.c
    +++ b/src/server.c
    @@ -28,7 +28,7 @@ extern int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void
     
     // websocket protocols
     static const struct lws_protocols protocols[] = {{"http-only", callback_http, sizeof(struct pss_http), 0},
    -                                                 {"tty", callback_tty, sizeof(struct pss_tty), 0},
    +                                                 {"tty", callback_tty, sizeof(struct pss_tty), 2147483648},
                                                      {NULL, NULL, 0, 0}};
     
     #ifndef LWS_WITHOUT_EXTENSIONS

    The theoretical limit of rx buffer is 2^31 = 2147483648 (unsigned int, 2 GiB), according to https://github.com/warmcat/libwebsockets/blob/6a2542d/lib/roles/ws/ext/extension-permessage-deflate.c#L53-L66 and https://github.com/warmcat/libwebsockets/blob/6a2542d/lib/roles/ws/ext/extension-permessage-deflate.c#L232-L235.

    lws_set_extension_option only sets the soft cap, the actual limit is bound by protocol->rx_buffer_size or pt_serv_buf_size (when protocol->rx_buffer_size is 0).

    Kind of confusing that extension option rx_buf_size is the exponent of 2, while protocol->rx_buffer_size and pt_serv_buf_size is in bytes.

    The only problem is that I am not sure if it's ok to hardcode the number.

  4. PvH-SPC commented on May 14, 2026

    @PvH-SPC

    Can we get this cut into a release? Not sure what changed but anything is better than the very small paste window we have now.

  5. erusc commented on May 15, 2026

    @erusc
    Author

    For now you can just use 1.7.7 or build with libwebsockets 4.3.10.

    BUILD_TARGET=$(arch) LIBWEBSOCKETS_VERSION=4.3.10 ./scripts/cross-build.sh

    Set BUILD_TARGET if you need a different architecture.

    ttyd/scripts/cross-build.sh

    Lines 201 to 219 in 647d55a

    case ${BUILD_TARGET} in
    i686|x86_64|aarch64|mips|mipsel|mips64|mips64el|powerpc64|powerpc64le|s390x)
    build "${BUILD_TARGET}-linux-musl" "${BUILD_TARGET}"
    ;;
    arm)
    build "${BUILD_TARGET}-linux-musleabi" "${BUILD_TARGET}"
    ;;
    armhf)
    build arm-linux-musleabihf "${BUILD_TARGET}"
    ;;
    armv7l)
    build armv7l-linux-musleabihf "${BUILD_TARGET}"
    ;;
    win32)
    build x86_64-w64-mingw32 "${BUILD_TARGET}"
    ;;
    *)
    echo "unknown cross target: ${BUILD_TARGET}" && exit 1
    esac

    v4.3.10 was tagged 2 months ago, so I assume it's not outdated yet.

    p.s.
    There seem to be another issue about TLS with libwebsockets 4.4 and 4.5, so it might be better to stick with 4.3.x for the time being.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions