Skip to content

[Enhancement] UPnP/DLNA Media Renderer Plugin: use HTTP/1.1 and always proxy thru LMS#1615

Open
stsichler wants to merge 1 commit into
LMS-Community:public/9.2from
stsichler:feature/http1.1-dlna-streaming
Open

[Enhancement] UPnP/DLNA Media Renderer Plugin: use HTTP/1.1 and always proxy thru LMS#1615
stsichler wants to merge 1 commit into
LMS-Community:public/9.2from
stsichler:feature/http1.1-dlna-streaming

Conversation

@stsichler

Copy link
Copy Markdown
Contributor

This is a follow-up of my comment to #1121.

Testing inter-operation with pa-dlna revealed that LMS's UPnP/DLNA Media Renderer Plugin needs an update to support HTTP/1.1 with chunked transfer encoding to be compatible to up-to-date DLNA Streaming Servers like pa-dlna.
In order to limit the changes required to LMS's DLNA plugin itself and not requiring any changes to Squeezebox Device Firmwares, this implies to also disable direct streaming for DLNA streams in general, meaning always routing the data through LMS and do the translation from HTTP/1.1 chunked transfers to raw HTTP/1.0 there.
Currently, direct streaming is only used when streaming to a single Squeezebox (not a synchronized group).

This PR addresses this.

Note: this PR is generated with the help of AI, since I'm not capable of Perl and I know too little about LMS' internal structures, so please carefully review the code.

In my local tests, this PR seems to work correctly.

I have tested: pa-dlna as server, a single Squeezebox as renderer, a synchronized group of Squeezeboxes as renderer.

…e proxy

DLNA requires the source connection to originate from the same IP
address that was published for the player via UPnP. Force the UPnP/DLNA
MediaRenderer protocol handler to always use the server-side proxy path
(never a direct player-to-source connection: canDirectStream => 0), and
to always use the persistent/enhanced proxy mode (canEnhanceHTTP => 1).

The proxy's primary connection to the source is opened and its request
built by Slim::Formats::RemoteStream / Slim::Player::Protocols::HTTP,
hardcoded to HTTP/1.0 with no understanding of chunked Transfer-Encoding.
Since canDirectStream is forced off above, Slim::Player::Protocols::HTTP's
requestString()/_sysread() are, for this handler, only ever exercised by
the server's own outgoing connection and never by player firmware, so
they can safely be overridden per-plugin:

- requestString() rewrites the request line's protocol token to HTTP/1.1,
  leaving every other header untouched.
- response() detects a "Transfer-Encoding: chunked" response header and
  arms a small dechunking state machine.
- _sysread() transparently strips the chunk framing from the primary
  connection's raw byte stream before it reaches the audio decoder, so
  DLNA sources that only offer chunked responses (no Content-Length)
  can be streamed correctly.

The retry/reconnect path (readPersistentChunk's persistent session, via
Slim::Networking::Async::HTTP) already understood HTTP/1.1 and chunked
decoding; it is also bumped to HTTP/1.1 for consistency.

The player-firmware-facing direct-stream request builder in
Slim::Player::Protocols::HTTP is untouched and still defaults to
HTTP/1.0, so no firmware changes are required.

*note: this commit and message is created with the help of AI*

Signed-off-by: Stefan Sichler <stsichler@web.de>
@stsichler
stsichler force-pushed the feature/http1.1-dlna-streaming branch from f74c2d2 to f49a07d Compare July 19, 2026 09:19
}

# use HTTP/1.1 with chunked transfer-encoding support for the proxied connection
$request_object->protocol('HTTP/1.1');

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I'm not sure about possible side-effects here. What needs to be tested?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant