You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Current status. gotd implements the TCP codecs (abridged/intermediate/full), obfuscated2, WebSocket and MTProxy transports, but not the plain HTTP(S) transport (POST /api) described in the MTProto transports doc. The mt.HTTPWaitRequest type is already generated from the schema but is never emitted anywhere in the codebase.
Motivation. In some network environments a client can reach a Telegram DC over HTTP POST but cannot hold a raw persistent TCP MTProto socket (HTTP-only egress proxies, restricted residential exits, request/response-only tunnels). An HTTP transport with http_wait long-polling makes gotd usable there, at the cost of some update latency.
Proposed solution (high level).
A new dcs resolver (e.g. dcs.HTTP(...)) returning a transport.Conn backed by an *http.Client:
Send issues POST {scheme}://{ip}:{port}/api with the raw MTProto frame as the request body — framing is done by HTTP Content-Length, no codec tag/header.
the response body (a single encrypted message, possibly a container) is queued and returned by Recv.
Send is non-blocking (the POST/response is handled off the write path) so a 25s long-poll does not stall the connection's write path / key exchange.
Long-polling via http_wait. Because http_wait is an encrypted service message, it must be produced at the mtproto layer, not inside the transport. Proposed hook: after the handshake, mtproto.Conn detects an optional capability interface on the transport and hands it a callback that yields a freshly-encrypted http_wait frame; the transport keeps exactly one long-poll POST outstanding and re-issues it immediately on completion (low update latency). Defaults: max_delay=0, wait_after=0, max_wait=25000.
Open questions for maintainers (I'd like to align before sending a PR):
Preferred shape of the mtproto↔transport hook: the capability-interface + frame-callback above, or a simpler background httpWaitLoop inside mtproto.Conn paced by a ticker (simpler, but higher idle update latency and possible overlap)?
Where should the HTTP transport.Conn live — telegram/dcs (next to the WebSocket client) or transport?
Is an HTTP transport something you'd want upstream at all?
I'm preparing a reference implementation (transport + http_wait + a tgtest end-to-end test) and am happy to open a PR once the approach is agreed.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Description
Current status. gotd implements the TCP codecs (abridged/intermediate/full), obfuscated2, WebSocket and MTProxy transports, but not the plain HTTP(S) transport (
POST /api) described in the MTProto transports doc. Themt.HTTPWaitRequesttype is already generated from the schema but is never emitted anywhere in the codebase.Motivation. In some network environments a client can reach a Telegram DC over HTTP
POSTbut cannot hold a raw persistent TCP MTProto socket (HTTP-only egress proxies, restricted residential exits, request/response-only tunnels). An HTTP transport withhttp_waitlong-polling makes gotd usable there, at the cost of some update latency.Proposed solution (high level).
A new
dcsresolver (e.g.dcs.HTTP(...)) returning atransport.Connbacked by an*http.Client:SendissuesPOST {scheme}://{ip}:{port}/apiwith the raw MTProto frame as the request body — framing is done by HTTPContent-Length, no codec tag/header.Recv.Sendis non-blocking (the POST/response is handled off the write path) so a 25s long-poll does not stall the connection's write path / key exchange.Long-polling via
http_wait. Becausehttp_waitis an encrypted service message, it must be produced at themtprotolayer, not inside the transport. Proposed hook: after the handshake,mtproto.Conndetects an optional capability interface on the transport and hands it a callback that yields a freshly-encryptedhttp_waitframe; the transport keeps exactly one long-pollPOSToutstanding and re-issues it immediately on completion (low update latency). Defaults:max_delay=0, wait_after=0, max_wait=25000.Open questions for maintainers (I'd like to align before sending a PR):
mtproto↔transport hook: the capability-interface + frame-callback above, or a simpler backgroundhttpWaitLoopinsidemtproto.Connpaced by a ticker (simpler, but higher idle update latency and possible overlap)?transport.Connlive —telegram/dcs(next to the WebSocket client) ortransport?I'm preparing a reference implementation (transport +
http_wait+ atgtestend-to-end test) and am happy to open a PR once the approach is agreed.References
http_waitfields (max_delay/wait_after/max_wait, ms): https://core.telegram.org/mtproto/service_messagesmt.HTTPWaitRequest— generated (mt/tl_http_wait_gen.go), currently unused.All reactions