Revert "improvements for httpcore (#12228)"
This reverts commit b865c2a54b.
This commit is contained in:
parent
5b43c98897
commit
f7a8fc46c0
4 changed files with 44 additions and 46 deletions
|
|
@ -85,6 +85,7 @@ type
|
||||||
- concurrency/threadpool
|
- concurrency/threadpool
|
||||||
- coro
|
- coro
|
||||||
- endians
|
- endians
|
||||||
|
- httpcore
|
||||||
- parsesql
|
- parsesql
|
||||||
- pathnorm
|
- pathnorm
|
||||||
- reservedmem
|
- reservedmem
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ proc sendHeaders*(req: Request, headers: HttpHeaders): Future[void] =
|
||||||
return req.client.send(msg)
|
return req.client.send(msg)
|
||||||
|
|
||||||
proc respond*(req: Request, code: HttpCode, content: string,
|
proc respond*(req: Request, code: HttpCode, content: string,
|
||||||
headers = EmptyHttpHeaders): Future[void] =
|
headers: HttpHeaders = nil): Future[void] =
|
||||||
## Responds to the request with the specified ``HttpCode``, headers and
|
## Responds to the request with the specified ``HttpCode``, headers and
|
||||||
## content.
|
## content.
|
||||||
##
|
##
|
||||||
|
|
@ -97,7 +97,7 @@ proc respond*(req: Request, code: HttpCode, content: string,
|
||||||
## await req.respond(Http404, "Not Found")
|
## await req.respond(Http404, "Not Found")
|
||||||
var msg = "HTTP/1.1 " & $code & "\c\L"
|
var msg = "HTTP/1.1 " & $code & "\c\L"
|
||||||
|
|
||||||
if isEmpty(headers):
|
if headers != nil:
|
||||||
msg.addHeaders(headers)
|
msg.addHeaders(headers)
|
||||||
msg.add("Content-Length: ")
|
msg.add("Content-Length: ")
|
||||||
# this particular way saves allocations:
|
# this particular way saves allocations:
|
||||||
|
|
|
||||||
|
|
@ -847,7 +847,7 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
|
||||||
|
|
||||||
proc override(fallback, override: HttpHeaders): HttpHeaders =
|
proc override(fallback, override: HttpHeaders): HttpHeaders =
|
||||||
# Right-biased map union for `HttpHeaders`
|
# Right-biased map union for `HttpHeaders`
|
||||||
if override.isEmpty:
|
if override.isNil:
|
||||||
return fallback
|
return fallback
|
||||||
|
|
||||||
result = newHttpHeaders()
|
result = newHttpHeaders()
|
||||||
|
|
@ -858,7 +858,7 @@ proc override(fallback, override: HttpHeaders): HttpHeaders =
|
||||||
|
|
||||||
proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
|
proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
|
||||||
httpMethod: string, body = "",
|
httpMethod: string, body = "",
|
||||||
headers = EmptyHttpHeaders): Future[Response | AsyncResponse]
|
headers: HttpHeaders = nil): Future[Response | AsyncResponse]
|
||||||
{.multisync.} =
|
{.multisync.} =
|
||||||
# Helper that actually makes the request. Does not handle redirects.
|
# Helper that actually makes the request. Does not handle redirects.
|
||||||
let requestUrl = parseUri(url)
|
let requestUrl = parseUri(url)
|
||||||
|
|
@ -892,7 +892,7 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
|
||||||
|
|
||||||
proc request*(client: HttpClient | AsyncHttpClient, url: string,
|
proc request*(client: HttpClient | AsyncHttpClient, url: string,
|
||||||
httpMethod: string, body = "",
|
httpMethod: string, body = "",
|
||||||
headers = EmptyHttpHeaders): Future[Response | AsyncResponse]
|
headers: HttpHeaders = nil): Future[Response | AsyncResponse]
|
||||||
{.multisync.} =
|
{.multisync.} =
|
||||||
## Connects to the hostname specified by the URL and performs a request
|
## Connects to the hostname specified by the URL and performs a request
|
||||||
## using the custom method string specified by ``httpMethod``.
|
## using the custom method string specified by ``httpMethod``.
|
||||||
|
|
@ -917,7 +917,7 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
|
||||||
|
|
||||||
proc request*(client: HttpClient | AsyncHttpClient, url: string,
|
proc request*(client: HttpClient | AsyncHttpClient, url: string,
|
||||||
httpMethod = HttpGet, body = "",
|
httpMethod = HttpGet, body = "",
|
||||||
headers = EmptyHttpHeaders): Future[Response | AsyncResponse]
|
headers: HttpHeaders = nil): Future[Response | AsyncResponse]
|
||||||
{.multisync.} =
|
{.multisync.} =
|
||||||
## Connects to the hostname specified by the URL and performs a request
|
## Connects to the hostname specified by the URL and performs a request
|
||||||
## using the method specified.
|
## using the method specified.
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,14 @@
|
||||||
|
|
||||||
## Contains functionality shared between the ``httpclient`` and
|
## Contains functionality shared between the ``httpclient`` and
|
||||||
## ``asynchttpserver`` modules.
|
## ``asynchttpserver`` modules.
|
||||||
|
##
|
||||||
|
## Unstable API.
|
||||||
|
|
||||||
import tables, strutils, parseutils
|
import tables, strutils, parseutils
|
||||||
|
|
||||||
type
|
type
|
||||||
HeadersImpl = TableRef[string, seq[string]]
|
HttpHeaders* = ref object
|
||||||
HttpHeaders* = distinct HeadersImpl
|
table*: TableRef[string, seq[string]]
|
||||||
|
|
||||||
HttpHeaderValues* = distinct seq[string]
|
HttpHeaderValues* = distinct seq[string]
|
||||||
|
|
||||||
|
|
@ -95,32 +97,25 @@ const
|
||||||
Http504* = HttpCode(504)
|
Http504* = HttpCode(504)
|
||||||
Http505* = HttpCode(505)
|
Http505* = HttpCode(505)
|
||||||
|
|
||||||
const
|
const headerLimit* = 10_000
|
||||||
headerLimit* = 10_000 ## The limit of HTTP headers in bytes. This limit
|
|
||||||
## is not enforced by httpcore but by modules using
|
|
||||||
## httpcore.
|
|
||||||
EmptyHttpHeaders* = HttpHeaders(nil) ## Constant that represents empty
|
|
||||||
## http headers.
|
|
||||||
|
|
||||||
template table*(x: HttpHeaders): TableRef[string, seq[string]] {.
|
|
||||||
deprecated: "use the other accessor procs instead".} =
|
|
||||||
TableRef[string, seq[string]](x)
|
|
||||||
|
|
||||||
proc newHttpHeaders*(): HttpHeaders =
|
proc newHttpHeaders*(): HttpHeaders =
|
||||||
result = HttpHeaders newTable[string, seq[string]]()
|
new result
|
||||||
|
result.table = newTable[string, seq[string]]()
|
||||||
|
|
||||||
proc newHttpHeaders*(keyValuePairs:
|
proc newHttpHeaders*(keyValuePairs:
|
||||||
openArray[tuple[key: string, val: string]]): HttpHeaders =
|
openArray[tuple[key: string, val: string]]): HttpHeaders =
|
||||||
result = HttpHeaders newTable[string, seq[string]]()
|
var pairs: seq[tuple[key: string, val: seq[string]]] = @[]
|
||||||
for pair in keyValuePairs:
|
for pair in keyValuePairs:
|
||||||
HeadersImpl(result)[pair.key.toLowerAscii()] = @[pair.val]
|
pairs.add((pair.key.toLowerAscii(), @[pair.val]))
|
||||||
|
new result
|
||||||
|
result.table = newTable[string, seq[string]](pairs)
|
||||||
|
|
||||||
proc `$`*(headers: HttpHeaders): string = $(HeadersImpl(headers))
|
proc `$`*(headers: HttpHeaders): string =
|
||||||
|
return $headers.table
|
||||||
proc isEmpty*(a: HttpHeaders): bool = HeadersImpl(a) == nil
|
|
||||||
|
|
||||||
proc clear*(headers: HttpHeaders) =
|
proc clear*(headers: HttpHeaders) =
|
||||||
HeadersImpl(headers).clear()
|
headers.table.clear()
|
||||||
|
|
||||||
proc `[]`*(headers: HttpHeaders, key: string): HttpHeaderValues =
|
proc `[]`*(headers: HttpHeaders, key: string): HttpHeaderValues =
|
||||||
## Returns the values associated with the given ``key``. If the returned
|
## Returns the values associated with the given ``key``. If the returned
|
||||||
|
|
@ -130,44 +125,43 @@ proc `[]`*(headers: HttpHeaders, key: string): HttpHeaderValues =
|
||||||
##
|
##
|
||||||
## To access multiple values of a key, use the overloaded ``[]`` below or
|
## To access multiple values of a key, use the overloaded ``[]`` below or
|
||||||
## to get all of them access the ``table`` field directly.
|
## to get all of them access the ``table`` field directly.
|
||||||
result = HeadersImpl(headers)[key.toLowerAscii].HttpHeaderValues
|
return headers.table[key.toLowerAscii].HttpHeaderValues
|
||||||
|
|
||||||
converter toString*(values: HttpHeaderValues): string =
|
converter toString*(values: HttpHeaderValues): string =
|
||||||
result = seq[string](values)[0]
|
return seq[string](values)[0]
|
||||||
|
|
||||||
proc `[]`*(headers: HttpHeaders, key: string, i: int): string =
|
proc `[]`*(headers: HttpHeaders, key: string, i: int): string =
|
||||||
## Returns the ``i``'th value associated with the given key. If there are
|
## Returns the ``i``'th value associated with the given key. If there are
|
||||||
## no values associated with the key or the ``i``'th value doesn't exist,
|
## no values associated with the key or the ``i``'th value doesn't exist,
|
||||||
## an exception is raised.
|
## an exception is raised.
|
||||||
result = HeadersImpl(headers)[key.toLowerAscii][i]
|
return headers.table[key.toLowerAscii][i]
|
||||||
|
|
||||||
proc `[]=`*(headers: HttpHeaders, key, value: string) =
|
proc `[]=`*(headers: HttpHeaders, key, value: string) =
|
||||||
## Sets the header entries associated with ``key`` to the specified value.
|
## Sets the header entries associated with ``key`` to the specified value.
|
||||||
## Replaces any existing values.
|
## Replaces any existing values.
|
||||||
HeadersImpl(headers)[key.toLowerAscii] = @[value]
|
headers.table[key.toLowerAscii] = @[value]
|
||||||
|
|
||||||
proc `[]=`*(headers: HttpHeaders, key: string, value: seq[string]) =
|
proc `[]=`*(headers: HttpHeaders, key: string, value: seq[string]) =
|
||||||
## Sets the header entries associated with ``key`` to the specified list of
|
## Sets the header entries associated with ``key`` to the specified list of
|
||||||
## values.
|
## values.
|
||||||
## Replaces any existing values.
|
## Replaces any existing values.
|
||||||
HeadersImpl(headers)[key.toLowerAscii] = value
|
headers.table[key.toLowerAscii] = value
|
||||||
|
|
||||||
proc add*(headers: HttpHeaders, key, value: string) =
|
proc add*(headers: HttpHeaders, key, value: string) =
|
||||||
## Adds the specified value to the specified key. Appends to any existing
|
## Adds the specified value to the specified key. Appends to any existing
|
||||||
## values associated with the key.
|
## values associated with the key.
|
||||||
let k = key.toLowerAscii
|
if not headers.table.hasKey(key.toLowerAscii):
|
||||||
if not HeadersImpl(headers).hasKey(k):
|
headers.table[key.toLowerAscii] = @[value]
|
||||||
HeadersImpl(headers)[k] = @[value]
|
|
||||||
else:
|
else:
|
||||||
HeadersImpl(headers)[k].add(value)
|
headers.table[key.toLowerAscii].add(value)
|
||||||
|
|
||||||
proc del*(headers: HttpHeaders, key: string) =
|
proc del*(headers: HttpHeaders, key: string) =
|
||||||
## Delete the header entries associated with ``key``
|
## Delete the header entries associated with ``key``
|
||||||
HeadersImpl(headers).del(key.toLowerAscii)
|
headers.table.del(key.toLowerAscii)
|
||||||
|
|
||||||
iterator pairs*(headers: HttpHeaders): tuple[key, value: string] =
|
iterator pairs*(headers: HttpHeaders): tuple[key, value: string] =
|
||||||
## Yields each key, value pair.
|
## Yields each key, value pair.
|
||||||
for k, v in HeadersImpl(headers):
|
for k, v in headers.table:
|
||||||
for value in v:
|
for value in v:
|
||||||
yield (k, value)
|
yield (k, value)
|
||||||
|
|
||||||
|
|
@ -178,15 +172,18 @@ proc contains*(values: HttpHeaderValues, value: string): bool =
|
||||||
if val.toLowerAscii == value.toLowerAscii: return true
|
if val.toLowerAscii == value.toLowerAscii: return true
|
||||||
|
|
||||||
proc hasKey*(headers: HttpHeaders, key: string): bool =
|
proc hasKey*(headers: HttpHeaders, key: string): bool =
|
||||||
result = HeadersImpl(headers).hasKey(key.toLowerAscii())
|
return headers.table.hasKey(key.toLowerAscii())
|
||||||
|
|
||||||
proc getOrDefault*(headers: HttpHeaders, key: string,
|
proc getOrDefault*(headers: HttpHeaders, key: string,
|
||||||
default = @[""].HttpHeaderValues): HttpHeaderValues =
|
default = @[""].HttpHeaderValues): HttpHeaderValues =
|
||||||
## Returns the values associated with the given ``key``. If there are no
|
## Returns the values associated with the given ``key``. If there are no
|
||||||
## values associated with the key, then ``default`` is returned.
|
## values associated with the key, then ``default`` is returned.
|
||||||
result = HttpHeaderValues(HeadersImpl(headers).getOrDefault(key, seq[string](default)))
|
if headers.hasKey(key):
|
||||||
|
return headers[key]
|
||||||
|
else:
|
||||||
|
return default
|
||||||
|
|
||||||
proc len*(headers: HttpHeaders): int = result = HeadersImpl(headers).len
|
proc len*(headers: HttpHeaders): int = return headers.table.len
|
||||||
|
|
||||||
proc parseList(line: string, list: var seq[string], start: int): int =
|
proc parseList(line: string, list: var seq[string], start: int): int =
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -227,7 +224,7 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int],
|
||||||
result = protocol.major == major and protocol.minor == minor
|
result = protocol.major == major and protocol.minor == minor
|
||||||
|
|
||||||
proc contains*(methods: set[HttpMethod], x: string): bool =
|
proc contains*(methods: set[HttpMethod], x: string): bool =
|
||||||
result = parseEnum[HttpMethod](x) in methods
|
return parseEnum[HttpMethod](x) in methods
|
||||||
|
|
||||||
proc `$`*(code: HttpCode): string =
|
proc `$`*(code: HttpCode): string =
|
||||||
## Converts the specified ``HttpCode`` into a HTTP status.
|
## Converts the specified ``HttpCode`` into a HTTP status.
|
||||||
|
|
@ -289,26 +286,26 @@ proc `$`*(code: HttpCode): string =
|
||||||
proc `==`*(a, b: HttpCode): bool {.borrow.}
|
proc `==`*(a, b: HttpCode): bool {.borrow.}
|
||||||
|
|
||||||
proc `==`*(rawCode: string, code: HttpCode): bool =
|
proc `==`*(rawCode: string, code: HttpCode): bool =
|
||||||
result = cmpIgnoreCase(rawCode, $code) == 0
|
return cmpIgnoreCase(rawCode, $code) == 0
|
||||||
|
|
||||||
proc is2xx*(code: HttpCode): bool =
|
proc is2xx*(code: HttpCode): bool =
|
||||||
## Determines whether ``code`` is a 2xx HTTP status code.
|
## Determines whether ``code`` is a 2xx HTTP status code.
|
||||||
result = code.int in {200 .. 299}
|
return code.int in {200 .. 299}
|
||||||
|
|
||||||
proc is3xx*(code: HttpCode): bool =
|
proc is3xx*(code: HttpCode): bool =
|
||||||
## Determines whether ``code`` is a 3xx HTTP status code.
|
## Determines whether ``code`` is a 3xx HTTP status code.
|
||||||
result = code.int in {300 .. 399}
|
return code.int in {300 .. 399}
|
||||||
|
|
||||||
proc is4xx*(code: HttpCode): bool =
|
proc is4xx*(code: HttpCode): bool =
|
||||||
## Determines whether ``code`` is a 4xx HTTP status code.
|
## Determines whether ``code`` is a 4xx HTTP status code.
|
||||||
result = code.int in {400 .. 499}
|
return code.int in {400 .. 499}
|
||||||
|
|
||||||
proc is5xx*(code: HttpCode): bool =
|
proc is5xx*(code: HttpCode): bool =
|
||||||
## Determines whether ``code`` is a 5xx HTTP status code.
|
## Determines whether ``code`` is a 5xx HTTP status code.
|
||||||
result = code.int in {500 .. 599}
|
return code.int in {500 .. 599}
|
||||||
|
|
||||||
proc `$`*(httpMethod: HttpMethod): string =
|
proc `$`*(httpMethod: HttpMethod): string =
|
||||||
result = (system.`$`(httpMethod))[4 .. ^1].toUpperAscii()
|
return (system.`$`(httpMethod))[4 .. ^1].toUpperAscii()
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var test = newHttpHeaders()
|
var test = newHttpHeaders()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue