Skip to content

Commit f59d03b

Browse files
committed
test: reuse connection from pool
1 parent 9db9aad commit f59d03b

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

test/pool.jl

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
module TestPool
2+
3+
using HTTP
4+
import ..httpbin
5+
using Sockets
6+
using Test
7+
8+
function pooledconnections(socket_type)
9+
pool = HTTP.Connections.getpool(nothing, socket_type)
10+
conns_per_key = values(pool.keyedvalues)
11+
[c for conns in conns_per_key for c in conns if isopen(c)]
12+
end
13+
14+
@testset "$schema pool" for (schema, socket_type) in [
15+
("http", Sockets.TCPSocket),
16+
("https", HTTP.SOCKET_TYPE_TLS[])]
17+
HTTP.Connections.closeall()
18+
@test length(pooledconnections(socket_type)) == 0
19+
try
20+
function request_ip()
21+
r = HTTP.get("$schema://$httpbin/ip"; retry=false, redirect = false, status_exception=true)
22+
String(r.body)
23+
end
24+
25+
@testset "Sequential request use the same socket" begin
26+
request_ip()
27+
conns = pooledconnections(socket_type)
28+
@test length(conns) == 1
29+
conn1io = conns[1].io
30+
31+
request_ip()
32+
conns = pooledconnections(socket_type)
33+
@test length(conns) == 1
34+
@test conn1io === conns[1].io
35+
end
36+
37+
@testset "Parallell requests however use parallell connections" begin
38+
n_asyncgetters = 3
39+
asyncgetters = [@async request_ip() for _ in 1:n_asyncgetters]
40+
wait.(asyncgetters)
41+
42+
conns = pooledconnections(socket_type)
43+
@test length(conns) == n_asyncgetters
44+
end
45+
finally
46+
HTTP.Connections.closeall()
47+
end
48+
end
49+
50+
function readwrite(src, dst)
51+
n = 0
52+
while isopen(dst) && !eof(src)
53+
buff = readavailable(src)
54+
if isopen(dst)
55+
write(dst, buff)
56+
end
57+
n += length(buff)
58+
end
59+
n
60+
end
61+
62+
@testset "http pool with proxy" begin
63+
downstreamconnections = Base.IdSet{HTTP.Connections.Connection}()
64+
upstreamconnections = Base.IdSet{HTTP.Connections.Connection}()
65+
downstreamcount = 0
66+
upstreamcount = 0
67+
68+
# Simple implementation of an http proxy server
69+
proxy = HTTP.listen!(IPv4(0), 8082; stream = true) do http::HTTP.Stream
70+
push!(downstreamconnections, http.stream)
71+
downstreamcount += 1
72+
73+
HTTP.open(http.message.method, http.message.target, http.message.headers;
74+
decompress = false, version = http.message.version, retry=false,
75+
redirect = false) do targetstream
76+
push!(upstreamconnections, targetstream.stream)
77+
upstreamcount += 1
78+
79+
up = @async readwrite(http, targetstream)
80+
targetresponse = startread(targetstream)
81+
82+
HTTP.setstatus(http, targetresponse.status)
83+
for h in targetresponse.headers
84+
HTTP.setheader(http, h)
85+
end
86+
87+
HTTP.startwrite(http)
88+
readwrite(targetstream, http)
89+
90+
wait(up)
91+
end
92+
end
93+
94+
try
95+
function http_request_ip_through_proxy()
96+
r = HTTP.get("http://$httpbin/ip"; proxy="http://localhost:8082", retry=false, redirect = false, status_exception=true)
97+
String(r.body)
98+
end
99+
100+
# Make the HTTP request
101+
http_request_ip_through_proxy()
102+
@test length(downstreamconnections) == 1
103+
@test length(upstreamconnections) == 1
104+
@test downstreamcount == 1
105+
@test upstreamcount == 1
106+
107+
# Make another request
108+
# This should reuse connections from the pool in both the client and the proxy
109+
http_request_ip_through_proxy()
110+
111+
# Check that additional requests were made, both downstream and upstream
112+
@test downstreamcount == 2
113+
@test upstreamcount == 2
114+
# But the set of unique connections in either direction should remain of size 1
115+
@test length(downstreamconnections) == 1
116+
@test length(upstreamconnections) == 1
117+
finally
118+
HTTP.Connections.closeall()
119+
close(proxy)
120+
wait(proxy)
121+
end
122+
end
123+
124+
end # module

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ isok(r) = r.status == 200
1616
"chunking.jl",
1717
"utils.jl",
1818
"client.jl",
19+
"pool.jl",
1920
# "download.jl",
2021
"multipart.jl",
2122
"parsemultipart.jl",

0 commit comments

Comments
 (0)