mirror of
https://github.com/zap-proto/http.git
synced 2026-10-04 03:07:19 +00:00
package http — the last element of the module path, as Go expects
v0.3.3 renamed this to package zap, and that was wrong twice. Go resolves an unaliased import to the package's own name, so github.com/zap-proto/http should answer to http; and this package IMPORTS zap, the wire format, so naming itself zap put two different things under one word in the same file. An importer that also needs net/http aliases one of them, which is the ordinary convention rather than a reason to invent a name. zap.Version and zap.HeaderSize are that other package and are untouched. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
package zap_test
|
package http_test
|
||||||
|
|
||||||
// Exported-API-only codec benchmarks. These use only MarshalRequest /
|
// Exported-API-only codec benchmarks. These use only MarshalRequest /
|
||||||
// MarshalResponse / UnmarshalRequest / UnmarshalResponse, so the SAME file
|
// MarshalResponse / UnmarshalRequest / UnmarshalResponse, so the SAME file
|
||||||
@@ -34,7 +34,7 @@ func BenchmarkCompat_MarshalRequest(b *testing.B) {
|
|||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if _, err := zap.MarshalRequest(req); err != nil {
|
if _, err := http.MarshalRequest(req); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ func BenchmarkCompat_MarshalResponse(b *testing.B) {
|
|||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if _, err := zap.MarshalResponse(resp); err != nil {
|
if _, err := http.MarshalResponse(resp); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,13 +54,13 @@ func BenchmarkCompat_MarshalResponse(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkCompat_UnmarshalRequest(b *testing.B) {
|
func BenchmarkCompat_UnmarshalRequest(b *testing.B) {
|
||||||
req := compatReq()
|
req := compatReq()
|
||||||
frame, _ := zap.MarshalRequest(req)
|
frame, _ := http.MarshalRequest(req)
|
||||||
fasthttp.ReleaseRequest(req)
|
fasthttp.ReleaseRequest(req)
|
||||||
var dst fasthttp.Request
|
var dst fasthttp.Request
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if err := zap.UnmarshalRequest(frame, &dst); err != nil {
|
if err := http.UnmarshalRequest(frame, &dst); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,13 +68,13 @@ func BenchmarkCompat_UnmarshalRequest(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkCompat_UnmarshalResponse(b *testing.B) {
|
func BenchmarkCompat_UnmarshalResponse(b *testing.B) {
|
||||||
resp := compatResp()
|
resp := compatResp()
|
||||||
frame, _ := zap.MarshalResponse(resp)
|
frame, _ := http.MarshalResponse(resp)
|
||||||
fasthttp.ReleaseResponse(resp)
|
fasthttp.ReleaseResponse(resp)
|
||||||
var dst fasthttp.Response
|
var dst fasthttp.Response
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if err := zap.UnmarshalResponse(frame, &dst); err != nil {
|
if err := http.UnmarshalResponse(frame, &dst); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// Usage mirrors fasthttp's Do(req, resp):
|
// Usage mirrors fasthttp's Do(req, resp):
|
||||||
//
|
//
|
||||||
// t := zap.Dial("tcp", "server:9999")
|
// t := http.Dial("tcp", "server:9999")
|
||||||
// req := fasthttp.AcquireRequest()
|
// req := fasthttp.AcquireRequest()
|
||||||
// resp := fasthttp.AcquireResponse()
|
// resp := fasthttp.AcquireResponse()
|
||||||
// req.SetRequestURI("/healthz")
|
// req.SetRequestURI("/healthz")
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
// decoded — no body-close handshake is needed. The pool caps at
|
// decoded — no body-close handshake is needed. The pool caps at
|
||||||
// MaxIdleConns; surplus conns close on return.
|
// MaxIdleConns; surplus conns close on return.
|
||||||
|
|
||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -57,8 +57,8 @@ type Transport struct {
|
|||||||
// functions. A unix address is a socket path and carries the same ZAP frames
|
// functions. A unix address is a socket path and carries the same ZAP frames
|
||||||
// as tcp — the wire does not change with the network.
|
// as tcp — the wire does not change with the network.
|
||||||
//
|
//
|
||||||
// zap.Dial("tcp", "billing.hanzo.svc:9653")
|
// http.Dial("tcp", "billing.hanzo.svc:9653")
|
||||||
// zap.Dial("unix", "/run/hanzo/billing.sock")
|
// http.Dial("unix", "/run/hanzo/billing.sock")
|
||||||
//
|
//
|
||||||
// Dialing is lazy; the first request opens the connection.
|
// Dialing is lazy; the first request opens the connection.
|
||||||
func Dial(network, addr string) *Transport {
|
func Dial(network, addr string) *Transport {
|
||||||
@@ -93,12 +93,12 @@ func (t *Transport) SetMaxIdleConns(n int) {
|
|||||||
// for concurrent use: each call takes its own connection from the pool.
|
// for concurrent use: each call takes its own connection from the pool.
|
||||||
func (t *Transport) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
|
func (t *Transport) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
|
||||||
if t.addr == "" {
|
if t.addr == "" {
|
||||||
return fmt.Errorf("zap: Transport.addr is empty (use Dial)")
|
return fmt.Errorf("zaphttp: Transport.addr is empty (use Dial)")
|
||||||
}
|
}
|
||||||
|
|
||||||
pc, err := t.acquireConn()
|
pc, err := t.acquireConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("zap: dial %s: %w", t.addr, err)
|
return fmt.Errorf("zaphttp: dial %s: %w", t.addr, err)
|
||||||
}
|
}
|
||||||
conn, br := pc.c, pc.br
|
conn, br := pc.c, pc.br
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ func (t *Transport) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
|
|||||||
}
|
}
|
||||||
if err := writeFramePrefixed(conn, pc.wbuf); err != nil {
|
if err := writeFramePrefixed(conn, pc.wbuf); err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return fmt.Errorf("zap: write request: %w", err)
|
return fmt.Errorf("zaphttp: write request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.readTimeout > 0 {
|
if t.readTimeout > 0 {
|
||||||
@@ -121,13 +121,13 @@ func (t *Transport) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
|
|||||||
pc.rbuf, err = readFrameInto(br, pc.rbuf)
|
pc.rbuf, err = readFrameInto(br, pc.rbuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return fmt.Errorf("zap: read response: %w", err)
|
return fmt.Errorf("zaphttp: read response: %w", err)
|
||||||
}
|
}
|
||||||
respFrame := pc.rbuf
|
respFrame := pc.rbuf
|
||||||
ft, ok := frameType(respFrame)
|
ft, ok := frameType(respFrame)
|
||||||
if !ok {
|
if !ok {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return fmt.Errorf("zap: short response frame")
|
return fmt.Errorf("zaphttp: short response frame")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Streamed response: apply the head, then attach a body stream that reads
|
// Streamed response: apply the head, then attach a body stream that reads
|
||||||
@@ -138,7 +138,7 @@ func (t *Transport) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
|
|||||||
if ft == FrameResponseHead {
|
if ft == FrameResponseHead {
|
||||||
if err := UnmarshalResponseHead(respFrame, resp); err != nil {
|
if err := UnmarshalResponseHead(respFrame, resp); err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return fmt.Errorf("zap: unmarshal response head: %w", err)
|
return fmt.Errorf("zaphttp: unmarshal response head: %w", err)
|
||||||
}
|
}
|
||||||
resp.SetBodyStream(&streamReader{t: t, pc: pc, br: br}, -1)
|
resp.SetBodyStream(&streamReader{t: t, pc: pc, br: br}, -1)
|
||||||
return nil
|
return nil
|
||||||
@@ -146,7 +146,7 @@ func (t *Transport) Do(req *fasthttp.Request, resp *fasthttp.Response) error {
|
|||||||
|
|
||||||
if err := UnmarshalResponse(respFrame, resp); err != nil {
|
if err := UnmarshalResponse(respFrame, resp); err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return fmt.Errorf("zap: unmarshal response: %w", err)
|
return fmt.Errorf("zaphttp: unmarshal response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the read deadline and return the conn to the pool. The response
|
// Reset the read deadline and return the conn to the pool. The response
|
||||||
@@ -209,7 +209,7 @@ func (s *streamReader) Read(p []byte) (int, error) {
|
|||||||
s.release()
|
s.release()
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
default:
|
default:
|
||||||
s.err = fmt.Errorf("zap: unexpected frame %#x mid-stream", ft)
|
s.err = fmt.Errorf("zaphttp: unexpected frame %#x mid-stream", ft)
|
||||||
return 0, s.err
|
return 0, s.err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
// relOffset is patched to point at them. An empty text/bytes field stays a
|
// relOffset is patched to point at them. An empty text/bytes field stays a
|
||||||
// zeroed {0,0} slot with no tail entry. This is exactly what zap.Builder emits.
|
// zeroed {0,0} slot with no tail entry. This is exactly what zap.Builder emits.
|
||||||
|
|
||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
@@ -123,7 +123,7 @@ func AppendRequest(dst []byte, req *fasthttp.Request) ([]byte, error) {
|
|||||||
|
|
||||||
trailer, err := encodeTrailers(&req.Header)
|
trailer, err := encodeTrailers(&req.Header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dst, fmt.Errorf("zap: encode trailer: %w", err)
|
return dst, fmt.Errorf("zaphttp: encode trailer: %w", err)
|
||||||
}
|
}
|
||||||
dst = putVarBytes(dst, obj+reqTrailer, trailer)
|
dst = putVarBytes(dst, obj+reqTrailer, trailer)
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ func AppendResponse(dst []byte, resp *fasthttp.Response) ([]byte, error) {
|
|||||||
|
|
||||||
trailer, err := encodeTrailers(&resp.Header)
|
trailer, err := encodeTrailers(&resp.Header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dst, fmt.Errorf("zap: encode trailer: %w", err)
|
return dst, fmt.Errorf("zaphttp: encode trailer: %w", err)
|
||||||
}
|
}
|
||||||
dst = putVarBytes(dst, obj+respTrailer, trailer)
|
dst = putVarBytes(dst, obj+respTrailer, trailer)
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ func frameRoot(frame []byte, wantType uint16) (root, size int, err error) {
|
|||||||
return 0, 0, zap.ErrBufferTooSmall
|
return 0, 0, zap.ErrBufferTooSmall
|
||||||
}
|
}
|
||||||
if t := binary.LittleEndian.Uint16(frame[6:8]) >> 8; t != wantType {
|
if t := binary.LittleEndian.Uint16(frame[6:8]) >> 8; t != wantType {
|
||||||
return 0, 0, fmt.Errorf("zap: frame type %#x, want %#x", t, wantType)
|
return 0, 0, fmt.Errorf("zaphttp: frame type %#x, want %#x", t, wantType)
|
||||||
}
|
}
|
||||||
root = int(binary.LittleEndian.Uint32(frame[8:12]))
|
root = int(binary.LittleEndian.Uint32(frame[8:12]))
|
||||||
if root < zap.HeaderSize || root >= size {
|
if root < zap.HeaderSize || root >= size {
|
||||||
@@ -347,7 +347,7 @@ func emitHeaders(dst []byte, pairs []hpair) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// errHeaderShort reports a header block that ends mid-field.
|
// errHeaderShort reports a header block that ends mid-field.
|
||||||
var errHeaderShort = errors.New("zap: truncated header block")
|
var errHeaderShort = errors.New("zaphttp: truncated header block")
|
||||||
|
|
||||||
// forEachHeader calls fn for every pair in raw. Keys and values alias raw and
|
// forEachHeader calls fn for every pair in raw. Keys and values alias raw and
|
||||||
// must not outlive it.
|
// must not outlive it.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|||||||
+22
-22
@@ -6,7 +6,7 @@
|
|||||||
// accidental format change fails loudly. They were regenerated once,
|
// accidental format change fails loudly. They were regenerated once,
|
||||||
// deliberately, when headers moved from a JSON map to length-prefixed pairs.
|
// deliberately, when headers moved from a JSON map to length-prefixed pairs.
|
||||||
|
|
||||||
package zap_test
|
package http_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -42,7 +42,7 @@ func listen(t *testing.T, handler fasthttp.RequestHandler) (addr string, shutdow
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("listen: %v", err)
|
t.Fatalf("listen: %v", err)
|
||||||
}
|
}
|
||||||
srv := &zap.Server{Handler: handler}
|
srv := &http.Server{Handler: handler}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -61,7 +61,7 @@ func listen(t *testing.T, handler fasthttp.RequestHandler) (addr string, shutdow
|
|||||||
// response the caller must release.
|
// response the caller must release.
|
||||||
func do(t *testing.T, addr, method, path string, body []byte, mutate func(*fasthttp.Request)) *fasthttp.Response {
|
func do(t *testing.T, addr, method, path string, body []byte, mutate func(*fasthttp.Request)) *fasthttp.Response {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
tr := zap.Dial("tcp", addr)
|
tr := http.Dial("tcp", addr)
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
defer fasthttp.ReleaseRequest(req)
|
defer fasthttp.ReleaseRequest(req)
|
||||||
req.Header.SetMethod(method)
|
req.Header.SetMethod(method)
|
||||||
@@ -241,7 +241,7 @@ func TestKeepAlive(t *testing.T) {
|
|||||||
})
|
})
|
||||||
defer stop()
|
defer stop()
|
||||||
|
|
||||||
tr := zap.Dial("tcp", addr)
|
tr := http.Dial("tcp", addr)
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
path := fmt.Sprintf("/req-%d", i)
|
path := fmt.Sprintf("/req-%d", i)
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
@@ -271,12 +271,12 @@ func TestMarshalRequest_idempotent(t *testing.T) {
|
|||||||
orig.Header.Set("Authorization", "Bearer token-stays-encrypted-on-the-wire")
|
orig.Header.Set("Authorization", "Bearer token-stays-encrypted-on-the-wire")
|
||||||
orig.SetBody(body)
|
orig.SetBody(body)
|
||||||
|
|
||||||
frame, err := zap.MarshalRequest(orig)
|
frame, err := http.MarshalRequest(orig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
var got fasthttp.Request
|
var got fasthttp.Request
|
||||||
if err := zap.UnmarshalRequest(frame, &got); err != nil {
|
if err := http.UnmarshalRequest(frame, &got); err != nil {
|
||||||
t.Fatalf("unmarshal: %v", err)
|
t.Fatalf("unmarshal: %v", err)
|
||||||
}
|
}
|
||||||
if string(got.Header.Method()) != fasthttp.MethodPost {
|
if string(got.Header.Method()) != fasthttp.MethodPost {
|
||||||
@@ -314,12 +314,12 @@ func TestMarshalResponse_idempotent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
orig.Header.Set("X-Checksum", "deadbeef")
|
orig.Header.Set("X-Checksum", "deadbeef")
|
||||||
|
|
||||||
frame, err := zap.MarshalResponse(orig)
|
frame, err := http.MarshalResponse(orig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
var got fasthttp.Response
|
var got fasthttp.Response
|
||||||
if err := zap.UnmarshalResponse(frame, &got); err != nil {
|
if err := http.UnmarshalResponse(frame, &got); err != nil {
|
||||||
t.Fatalf("unmarshal: %v", err)
|
t.Fatalf("unmarshal: %v", err)
|
||||||
}
|
}
|
||||||
if got.StatusCode() != fasthttp.StatusTeapot {
|
if got.StatusCode() != fasthttp.StatusTeapot {
|
||||||
@@ -345,24 +345,24 @@ func TestFrameType_crossGuard(t *testing.T) {
|
|||||||
defer fasthttp.ReleaseRequest(req)
|
defer fasthttp.ReleaseRequest(req)
|
||||||
req.Header.SetMethod(fasthttp.MethodGet)
|
req.Header.SetMethod(fasthttp.MethodGet)
|
||||||
req.SetRequestURI("/x")
|
req.SetRequestURI("/x")
|
||||||
reqFrame, err := zap.MarshalRequest(req)
|
reqFrame, err := http.MarshalRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal request: %v", err)
|
t.Fatalf("marshal request: %v", err)
|
||||||
}
|
}
|
||||||
var asResp fasthttp.Response
|
var asResp fasthttp.Response
|
||||||
if err := zap.UnmarshalResponse(reqFrame, &asResp); err == nil {
|
if err := http.UnmarshalResponse(reqFrame, &asResp); err == nil {
|
||||||
t.Errorf("UnmarshalResponse accepted a request frame; want error")
|
t.Errorf("UnmarshalResponse accepted a request frame; want error")
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := fasthttp.AcquireResponse()
|
resp := fasthttp.AcquireResponse()
|
||||||
defer fasthttp.ReleaseResponse(resp)
|
defer fasthttp.ReleaseResponse(resp)
|
||||||
resp.SetStatusCode(fasthttp.StatusOK)
|
resp.SetStatusCode(fasthttp.StatusOK)
|
||||||
respFrame, err := zap.MarshalResponse(resp)
|
respFrame, err := http.MarshalResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal response: %v", err)
|
t.Fatalf("marshal response: %v", err)
|
||||||
}
|
}
|
||||||
var asReq fasthttp.Request
|
var asReq fasthttp.Request
|
||||||
if err := zap.UnmarshalRequest(respFrame, &asReq); err == nil {
|
if err := http.UnmarshalRequest(respFrame, &asReq); err == nil {
|
||||||
t.Errorf("UnmarshalRequest accepted a response frame; want error")
|
t.Errorf("UnmarshalRequest accepted a response frame; want error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,12 +372,12 @@ func TestEmptyHeaders_decode(t *testing.T) {
|
|||||||
defer fasthttp.ReleaseRequest(req)
|
defer fasthttp.ReleaseRequest(req)
|
||||||
req.Header.SetMethod(fasthttp.MethodGet)
|
req.Header.SetMethod(fasthttp.MethodGet)
|
||||||
req.SetRequestURI("/")
|
req.SetRequestURI("/")
|
||||||
frame, err := zap.MarshalRequest(req)
|
frame, err := http.MarshalRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
var got fasthttp.Request
|
var got fasthttp.Request
|
||||||
if err := zap.UnmarshalRequest(frame, &got); err != nil {
|
if err := http.UnmarshalRequest(frame, &got); err != nil {
|
||||||
t.Fatalf("unmarshal: %v", err)
|
t.Fatalf("unmarshal: %v", err)
|
||||||
}
|
}
|
||||||
got.Header.Add("X-Added", "ok") // must not panic
|
got.Header.Add("X-Added", "ok") // must not panic
|
||||||
@@ -401,7 +401,7 @@ func mustHex(t *testing.T, s string) []byte {
|
|||||||
// produced by the prior net/http codec faithfully (backward wire compat).
|
// produced by the prior net/http codec faithfully (backward wire compat).
|
||||||
func TestWireGolden_DecodeRequest(t *testing.T) {
|
func TestWireGolden_DecodeRequest(t *testing.T) {
|
||||||
var req fasthttp.Request
|
var req fasthttp.Request
|
||||||
if err := zap.UnmarshalRequest(mustHex(t, goldenRequest), &req); err != nil {
|
if err := http.UnmarshalRequest(mustHex(t, goldenRequest), &req); err != nil {
|
||||||
t.Fatalf("decode golden request: %v", err)
|
t.Fatalf("decode golden request: %v", err)
|
||||||
}
|
}
|
||||||
if string(req.Header.Method()) != "POST" {
|
if string(req.Header.Method()) != "POST" {
|
||||||
@@ -423,7 +423,7 @@ func TestWireGolden_DecodeRequest(t *testing.T) {
|
|||||||
|
|
||||||
func TestWireGolden_DecodeResponse(t *testing.T) {
|
func TestWireGolden_DecodeResponse(t *testing.T) {
|
||||||
var resp fasthttp.Response
|
var resp fasthttp.Response
|
||||||
if err := zap.UnmarshalResponse(mustHex(t, goldenResponse), &resp); err != nil {
|
if err := http.UnmarshalResponse(mustHex(t, goldenResponse), &resp); err != nil {
|
||||||
t.Fatalf("decode golden response: %v", err)
|
t.Fatalf("decode golden response: %v", err)
|
||||||
}
|
}
|
||||||
if resp.StatusCode() != 200 {
|
if resp.StatusCode() != 200 {
|
||||||
@@ -452,7 +452,7 @@ func TestWireGolden_EncodeRequest(t *testing.T) {
|
|||||||
req.Header.Set("X-Trace-Id", "abc-123")
|
req.Header.Set("X-Trace-Id", "abc-123")
|
||||||
req.SetBody([]byte(`{"jsonrpc":"2.0","method":"eth_blockNumber"}`))
|
req.SetBody([]byte(`{"jsonrpc":"2.0","method":"eth_blockNumber"}`))
|
||||||
|
|
||||||
frame, err := zap.MarshalRequest(req)
|
frame, err := http.MarshalRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -470,7 +470,7 @@ func TestWireGolden_EncodeResponse(t *testing.T) {
|
|||||||
resp.Header.Set("X-Trace-Id", "abc-123")
|
resp.Header.Set("X-Trace-Id", "abc-123")
|
||||||
resp.SetBody([]byte(`{"result":"0x2a"}`))
|
resp.SetBody([]byte(`{"result":"0x2a"}`))
|
||||||
|
|
||||||
frame, err := zap.MarshalResponse(resp)
|
frame, err := http.MarshalResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,7 @@ func TestWireGolden_EncodeEmptyRequest(t *testing.T) {
|
|||||||
req.SetRequestURI("/health")
|
req.SetRequestURI("/health")
|
||||||
req.Header.SetProtocol("HTTP/1.1")
|
req.Header.SetProtocol("HTTP/1.1")
|
||||||
|
|
||||||
frame, err := zap.MarshalRequest(req)
|
frame, err := http.MarshalRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -500,7 +500,7 @@ func TestWireGolden_EncodeEmptyRequest(t *testing.T) {
|
|||||||
// codec's output.
|
// codec's output.
|
||||||
func TestWireGolden_TrailerResponse(t *testing.T) {
|
func TestWireGolden_TrailerResponse(t *testing.T) {
|
||||||
var resp fasthttp.Response
|
var resp fasthttp.Response
|
||||||
if err := zap.UnmarshalResponse(mustHex(t, goldenTrailerResponse), &resp); err != nil {
|
if err := http.UnmarshalResponse(mustHex(t, goldenTrailerResponse), &resp); err != nil {
|
||||||
t.Fatalf("decode golden trailer response: %v", err)
|
t.Fatalf("decode golden trailer response: %v", err)
|
||||||
}
|
}
|
||||||
if string(resp.Header.ContentType()) != "application/octet-stream" {
|
if string(resp.Header.ContentType()) != "application/octet-stream" {
|
||||||
@@ -512,7 +512,7 @@ func TestWireGolden_TrailerResponse(t *testing.T) {
|
|||||||
if cs := string(resp.Header.Peek("X-Checksum")); cs != "deadbeef" {
|
if cs := string(resp.Header.Peek("X-Checksum")); cs != "deadbeef" {
|
||||||
t.Errorf("trailer X-Checksum = %q want deadbeef", cs)
|
t.Errorf("trailer X-Checksum = %q want deadbeef", cs)
|
||||||
}
|
}
|
||||||
frame, err := zap.MarshalResponse(&resp)
|
frame, err := http.MarshalResponse(&resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("re-marshal: %v", err)
|
t.Fatalf("re-marshal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -529,7 +529,7 @@ func TestConnReuse(t *testing.T) {
|
|||||||
defer stop()
|
defer stop()
|
||||||
_ = dials
|
_ = dials
|
||||||
|
|
||||||
tr := zap.Dial("tcp", addr)
|
tr := http.Dial("tcp", addr)
|
||||||
deadline := time.Now().Add(2 * time.Second)
|
deadline := time.Now().Add(2 * time.Second)
|
||||||
for i := 0; i < 3 && time.Now().Before(deadline); i++ {
|
for i := 0; i < 3 && time.Now().Before(deadline); i++ {
|
||||||
resp := fasthttp.AcquireResponse()
|
resp := fasthttp.AcquireResponse()
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// A Fiber app (or any fasthttp stack) hands its handler straight in:
|
// A Fiber app (or any fasthttp stack) hands its handler straight in:
|
||||||
//
|
//
|
||||||
// srv := &zap.Server{Addr: ":9999", Handler: app.Handler()}
|
// srv := &http.Server{Addr: ":9999", Handler: app.Handler()}
|
||||||
// srv.ListenAndServe()
|
// srv.ListenAndServe()
|
||||||
//
|
//
|
||||||
// The server reads ZAP-HTTP frames off each accepted connection,
|
// The server reads ZAP-HTTP frames off each accepted connection,
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
// writes one response frame back from the ctx's Response. Connections are
|
// writes one response frame back from the ctx's Response. Connections are
|
||||||
// kept alive across requests. There is no net/http anywhere in the path.
|
// kept alive across requests. There is no net/http anywhere in the path.
|
||||||
|
|
||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -69,7 +69,7 @@ func (s *Server) ListenAndServe() error {
|
|||||||
// fails, because something is genuinely listening.
|
// fails, because something is genuinely listening.
|
||||||
if c, err := net.DialTimeout("unix", addr, 200*time.Millisecond); err == nil {
|
if c, err := net.DialTimeout("unix", addr, 200*time.Millisecond); err == nil {
|
||||||
_ = c.Close()
|
_ = c.Close()
|
||||||
return fmt.Errorf("zap: %s is already served by a live process", addr)
|
return fmt.Errorf("zaphttp: %s is already served by a live process", addr)
|
||||||
}
|
}
|
||||||
_ = os.Remove(addr)
|
_ = os.Remove(addr)
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ func (s *Server) Serve(ln net.Listener) error {
|
|||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
|
|
||||||
if s.Handler == nil {
|
if s.Handler == nil {
|
||||||
return errors.New("zap: Server.Handler is nil")
|
return errors.New("zaphttp: Server.Handler is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -136,7 +136,7 @@ func (s *Server) serveConn(conn net.Conn) {
|
|||||||
readBuf, err = readFrameInto(br, readBuf)
|
readBuf, err = readFrameInto(br, readBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, io.EOF) && !isClosedConn(err) {
|
if !errors.Is(err, io.EOF) && !isClosedConn(err) {
|
||||||
log.Printf("zap: read frame: %v", err)
|
log.Printf("zaphttp: read frame: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ func (s *Server) serveConn(conn net.Conn) {
|
|||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
ctx.Response.Reset()
|
ctx.Response.Reset()
|
||||||
ctx.Response.SetStatusCode(fasthttp.StatusInternalServerError)
|
ctx.Response.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
log.Printf("zap: handler panic on %s %s: %v",
|
log.Printf("zaphttp: handler panic on %s %s: %v",
|
||||||
ctx.Method(), ctx.RequestURI(), r)
|
ctx.Method(), ctx.RequestURI(), r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -179,7 +179,7 @@ func (s *Server) serveConn(conn net.Conn) {
|
|||||||
if ctx.Response.IsBodyStream() {
|
if ctx.Response.IsBodyStream() {
|
||||||
if err := s.streamResponse(conn, &ctx.Response); err != nil {
|
if err := s.streamResponse(conn, &ctx.Response); err != nil {
|
||||||
if !isClosedConn(err) {
|
if !isClosedConn(err) {
|
||||||
log.Printf("zap: stream response: %v", err)
|
log.Printf("zaphttp: stream response: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -191,12 +191,12 @@ func (s *Server) serveConn(conn net.Conn) {
|
|||||||
writeBuf = append(writeBuf[:0], 0, 0, 0, 0)
|
writeBuf = append(writeBuf[:0], 0, 0, 0, 0)
|
||||||
writeBuf, err = AppendResponse(writeBuf, &ctx.Response)
|
writeBuf, err = AppendResponse(writeBuf, &ctx.Response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("zap: marshal response: %v", err)
|
log.Printf("zaphttp: marshal response: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := writeFramePrefixed(conn, writeBuf); err != nil {
|
if err := writeFramePrefixed(conn, writeBuf); err != nil {
|
||||||
if !isClosedConn(err) {
|
if !isClosedConn(err) {
|
||||||
log.Printf("zap: write frame: %v", err)
|
log.Printf("zaphttp: write frame: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package zap_test
|
package http_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -34,7 +34,7 @@ func TestStream_SSEOverZAP(t *testing.T) {
|
|||||||
})
|
})
|
||||||
defer stop()
|
defer stop()
|
||||||
|
|
||||||
tr := zap.Dial("tcp", addr)
|
tr := http.Dial("tcp", addr)
|
||||||
defer tr.CloseIdleConnections()
|
defer tr.CloseIdleConnections()
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
resp := fasthttp.AcquireResponse()
|
resp := fasthttp.AcquireResponse()
|
||||||
|
|||||||
+8
-8
@@ -11,7 +11,7 @@
|
|||||||
// across exchanges (HTTP/1.1-style keep-alive); the transport itself
|
// across exchanges (HTTP/1.1-style keep-alive); the transport itself
|
||||||
// does not pipeline.
|
// does not pipeline.
|
||||||
|
|
||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -52,10 +52,10 @@ func readFrameInto(r *bufio.Reader, buf []byte) ([]byte, error) {
|
|||||||
return buf, err
|
return buf, err
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return buf, fmt.Errorf("zap: zero-length frame")
|
return buf, fmt.Errorf("zaphttp: zero-length frame")
|
||||||
}
|
}
|
||||||
if n > MaxFrameSize {
|
if n > MaxFrameSize {
|
||||||
return buf, fmt.Errorf("zap: frame size %d exceeds MaxFrameSize=%d", n, MaxFrameSize)
|
return buf, fmt.Errorf("zaphttp: frame size %d exceeds MaxFrameSize=%d", n, MaxFrameSize)
|
||||||
}
|
}
|
||||||
if uint32(cap(buf)) < n {
|
if uint32(cap(buf)) < n {
|
||||||
buf = make([]byte, n)
|
buf = make([]byte, n)
|
||||||
@@ -65,7 +65,7 @@ func readFrameInto(r *bufio.Reader, buf []byte) ([]byte, error) {
|
|||||||
// buf is already heap-backed (persistent across calls), so ReadFull's
|
// buf is already heap-backed (persistent across calls), so ReadFull's
|
||||||
// interface indirection costs no new allocation here.
|
// interface indirection costs no new allocation here.
|
||||||
if _, err := io.ReadFull(r, buf); err != nil {
|
if _, err := io.ReadFull(r, buf); err != nil {
|
||||||
return buf, fmt.Errorf("zap: short frame: %w", err)
|
return buf, fmt.Errorf("zaphttp: short frame: %w", err)
|
||||||
}
|
}
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
@@ -77,10 +77,10 @@ func readFrameInto(r *bufio.Reader, buf []byte) ([]byte, error) {
|
|||||||
func writeFramePrefixed(w io.Writer, framePlusPrefix []byte) error {
|
func writeFramePrefixed(w io.Writer, framePlusPrefix []byte) error {
|
||||||
body := len(framePlusPrefix) - 4
|
body := len(framePlusPrefix) - 4
|
||||||
if body <= 0 {
|
if body <= 0 {
|
||||||
return fmt.Errorf("zap: refusing to write zero-length frame")
|
return fmt.Errorf("zaphttp: refusing to write zero-length frame")
|
||||||
}
|
}
|
||||||
if uint64(body) > MaxFrameSize {
|
if uint64(body) > MaxFrameSize {
|
||||||
return fmt.Errorf("zap: frame size %d exceeds MaxFrameSize=%d", body, MaxFrameSize)
|
return fmt.Errorf("zaphttp: frame size %d exceeds MaxFrameSize=%d", body, MaxFrameSize)
|
||||||
}
|
}
|
||||||
binary.BigEndian.PutUint32(framePlusPrefix[0:4], uint32(body))
|
binary.BigEndian.PutUint32(framePlusPrefix[0:4], uint32(body))
|
||||||
_, err := w.Write(framePlusPrefix)
|
_, err := w.Write(framePlusPrefix)
|
||||||
@@ -90,10 +90,10 @@ func writeFramePrefixed(w io.Writer, framePlusPrefix []byte) error {
|
|||||||
// writeFrame writes one length-prefixed frame to w.
|
// writeFrame writes one length-prefixed frame to w.
|
||||||
func writeFrame(w io.Writer, frame []byte) error {
|
func writeFrame(w io.Writer, frame []byte) error {
|
||||||
if len(frame) == 0 {
|
if len(frame) == 0 {
|
||||||
return fmt.Errorf("zap: refusing to write zero-length frame")
|
return fmt.Errorf("zaphttp: refusing to write zero-length frame")
|
||||||
}
|
}
|
||||||
if uint64(len(frame)) > MaxFrameSize {
|
if uint64(len(frame)) > MaxFrameSize {
|
||||||
return fmt.Errorf("zap: frame size %d exceeds MaxFrameSize=%d", len(frame), MaxFrameSize)
|
return fmt.Errorf("zaphttp: frame size %d exceeds MaxFrameSize=%d", len(frame), MaxFrameSize)
|
||||||
}
|
}
|
||||||
var hdr [4]byte
|
var hdr [4]byte
|
||||||
binary.BigEndian.PutUint32(hdr[:], uint32(len(frame)))
|
binary.BigEndian.PutUint32(hdr[:], uint32(len(frame)))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Package zap implements HTTP request/response semantics over the
|
// Package zaphttp implements HTTP request/response semantics over the
|
||||||
// ZAP transport for the fasthttp handler model. A fasthttp.RequestHandler
|
// ZAP transport for the fasthttp handler model. A fasthttp.RequestHandler
|
||||||
// is served over ZAP frames; a fasthttp.Request/Response pair is exchanged
|
// is served over ZAP frames; a fasthttp.Request/Response pair is exchanged
|
||||||
// by the client. There is no net/http in the request path — Fiber and
|
// by the client. There is no net/http in the request path — Fiber and
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
// repeated pair, which covers multi-value headers (RFC 9110 §5.2) without
|
// repeated pair, which covers multi-value headers (RFC 9110 §5.2) without
|
||||||
// modelling a list.
|
// modelling a list.
|
||||||
|
|
||||||
package zap
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
@@ -166,10 +166,10 @@ func UnmarshalRequest(frame []byte, dst *fasthttp.Request) error {
|
|||||||
dst.Header.SetProtocolBytes(proto)
|
dst.Header.SetProtocolBytes(proto)
|
||||||
}
|
}
|
||||||
if err := decodeRequestHeaders(&dst.Header, headers); err != nil {
|
if err := decodeRequestHeaders(&dst.Header, headers); err != nil {
|
||||||
return fmt.Errorf("zap: decode headers: %w", err)
|
return fmt.Errorf("zaphttp: decode headers: %w", err)
|
||||||
}
|
}
|
||||||
if err := applyTrailers(&dst.Header, trailer); err != nil {
|
if err := applyTrailers(&dst.Header, trailer); err != nil {
|
||||||
return fmt.Errorf("zap: decode trailer: %w", err)
|
return fmt.Errorf("zaphttp: decode trailer: %w", err)
|
||||||
}
|
}
|
||||||
dst.SetBody(body)
|
dst.SetBody(body)
|
||||||
return nil
|
return nil
|
||||||
@@ -197,10 +197,10 @@ func UnmarshalResponse(frame []byte, dst *fasthttp.Response) error {
|
|||||||
dst.Header.SetProtocol(proto)
|
dst.Header.SetProtocol(proto)
|
||||||
}
|
}
|
||||||
if err := decodeResponseHeaders(&dst.Header, headers); err != nil {
|
if err := decodeResponseHeaders(&dst.Header, headers); err != nil {
|
||||||
return fmt.Errorf("zap: decode headers: %w", err)
|
return fmt.Errorf("zaphttp: decode headers: %w", err)
|
||||||
}
|
}
|
||||||
if err := applyTrailers(&dst.Header, trailer); err != nil {
|
if err := applyTrailers(&dst.Header, trailer); err != nil {
|
||||||
return fmt.Errorf("zap: decode trailer: %w", err)
|
return fmt.Errorf("zaphttp: decode trailer: %w", err)
|
||||||
}
|
}
|
||||||
dst.SetBody(body)
|
dst.SetBody(body)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user