Skip to content

Commit 61ea784

Browse files
author
Documenter.jl
committed
build based on b40b58b
1 parent acc6c68 commit 61ea784

9 files changed

Lines changed: 61 additions & 89 deletions

File tree

previews/PR1240/changelog/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

previews/PR1240/client/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
HTTP.request("GET", "http://127.0.0.1:8080/events"; sse_callback = (stream, event) -> begin
1818
@info "event" data=event.data id=event.id event_type=event.event retry_after=event.retry
1919
push!(events, event)
20-
end)</code></pre><p>The callback can be <code>f(event)</code> or <code>f(stream, event)</code>. The two-argument form allows cancelling the request by calling <code>close(stream)</code> (for example, in response to a specific event).</p><p>Each callback receives a <code>SSEEvent</code> with the following fields:</p><ul><li><code>data::String</code>: newline-joined <code>data:</code> payload for the event (with the trailing newline removed).</li><li><code>event::Union{Nothing,String}</code>: the most recent <code>event:</code> field, or <code>nothing</code> when not provided (equivalent to the default <code>&quot;message&quot;</code> type).</li><li><code>id::Union{Nothing,String}</code>: the last <code>id:</code> value observed, automatically persisted between events per the SSE specification.</li><li><code>retry::Union{Nothing,Int}</code>: the last <code>retry:</code> directive in milliseconds, propagated to subsequent events until another <code>retry:</code> value is parsed.</li><li><code>fields::Dict{String,String}</code>: newline-joined string values for every field encountered since the previous event, including custom non-standard fields.</li></ul><p>Because HTTP.jl streams the response directly to the callback, the returned <code>HTTP.Response</code> will always have <code>response.body === HTTP.nobody</code>. The <code>sse_callback</code> keyword cannot be combined with <code>response_stream</code> or a custom <code>iofunction</code>, and parsing errors raise <code>HTTP.SSEError</code>. Compressed streams are supported automatically unless <code>decompress=false</code> is explicitly set.</p><p>For a full end-to-end example, see <a href="https://github.com/JuliaWeb/HTTP.jl/blob/master/docs/examples/server_sent_events.jl"><code>docs/examples/server_sent_events.jl</code></a>.</p><h3 id="Download"><a class="docs-heading-anchor" href="#Download">Download</a><a id="Download-1"></a><a class="docs-heading-anchor-permalink" href="#Download" title="Permalink"></a></h3><p>A <a href="@ref"><code>download</code></a> function is provided for similar functionality to <code>Downloads.download</code>.</p><h2 id="Client-side-Middleware-(Layers)"><a class="docs-heading-anchor" href="#Client-side-Middleware-(Layers)">Client-side Middleware (Layers)</a><a id="Client-side-Middleware-(Layers)-1"></a><a class="docs-heading-anchor-permalink" href="#Client-side-Middleware-(Layers)" title="Permalink"></a></h2><p>An <code>HTTP.Layer</code> is an abstract type to represent a client-side middleware. A layer is any function of the form <code>f(::Handler) -&gt; Handler</code>, where <a href="@ref"><code>Handler</code></a> is a function of the form <code>f(::Request) -&gt; Response</code>. Note that this <code>Handler</code> definition is the same from the server-side documentation. It may also be apparent that a <code>Layer</code> is the same as the <a href="@ref"><code>Middleware</code></a> interface from server-side, which is true, but we define <code>Layer</code> to clarify the client-side distinction and its unique usage.</p><p>Creating custom layers can be a convenient way to &quot;enhance&quot; the <code>HTTP.request</code> process with custom functionality. It might be a layer that computes a special authorization header, or modifies the body in some way, or treats the response specially. Oftentimes, layers are application or domain-specific, where certain domain knowledge can be used to improve or simplify the request process. Layers can also be used to enforce the usage of certain keyword arguments if desired.</p><p>Custom layers can be deployed in one of two ways:</p><ul><li><a href="../reference/#HTTP.@client"><code>HTTP.@client</code></a>: Create a custom &quot;client&quot; with shorthand verb definitions, but which include custom layers; only these new verb methods will use the custom layers.</li><li><a href="../reference/#HTTP.pushlayer!"><code>HTTP.pushlayer!</code></a>/<a href="../reference/#HTTP.poplayer!"><code>HTTP.poplayer!</code></a>: Allows globally adding and removing layers from the default HTTP.jl layer stack; <em>all</em> http requests will then use the custom layers</li></ul><h3 id="Quick-Examples"><a class="docs-heading-anchor" href="#Quick-Examples">Quick Examples</a><a id="Quick-Examples-1"></a><a class="docs-heading-anchor-permalink" href="#Quick-Examples" title="Permalink"></a></h3><pre><code class="language-julia hljs">module Auth
20+
end)</code></pre><p>The callback can be <code>f(event)</code> or <code>f(stream, event)</code>. The two-argument form allows cancelling the request by calling <code>close(stream)</code> (for example, in response to a specific event).</p><p>Each callback receives a <code>SSEEvent</code> with the following fields:</p><ul><li><code>data::String</code>: newline-joined <code>data:</code> payload for the event (with the trailing newline removed).</li><li><code>event::Union{Nothing,String}</code>: the most recent <code>event:</code> field, or <code>nothing</code> when not provided (equivalent to the default <code>&quot;message&quot;</code> type).</li><li><code>id::Union{Nothing,String}</code>: the last <code>id:</code> value observed, automatically persisted between events per the SSE specification.</li><li><code>retry::Union{Nothing,Int}</code>: the last <code>retry:</code> directive in milliseconds, propagated to subsequent events until another <code>retry:</code> value is parsed.</li><li><code>fields::Dict{String,String}</code>: newline-joined string values for every field encountered since the previous event, including custom non-standard fields.</li></ul><p>Because HTTP.jl streams the response directly to the callback, the returned <code>HTTP.Response</code> will always have <code>response.body === HTTP.nobody</code>. The <code>sse_callback</code> keyword cannot be combined with <code>response_stream</code> or a custom <code>iofunction</code>. The callback is only invoked for non-error responses; error responses are read like a normal request, and <code>status_exception</code> behavior applies. Parsing or callback errors surface as regular request errors (<code>HTTP.RequestError</code>) with the underlying exception in <code>err.error</code>. Compressed streams are supported automatically unless <code>decompress=false</code> is explicitly set.</p><p>For a full end-to-end example, see <a href="https://github.com/JuliaWeb/HTTP.jl/blob/master/docs/examples/server_sent_events.jl"><code>docs/examples/server_sent_events.jl</code></a>.</p><h3 id="Download"><a class="docs-heading-anchor" href="#Download">Download</a><a id="Download-1"></a><a class="docs-heading-anchor-permalink" href="#Download" title="Permalink"></a></h3><p>A <a href="@ref"><code>download</code></a> function is provided for similar functionality to <code>Downloads.download</code>.</p><h2 id="Client-side-Middleware-(Layers)"><a class="docs-heading-anchor" href="#Client-side-Middleware-(Layers)">Client-side Middleware (Layers)</a><a id="Client-side-Middleware-(Layers)-1"></a><a class="docs-heading-anchor-permalink" href="#Client-side-Middleware-(Layers)" title="Permalink"></a></h2><p>An <code>HTTP.Layer</code> is an abstract type to represent a client-side middleware. A layer is any function of the form <code>f(::Handler) -&gt; Handler</code>, where <a href="@ref"><code>Handler</code></a> is a function of the form <code>f(::Request) -&gt; Response</code>. Note that this <code>Handler</code> definition is the same from the server-side documentation. It may also be apparent that a <code>Layer</code> is the same as the <a href="@ref"><code>Middleware</code></a> interface from server-side, which is true, but we define <code>Layer</code> to clarify the client-side distinction and its unique usage.</p><p>Creating custom layers can be a convenient way to &quot;enhance&quot; the <code>HTTP.request</code> process with custom functionality. It might be a layer that computes a special authorization header, or modifies the body in some way, or treats the response specially. Oftentimes, layers are application or domain-specific, where certain domain knowledge can be used to improve or simplify the request process. Layers can also be used to enforce the usage of certain keyword arguments if desired.</p><p>Custom layers can be deployed in one of two ways:</p><ul><li><a href="../reference/#HTTP.@client"><code>HTTP.@client</code></a>: Create a custom &quot;client&quot; with shorthand verb definitions, but which include custom layers; only these new verb methods will use the custom layers.</li><li><a href="../reference/#HTTP.pushlayer!"><code>HTTP.pushlayer!</code></a>/<a href="../reference/#HTTP.poplayer!"><code>HTTP.poplayer!</code></a>: Allows globally adding and removing layers from the default HTTP.jl layer stack; <em>all</em> http requests will then use the custom layers</li></ul><h3 id="Quick-Examples"><a class="docs-heading-anchor" href="#Quick-Examples">Quick Examples</a><a id="Quick-Examples-1"></a><a class="docs-heading-anchor-permalink" href="#Quick-Examples" title="Permalink"></a></h3><pre><code class="language-julia hljs">module Auth
2121

