@@ -51,7 +51,7 @@ module Messages
5151
5252export Message, Request, Response,
5353 reset!, status, method, headers, uri, body, resource,
54- iserror, isredirect, retryable, ischunked, issafe, isidempotent,
54+ iserror, isredirect, retryablebody, retryable, ischunked, issafe, isidempotent,
5555 header, hasheader, headercontains, setheader, defaultheader!, appendheader,
5656 removeheader, mkheaders, readheaders, headerscomplete,
5757 readchunksize,
@@ -124,9 +124,8 @@ function reset!(r::Response)
124124 if ! isempty (r. headers)
125125 empty! (r. headers)
126126 end
127- if r. body isa Vector{UInt8} && ! isempty (r. body)
128- empty! (r. body)
129- end
127+ delete! (r. request. context, :response_body )
128+ return
130129end
131130
132131status (r:: Response ) = getfield (r, :status )
@@ -224,17 +223,6 @@ https://tools.ietf.org/html/rfc7231#section-4.2.1
224223issafe (r:: Request ) = issafe (r. method)
225224issafe (method) = method in [" GET" , " HEAD" , " OPTIONS" , " TRACE" ]
226225
227- """
228- isidempotent(::Request)
229-
230- https://tools.ietf.org/html/rfc7231#section-4.2.2
231- """
232- isidempotent (r:: Request ) = isidempotent (r. method)
233- isidempotent (method) = issafe (method) || method in [" PUT" , " DELETE" ]
234- retry_non_idempotent (r:: Request ) = get (r. context, :retry_non_idempotent , false )
235- allow_retries (r:: Request ) = get (r. context, :allow_retries , false )
236- nothing_written (r:: Request ) = get (r. context, :nothingwritten , false )
237-
238226"""
239227 iserror(::Response)
240228
@@ -258,6 +246,17 @@ isredirect(status) = status in (301, 302, 303, 307, 308)
258246redirectlimitreached (r:: Request ) = get (r. context, :redirectlimitreached , false )
259247allow_redirects (r:: Request ) = get (r. context, :allow_redirects , false )
260248
249+ """
250+ isidempotent(::Request)
251+
252+ https://tools.ietf.org/html/rfc7231#section-4.2.2
253+ """
254+ isidempotent (r:: Request ) = isidempotent (r. method)
255+ isidempotent (method) = issafe (method) || method in [" PUT" , " DELETE" ]
256+ retry_non_idempotent (r:: Request ) = get (r. context, :retry_non_idempotent , false )
257+ allow_retries (r:: Request ) = get (r. context, :allow_retries , false )
258+ nothing_written (r:: Request ) = get (r. context, :nothingwritten , false )
259+
261260# whether the retry limit has been reached for a given request
262261# set in the RetryRequest layer once the limit is reached
263262retrylimitreached (r:: Request ) = get (r. context, :retrylimitreached , false )
@@ -272,8 +271,15 @@ function retryable end
272271supportsmark (x) = false
273272supportsmark (x:: T ) where {T <: IO } = length (Base. methods (mark, Tuple{T}, parentmodule (T))) > 0 || hasfield (T, :mark )
274273
275- retryable (r:: Request ) = (isbytes (r. body) || r. body isa Union{Dict, NamedTuple} || (r. body isa Vector && all (isbytes, r. body)) ||
276- (supportsmark (r. body) && ismarked (r. body))) &&
274+ # request body is retryable if it was provided as "bytes", a Dict or NamedTuple,
275+ # or a chunked array of "bytes"; OR if it supports mark() and is marked
276+ retryablebody (r:: Request ) = (isbytes (r. body) || r. body isa Union{Dict, NamedTuple} ||
277+ (r. body isa Vector && all (isbytes, r. body)) || (supportsmark (r. body) && ismarked (r. body)))
278+
279+ # request is retryable if the body is retryable, the user is allowing retries at all,
280+ # we haven't reached the retry limit, and either nothing has been written yet or
281+ # the request is idempotent or the user has explicitly allowed non-idempotent retries
282+ retryable (r:: Request ) = retryablebody (r) &&
277283 allow_retries (r) && ! retrylimitreached (r) &&
278284 (nothing_written (r) || isidempotent (r) || retry_non_idempotent (r))
279285retryable (r:: Response ) = retryable (r. status)
0 commit comments