@@ -61,6 +61,7 @@ export Message, Request, Response,
61
61
62
62
using URIs, CodecZlib
63
63
using .. Pairs, .. IOExtras, .. Parsers, .. Strings, .. Forms, .. Conditions
64
+ using .. ConnectionPool
64
65
65
66
const nobody = UInt8[]
66
67
const unknown_length = typemax (Int)
@@ -77,7 +78,7 @@ abstract type Message end
77
78
78
79
Represents an HTTP response message with fields:
79
80
80
- - `version::VersionNumber `
81
+ - `version::HTTPVersion `
81
82
[RFC7230 2.6](https://tools.ietf.org/html/rfc7230#section-2.6)
82
83
83
84
- `status::Int16`
@@ -94,14 +95,14 @@ Represents an HTTP response message with fields:
94
95
95
96
"""
96
97
mutable struct Response <: Message
97
- version:: VersionNumber
98
+ version:: HTTPVersion
98
99
status:: Int16
99
100
headers:: Headers
100
101
body:: Any # Usually Vector{UInt8} or IO
101
102
request:: Union{Message, Nothing} # Union{Request, Nothing}
102
103
end
103
104
104
- function Response (status:: Integer , headers, body; version:: VersionNumber = v " 1.1 " , request= nothing )
105
+ function Response (status:: Integer , headers, body; version= HTTPVersion ( 1 , 1 ) , request= nothing )
105
106
b = isbytes (body) ? bytes (body) : something (body, nobody)
106
107
@assert (request isa Request || request === nothing )
107
108
return Response (version, status, mkheaders (headers), b, request)
@@ -119,7 +120,7 @@ Response(body) = Response(200; body=body)
119
120
Base. convert (:: Type{Response} , s:: AbstractString ) = Response (s)
120
121
121
122
function reset! (r:: Response )
122
- r. version = v " 1.1 "
123
+ r. version = HTTPVersion ( 1 , 1 )
123
124
r. status = 0
124
125
if ! isempty (r. headers)
125
126
empty! (r. headers)
@@ -136,8 +137,10 @@ body(r::Response) = getfield(r, :body)
136
137
const Context = Dict{Symbol, Any}
137
138
138
139
"""
139
- HTTP.Request(method, target, headers=[], body=nobody;
140
- version=v"1.1", url::URI=URI(), responsebody=nothing, parent=nothing, context=HTTP.Context())
140
+ HTTP.Request(
141
+ method, target, headers=[], body=nobody;
142
+ version=v"1.1", url::URI=URI(), responsebody=nothing, parent=nothing, context=HTTP.Context()
143
+ )
141
144
142
145
Represents a HTTP Request Message with fields:
143
146
@@ -147,7 +150,7 @@ Represents a HTTP Request Message with fields:
147
150
- `target::String`
148
151
[RFC7230 5.3](https://tools.ietf.org/html/rfc7230#section-5.3)
149
152
150
- - `version::VersionNumber `
153
+ - `version::HTTPVersion `
151
154
[RFC7230 2.6](https://tools.ietf.org/html/rfc7230#section-2.6)
152
155
153
156
- `headers::HTTP.Headers`
@@ -170,7 +173,7 @@ Represents a HTTP Request Message with fields:
170
173
mutable struct Request <: Message
171
174
method:: String
172
175
target:: String
173
- version:: VersionNumber
176
+ version:: HTTPVersion
174
177
headers:: Headers
175
178
body:: Any # Usually Vector{UInt8} or some kind of IO
176
179
response:: Response
181
184
182
185
Request () = Request (" " , " " )
183
186
184
- function Request (method:: String , target, headers= [], body= nobody;
185
- version= v " 1.1" , url:: URI = URI (), responsebody= nothing , parent= nothing , context= Context ())
187
+ function Request (
188
+ method:: String , target, headers= [], body= nobody;
189
+ version= HTTPVersion (1 , 1 ), url:: URI = URI (), responsebody= nothing , parent= nothing , context= Context ()
190
+ )
186
191
b = isbytes (body) ? bytes (body) : body
187
192
r = Request (method, target == " " ? " /" : target, version,
188
193
mkheaders (headers), b, Response (0 ; body= responsebody),
@@ -463,26 +468,19 @@ function decode(m::Message, encoding::String="gzip")::Vector{UInt8}
463
468
end
464
469
465
470
# Writing HTTP Messages to IO streams
466
- """
467
- HTTP.httpversion(::Message)
468
-
469
- e.g. `"HTTP/1.1"`
470
- """
471
- httpversion (m:: Message ) = " HTTP/$(m. version. major) .$(m. version. minor) "
471
+ Base. write (io:: IO , v:: HTTPVersion ) = write (io, " HTTP/" , string (v. major), " ." , string (v. minor))
472
472
473
473
"""
474
474
writestartline(::IO, ::Message)
475
475
476
476
e.g. `"GET /path HTTP/1.1\\ r\\ n"` or `"HTTP/1.1 200 OK\\ r\\ n"`
477
477
"""
478
478
function writestartline (io:: IO , r:: Request )
479
- write (io, " $(r. method) $(r. target) $(httpversion (r)) \r\n " )
480
- return
479
+ return write (io, r. method, " " , r. target, " " , r. version, " \r\n " )
481
480
end
482
481
483
482
function writestartline (io:: IO , r:: Response )
484
- write (io, " $(httpversion (r)) $(r. status) $(statustext (r. status)) \r\n " )
485
- return
483
+ return write (io, r. version, " " , string (r. status), " " , statustext (r. status), " \r\n " )
486
484
end
487
485
488
486
"""
@@ -491,14 +489,18 @@ end
491
489
Write `Message` start line and
492
490
a line for each "name: value" pair and a trailing blank line.
493
491
"""
494
- function writeheaders (io:: IO , m:: Message )
495
- writestartline (io, m)
492
+ writeheaders (io:: IO , m:: Message ) = writeheaders (io, m, IOBuffer ())
493
+ writeheaders (io:: Connection , m:: Message ) = writeheaders (io, m, io. writebuffer)
494
+
495
+ function writeheaders (io:: IO , m:: Message , buf:: IOBuffer )
496
+ writestartline (buf, m)
496
497
for (name, value) in m. headers
497
498
# match curl convention of not writing empty headers
498
- ! isempty (value) && write (io, " $ name: $ value\r\n " )
499
+ ! isempty (value) && write (buf, name, " : " , value, " \r\n " )
499
500
end
500
- write (io, " \r\n " )
501
- return
501
+ write (buf, " \r\n " )
502
+ nwritten = write (io, take! (buf))
503
+ return nwritten
502
504
end
503
505
504
506
"""
@@ -507,15 +509,15 @@ end
507
509
Write start line, headers and body of HTTP Message.
508
510
"""
509
511
function Base. write (io:: IO , m:: Message )
510
- writeheaders (io, m)
511
- write (io, m. body)
512
- return
512
+ nwritten = writeheaders (io, m)
513
+ nwritten += write (io, m. body)
514
+ return nwritten
513
515
end
514
516
515
517
function Base. String (m:: Message )
516
518
io = IOBuffer ()
517
519
write (io, m)
518
- String (take! (io))
520
+ return String (take! (io))
519
521
end
520
522
521
523
# Reading HTTP Messages from IO streams
589
591
function compactstartline (m:: Message )
590
592
b = IOBuffer ()
591
593
writestartline (b, m)
592
- strip (String (take! (b)))
594
+ return strip (String (take! (b)))
593
595
end
594
596
595
597
# temporary replacement for isvalid(String, s), until the
0 commit comments