2222
using HTTP
2323

@@ -49,4 +49,4 @@
4949
HTTP.pushlayer!(Auth.auth_layer)
5050

5151
# Now can use normal HTTP.jl methods and auth_layer will be included
52-
HTTP.get(url; authcreds=creds)</code></pre><p>For more ideas or examples on how client-side layers work, it can be useful to see how <code>HTTP.request</code> is built on layers internally, in the <a href="https://github.com/JuliaWeb/HTTP.jl/tree/master/src/clientlayers"><code>/src/clientlayers</code></a> source code directory.</p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../">« Home</a><a class="docs-footer-nextpage" href="../server/">Server »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 0.27.25 on <span class="colophon-date" title="Thursday 18 December 2025 06:04">Thursday 18 December 2025</span>. Using Julia version 1.12.3.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
52+
HTTP.get(url; authcreds=creds)</code></pre><p>For more ideas or examples on how client-side layers work, it can be useful to see how <code>HTTP.request</code> is built on layers internally, in the <a href="https://github.com/JuliaWeb/HTTP.jl/tree/master/src/clientlayers"><code>/src/clientlayers</code></a> source code directory.</p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../">« Home</a><a class="docs-footer-nextpage" href="../server/">Server »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 0.27.25 on <span class="colophon-date" title="Saturday 20 December 2025 14:25">Saturday 20 December 2025</span>. Using Julia version 1.12.3.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>

