netkit/http/connection

这个模块实现了一个介于客户端和服务器的 HTTP 连接。 HttpConnection 能够识别网络传输的 HTTP 消息。

使用

读消息头

import netkit/http/connection
import netkit/http/header

type
  Packet = ref object
    header: HttpHeader

var packet = new(Packet)
packet.header = HttpHeader(kind: HttpHeaderKind.Request)

var conn = newHttpConnection(socket, address)

try:
  GC_ref(packet)
  await conn.readHttpHeader(packet.header.addr)
finally:
  GC_unref(packet)

读消息体

let readLen = await conn.readData(buf, 1024)

读 chunked 编码的消息体

type
  Packet = ref object
    header: ChunkHeader

try:
  GC_ref(packet)
  await conn.readChunkHeader(packet.header.addr)
finally:
  GC_unref(packet)

if header.size == 0: # read tail
  var trailers: seq[string]
  await conn.readEnd(trailers)
else:
  var chunkLen = header.size
  var buf = newString(header.size)
  let readLen = await conn.readData(buf, header.size)
  if readLen != header.size:
    echo "Connection closed prematurely"

写消息

await conn.write("""
GET /iocrate/netkit HTTP/1.1
Host: iocrate.com
Content-Length: 12

foobarfoobar
""")

Types

HttpConnection = ref object
  buffer: MarkableCircularBuffer
  parser: HttpParser
  socket: AsyncFD
  address: string
  closed: bool
HTTP 连接.   Source Edit

Procs

proc newHttpConnection(socket: AsyncFD; address: string): HttpConnection {...}{.raises: [],
    tags: [].}
创建一个新的 HttpConnection 。   Source Edit
proc close(conn: HttpConnection) {...}{.inline, raises: [], tags: [].}
关闭连接以释放底层资源。   Source Edit
proc closed(conn: HttpConnection): bool {...}{.inline, raises: [], tags: [].}
判断连接是否已经关闭。   Source Edit
proc readHttpHeader(conn: HttpConnection; header: ptr HttpHeader): Future[void] {...}{.
    raises: [], tags: [].}

读取一个消息头部。

如果读过程中出现系统错误,则会触发 OSError 异常;如果在成功读取之前连接断开,则会触发 ReadAbortedError 异常。

  Source Edit
proc readChunkHeader(conn: HttpConnection; header: ptr ChunkHeader): Future[void] {...}{.
    raises: [], tags: [].}

读取一个 chunked 编码的块的头部。

如果读过程中出现系统错误,则会触发 OSError 异常;如果在成功读取之前连接断开,则会触发 ReadAbortedError 异常。

  Source Edit
proc readChunkEnd(conn: HttpConnection; trailer: ptr seq[string]): Future[void] {...}{.
    raises: [], tags: [].}

读取一个 chunked 编码终止块 (terminating chunk)、trailers、和 final CRLF。

如果读过程中出现系统错误,则会触发 OSError 异常;如果在成功读取之前连接断开,则会触发 ReadAbortedError 异常。

  Source Edit
proc readData(conn: HttpConnection; buf: pointer; size: Natural): Future[Natural] {...}{.
    raises: [], tags: [].}

读取数据直到 size 字节,读取的数据填充在 buf ,返回实际读取的字节数。如果返回值不等于 size ,说明 出现错误或者连接已经断开。如果出现错误或连接已经断开,则立刻返回;否则,将一直等待读取,直到 size 字节。

这个函数应该用来读取消息体。

如果读过程中出现系统错误,则会触发 OSError 异常;如果在成功读取之前连接断开,则会触发 ReadAbortedError 异常。

  Source Edit
proc write(conn: HttpConnection; buf: pointer; size: Natural): Future[void] {...}{.inline,
    raises: [], tags: [].}

写入数据。 buf 指定数据源, size 指定数据源的字节数。

如果写过程中出现系统错误,则会触发 OSError 异常;如果在成功写之前连接断开,则会触发 WriteAbortedError 异常。

  Source Edit
proc write(conn: HttpConnection; data: string): Future[void] {...}{.inline, raises: [],
    tags: [].}

写入数据。 data 指定数据源。

如果写过程中出现系统错误,则会触发 OSError 异常;如果在成功写之前连接断开,则会触发 WriteAbortedError 异常。

  Source Edit