Skip to content

Commit

Permalink
fixed bug in handling chunked responses
Browse files Browse the repository at this point in the history
  • Loading branch information
massivefermion committed Nov 17, 2023
1 parent 9202f2d commit f7354a0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = "dove"
version = "0.8.0"
version = "0.9.0"

description = "Fast and flexible http client for Gleam"
gleam = ">= 0.32.0"
Expand Down
1 change: 1 addition & 0 deletions src/dove/error.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub type Error {
TCPError(mug.Error)
UnableToSendRequest
HttpsNotSupportedYet
InvalidChunkedResponse
InvalidHeaderName(#(String, String))
InvalidHeaderValue(#(String, String))
}
39 changes: 22 additions & 17 deletions src/dove/response.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ fn consume_by_length(
0 -> Error(error.MoreNeeded)
_ -> {
let <<ch:8, rest:bits>> = data
let storage = bit_array.append(storage, <<ch>>)
case bit_array.byte_size(storage) == length {
True -> Ok(#(bit_array.append(storage, <<ch>>), rest))
False ->
consume_by_length(rest, length, bit_array.append(storage, <<ch>>))
True -> Ok(#(storage, rest))
False -> consume_by_length(rest, length, storage)
}
}
}
Expand All @@ -130,23 +130,28 @@ fn gather_chunks(data: BitArray, storage: BitArray) {
case bit_array.byte_size(data) {
0 -> Error(error.MoreNeeded)
_ -> {
case consume_till_crlf(data, <<>>, False) {
Ok(#(length, rest)) ->
case length {
<<"0":utf8>> -> {
let <<"\r\n":utf8, rest:bits>> = rest
Ok(#(storage, rest))
}
_ -> {
case consume_till_crlf(rest, <<>>, False) {
Ok(#(chunk, rest)) ->
gather_chunks(rest, bit_array.append(storage, chunk))
use #(length, rest) <- result.then(consume_till_crlf(data, <<>>, False))

use length <- result.then(
bit_array.to_string(length)
|> result.replace_error(error.InvalidChunkedResponse),
)

Error(error) -> Error(error)
}
case int.base_parse(length, 16) {
Ok(0) -> {
let <<"\r\n":utf8, rest:bits>> = rest
Ok(#(storage, rest))
}
Ok(length) -> {
case consume_by_length(rest, length, <<>>) {
Ok(#(chunk, rest)) -> {
let <<"\r\n":utf8, rest:bits>> = rest
gather_chunks(rest, bit_array.append(storage, chunk))
}
Error(error) -> Error(error)
}
Error(error) -> Error(error)
}
Error(Nil) -> Error(error.InvalidChunkedResponse)
}
}
}
Expand Down

0 comments on commit f7354a0

Please sign in to comment.