previews/PR1240/examples/index.html

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -267,23 +267,16 @@
267267
HTTP.setheader(response, &quot;Access-Control-Allow-Origin&quot; =&gt; &quot;*&quot;)
268268

269269
# Create SSE stream - automatically sets Content-Type and Cache-Control
270-
stream = HTTP.sse_stream(response)
271-
272-
# Spawn a task to write events asynchronously
273-
Threads.@spawn begin
274-
try
275-
for i in 1:10
276-
# Write a ping event with timestamp
277-
write(stream, HTTP.SSEEvent(string(round(Int, time())); event=&quot;ping&quot;))
278-
279-
# Occasionally write a data event
280-
if rand(Bool)
281-
write(stream, HTTP.SSEEvent(string(rand())))
282-
end
283-
sleep(1)
270+
HTTP.sse_stream(response) do stream
271+
for i in 1:10
272+
# Write a ping event with timestamp
273+
write(stream, HTTP.SSEEvent(string(round(Int, time())); event=&quot;ping&quot;))
274+
275+
# Occasionally write a data event
276+
if rand(Bool)
277+
write(stream, HTTP.SSEEvent(string(rand())))
284278
end
285-
finally
286-
close(stream)
279+
sleep(1)
287280
end
288281
end
289282

@@ -317,19 +310,13 @@
317310

318311
response = HTTP.Response(200)
319312
HTTP.setheader(response, &quot;Access-Control-Allow-Origin&quot; =&gt; &quot;*&quot;)
320-
stream = HTTP.sse_stream(response)
321-
322-
Threads.@spawn begin
323-
try
324-
while true
325-
write(stream, HTTP.SSEEvent(string(round(Int, time())); event=&quot;ping&quot;))
326-
if rand(Bool)
327-
write(stream, HTTP.SSEEvent(string(rand())))
328-
end
329-
sleep(1)
313+
HTTP.sse_stream(response) do stream
314+
while true
315+
write(stream, HTTP.SSEEvent(string(round(Int, time())); event=&quot;ping&quot;))
316+
if rand(Bool)
317+
write(stream, HTTP.SSEEvent(string(rand())))
330318
end
331-
finally
332-
close(stream)
319+
sleep(1)
333320
end
334321
end
335322

@@ -531,4 +518,4 @@
531518

532519
close(server)
533520

534-
</code></pre></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../reference/">« API Reference</a><a class="docs-footer-nextpage" href="../changelog/">HTTP.jl Changelog »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 0.27.25 on <span class="colophon-date" title="Thursday 18 December 2025 06:04">Thursday 18 December 2025</span>. Using Julia version 1.12.3.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
521+
</code></pre></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../reference/">« API Reference</a><a class="docs-footer-nextpage" href="../changelog/">HTTP.jl Changelog »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 0.27.25 on <span class="colophon-date" title="Saturday 20 December 2025 14:25">Saturday 20 December 2025</span>. Using Julia version 1.12.3.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>

0 commit comments

Comments
 (0)