Implemented io.Reader for requests
All checks were successful
/ test (push) Successful in 18s

This commit is contained in:
Eduard Urbach 2025-06-12 17:44:28 +02:00
parent 0442fc1e2e
commit 9a781d2e64
Signed by: eduard
GPG key ID: 49226B848C78F6C8
4 changed files with 28 additions and 9 deletions

View file

@ -2,12 +2,14 @@ package web
import ( import (
"bufio" "bufio"
"io"
"git.urbach.dev/go/router" "git.urbach.dev/go/router"
) )
// Request is an interface for HTTP requests. // Request is an interface for HTTP requests.
type Request interface { type Request interface {
io.Reader
Header(string) string Header(string) string
Host() string Host() string
Method() string Method() string
@ -18,14 +20,13 @@ type Request interface {
// request represents the HTTP request used in the given context. // request represents the HTTP request used in the given context.
type request struct { type request struct {
reader *bufio.Reader bufio.Reader
scheme string scheme string
host string host string
method string method string
path string path string
query string query string
headers []Header headers []Header
body []byte
params []router.Parameter params []router.Parameter
} }

View file

@ -2,6 +2,7 @@ package web_test
import ( import (
"fmt" "fmt"
"strings"
"testing" "testing"
"git.urbach.dev/go/assert" "git.urbach.dev/go/assert"
@ -25,6 +26,25 @@ func TestRequest(t *testing.T) {
assert.Equal(t, string(response.Body()), "GET http example.com /request") assert.Equal(t, string(response.Body()), "GET http example.com /request")
} }
func TestRequestBody(t *testing.T) {
s := web.NewServer()
s.Get("/", func(ctx web.Context) error {
body := make([]byte, 4096)
n, err := ctx.Request().Read(body)
if err != nil {
return err
}
return ctx.Bytes(body[:n])
})
response := s.Request("GET", "/", nil, strings.NewReader("Hello"))
assert.Equal(t, response.Status(), 200)
assert.Equal(t, string(response.Body()), "Hello")
}
func TestRequestHeader(t *testing.T) { func TestRequestHeader(t *testing.T) {
s := web.NewServer() s := web.NewServer()

View file

@ -1,7 +1,6 @@
package web package web
import ( import (
"bufio"
"bytes" "bytes"
"io" "io"
"log" "log"
@ -79,6 +78,7 @@ func (s *server) Ready() chan struct{} {
func (s *server) Request(method string, url string, headers []Header, body io.Reader) Response { func (s *server) Request(method string, url string, headers []Header, body io.Reader) Response {
ctx := s.newContext() ctx := s.newContext()
ctx.request.headers = headers ctx.request.headers = headers
ctx.request.Reader.Reset(body)
s.handleRequest(ctx, method, url, io.Discard) s.handleRequest(ctx, method, url, io.Discard)
return ctx.Response() return ctx.Response()
} }
@ -133,14 +133,14 @@ func (s *server) handleConnection(conn net.Conn) {
close bool close bool
) )
ctx.reader.Reset(conn) ctx.Reader.Reset(conn)
defer conn.Close() defer conn.Close()
defer s.contextPool.Put(ctx) defer s.contextPool.Put(ctx)
for !close { for !close {
// Read the HTTP request line // Read the HTTP request line
message, err := ctx.reader.ReadString('\n') message, err := ctx.Reader.ReadString('\n')
if err != nil { if err != nil {
return return
@ -177,7 +177,7 @@ func (s *server) handleConnection(conn net.Conn) {
// Add headers until we meet an empty line // Add headers until we meet an empty line
for { for {
message, err = ctx.reader.ReadString('\n') message, err = ctx.Reader.ReadString('\n')
if err != nil { if err != nil {
return return
@ -215,7 +215,6 @@ func (s *server) handleConnection(conn net.Conn) {
// Clean up the context // Clean up the context
ctx.request.headers = ctx.request.headers[:0] ctx.request.headers = ctx.request.headers[:0]
ctx.request.body = ctx.request.body[:0]
ctx.response.headers = ctx.response.headers[:0] ctx.response.headers = ctx.response.headers[:0]
ctx.response.body = ctx.response.body[:0] ctx.response.body = ctx.response.body[:0]
ctx.params = ctx.params[:0] ctx.params = ctx.params[:0]
@ -259,8 +258,6 @@ func (s *server) newContext() *context {
return &context{ return &context{
server: s, server: s,
request: request{ request: request{
reader: bufio.NewReader(nil),
body: make([]byte, 0),
headers: make([]Header, 0, 8), headers: make([]Header, 0, 8),
params: make([]router.Parameter, 0, 8), params: make([]router.Parameter, 0, 8),
}, },

View file

@ -57,6 +57,7 @@ PASS: TestError
PASS: TestErrorMultiple PASS: TestErrorMultiple
PASS: TestRedirect PASS: TestRedirect
PASS: TestRequest PASS: TestRequest
PASS: TestRequestBody
PASS: TestRequestHeader PASS: TestRequestHeader
PASS: TestRequestParam PASS: TestRequestParam
PASS: TestWrite PASS: TestWrite