BBS:      TELESC.NET.BR
Assunto:  JS http.js: 2nd HTTPS request to same host fails with 'Unable to read
De:       Rob Swindell
Data:     Mon, 25 May 2026 18:36:22 -0700
-----------------------------------------------------------
open https://gitlab.synchro.net/main/sbbs/-/issues/1148

## Summary

Any second HTTPS GET to the **same host** in a single Synchronet JS process fails with `Error: Unable to read status` thrown out of `HTTPRequest.ReadStatus()`.  The first HTTPS request to a given host succeeds; the second fails.  Plain HTTP repeats (no TLS) work fine.  Looks like a TLS-session-cache issue in the cryptlib-backed socket layer, not in `exec/load/http.js` itself.

## Minimal Repro

Run in `jsexec` (Win32 release build, but seen across builds):

```javascript
require('http.js', 'HTTPRequest');
for (var i = 1; i <= 3; i++) {
    var h = new HTTPRequest(undefined, undefined, undefined, 30);
    try {
        h.Get("https://gitlab.synchro.net/api/v4/projects/13");
        writeln("call " + i + ": rc=" + h.response_code + " body.len=" + h.body.length);
    } catch (e) {
        writeln("call " + i + ": ERR: " + e);
    }
}
```

Output:

```
call 1: rc=200 body.len=946
call 2: ERR: Error: Unable to read status
call 3: ERR: Error: Unable to read status
```

The error originates at `HTTPRequest.prototype.ReadStatus` in `exec/load/http.js`:

```javascript
HTTPRequest.prototype.ReadStatus = function() {
    this.status_line = this.sock.recvline(4096, this.recv_timeout);
    if (this.status_line == null)
        throw new Error("Unable to read status");
    // ...
};
```

`this.sock.recvline()` returns null on the 2nd request to the same host, indicating the TLS handshake either fails or the connection drops before any status bytes arrive.

## Things I Tried That Did NOT Fix It

- Using a fresh `HTTPRequest` object per call (not just reusing one)
- Explicitly `http.sock.close()` and `http.sock = undefined` between calls
- Sleeping 2s between calls (`mswait(2000)`)
- Clearing `http.body = undefined` before the 2nd `Get` (in case `SetupGet` was reusing it -- it does NOT reset `this.body`, which is a latent bug but not the cause here)
- Letting the redirect-follow logic run (no redirects involved at this URL)

## Things That DO Work

- A second HTTPS request to a **DIFFERENT host** succeeds (call 1 to gitlab  call 2 to httpbin.org  both work)
- BUT after the intervening different-host call, going BACK to the original host on call 3 fails again
- Plain HTTP repeats to the same host: all calls succeed (no TLS, no problem)

## Hypothesis

The cryptlib `ssl_session` socket attribute (set by `http.js` `SendRequest` at line 129) caches per-host TLS session state.  On a 2nd connection to the same host the cached session is stale / invalid for resumption, and the new TCP+TLS attempt either:

a) Tries to resume a closed session and the handshake fails silently
b) Cryptlib's per-host session cache holds a reference to the freed previous-socket session and corrupts the new connection

Either way `recvline()` returns null instead of a status line.

## Impact

Blocks any JS module that wants to make multiple HTTPS requests in one process, such as:

- `chat_llm.js` retrieval crawlers wanting to use the GitLab REST API (`/api/v4/projects//issues` is paginated -- a real-world script needs 10+ calls to fetch all issues)
- Any future module pulling RSS / web content for grounding / mirroring
- IRC adapters that want to do periodic HTTPS polls

Current workaround in `chat_llm.js` is to read GitLab data from locally captured webhook JSONL files (`data/gitissue.jsonl`, `data/gitpush.jsonl`) instead of the API.  Works on vert (which receives the upstream webhook feed) but isn't portable to other Synchronet installs.

## Environment

- Synchronet 3.22a (Win32, Release build)
- Single-process jsexec invocation
- Affected hosts: gitlab.synchro.net, httpbin.org (any HTTPS host)
- Cryptlib version: whatever ships in this build

 *Authored by Claude (Claude Code), on behalf of @rswindell*
n
---
  mSynchronetn  hgVertrauen n hHome of Synchronet n gh[vert/cvs/bbs].synchro.net

-----------------------------------------------------------
[Voltar]