Skip to content

Make m_iobuf size configurable — 2048 default silently truncates bulk HTTPS downloads (BR_ERR_TOO_LARGE) #109

Description

@Upendra237

Summary

The hardcoded m_iobuf[2048] in src/SSLClient.h (line ~469) is too small to hold a full-size (16 KB) TLS record, so any bulk HTTPS download aborts partway through with BR_ERR_TOO_LARGE. Small requests (e.g. a short POST) work fine, which makes the failure look intermittent and confusing. Changing the buffer to BR_SSL_BUFSIZE_MONO fixes it completely, but requires editing library source. This is a request to make the buffer size configurable (constructor or template arg) instead of a source edit.

Environment

  • Library: SSLClient, latest master
  • MCU: ESP32 (Arduino-ESP32 core)
  • Transport: EthernetClient from EthernetENC (ENC28J60)
  • Server: standard HTTPS (Apache/nginx), file ~1 MB, Content-Length present, HTTP/1.1 200 OK

What works vs what fails

  • ✅ TLS handshake, trust-anchor cert verification, and small request/response (short POST) — all fine.
  • ❌ Streaming a ~1 MB body over HTTPS aborts at ~43,000 bytes every time.

Error output

[DL] status: HTTP/1.1 200 OK
[DL] size: 1074.36 KB
[DL] 40.5 / 1074.4 KB  (4%)
(SSLClient)(SSL_ERROR)(available): Cannot operate on a closed SSL connection.
(SSLClient)(SSL_ERROR)(m_print_br_error): Incoming record is too large to be processed, or buffer is too small for the handshake message to send.

Root cause

src/SSLClient.h (~line 469):

unsigned char m_iobuf[2048];

TLS records can be up to 16 KB. The first max-size record after the headers overflows the 2048-byte buffer, so BearSSL returns BR_ERR_TOO_LARGE. It's also below the ~8000-byte minimum the code's own comment recommends.

The duplex-selection logic in src/SSLClient.cpp already keys off this size, so a mono-sized buffer is handled correctly by the engine:

constexpr auto duplex = sizeof m_iobuf <= BR_SSL_BUFSIZE_MONO ? 0 : 1;

Fix that works

Changing the declaration to:

unsigned char m_iobuf[BR_SSL_BUFSIZE_MONO];   // 16709 bytes

makes the download complete fully:

[DL] DONE  1100144 B in 26.56 s = 331.4 kbit/s (40.4 KB/s)
[DL] full file received

RAM cost: ~14 KB extra — negligible on ESP32, but understandably not desirable as a global default for RAM-constrained boards (SAMD, AVR).

Requested change

Rather than forcing users to patch library source, expose the buffer size — e.g. a template parameter or constructor argument, defaulting to the current 2048 to preserve existing behavior — so applications that need bulk downloads can opt into a full-record buffer.

Minimal repro

SSLClient client(base_client, TAs, (size_t)TAs_NUM, RAND_PIN);
// GET a ~1 MB file over :443, stream the body in a read loop → aborts ~43 KB

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions