Added request headers

This commit is contained in:
2024-03-27 22:12:16 +01:00
parent b6c208c75b
commit c3bb8336a3
6 changed files with 131 additions and 65 deletions

124
Server.go
View File

@ -121,36 +121,77 @@ func (s *server) handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
var (
ctx *context
method string
url string
)
for {
message, err := reader.ReadString('\n')
// Search for a line containing HTTP method and url
for {
message, err := reader.ReadString('\n')
if err != nil {
return
if err != nil {
return
}
space := strings.IndexByte(message, ' ')
if space <= 0 {
continue
}
method = message[:space]
if method != "GET" {
continue
}
lastSpace := strings.LastIndexByte(message, ' ')
if lastSpace == -1 {
lastSpace = len(message)
}
ctx = s.pool.Get().(*context)
url = message[space+1 : lastSpace]
break
}
space := strings.IndexByte(message, ' ')
// Add headers until we meet an empty line
for {
message, err := reader.ReadString('\n')
if space <= 0 {
continue
if err != nil {
return
}
if message == "\r\n" {
break
}
colon := strings.IndexByte(message, ':')
if colon <= 0 {
continue
}
key := message[:colon]
value := message[colon+2 : len(message)-2]
ctx.request.headers = append(ctx.request.headers, header{
Key: key,
Value: value,
})
}
method := message[:space]
if method != "GET" {
continue
}
lastSpace := strings.LastIndexByte(message, ' ')
if lastSpace == -1 {
lastSpace = len(message)
}
url := message[space+1 : lastSpace]
ctx := s.pool.Get().(*context)
// Handle the request
s.handleRequest(ctx, method, url, conn)
ctx.body = ctx.body[:0]
ctx.request.headers = ctx.request.headers[:0]
ctx.request.body = ctx.request.body[:0]
ctx.response.headers = ctx.response.headers[:0]
ctx.response.body = ctx.response.body[:0]
ctx.params = ctx.params[:0]
ctx.handlerCount = 0
ctx.status = 200
@ -169,7 +210,7 @@ func (s *server) handleRequest(ctx *context, method string, url string, writer i
s.errorHandler(ctx, err)
}
fmt.Fprintf(writer, "HTTP/1.1 %d %s\r\nContent-Length: %d\r\n%s\r\n%s", ctx.status, "OK", len(ctx.body), ctx.response.headerText(), ctx.body)
fmt.Fprintf(writer, "HTTP/1.1 %d %s\r\nContent-Length: %d\r\n%s\r\n%s", ctx.status, "OK", len(ctx.response.body), ctx.response.headerText(), ctx.response.body)
}
// newContext allocates a new context with the default state.
@ -177,39 +218,14 @@ func (s *server) newContext() *context {
return &context{
server: s,
request: request{
params: make([]router.Parameter, 0, 8),
body: make([]byte, 0),
headers: make([]header, 0, 8),
params: make([]router.Parameter, 0, 8),
},
response: response{
body: make([]byte, 0, 1024),
status: 200,
body: make([]byte, 0, 1024),
headers: make([]header, 0, 8),
status: 200,
},
}
}
// parseURL parses a URL and returns the scheme, host, path and query.
func parseURL(url string) (scheme string, host string, path string, query string) {
schemePos := strings.Index(url, "://")
if schemePos != -1 {
scheme = url[:schemePos]
url = url[schemePos+len("://"):]
}
pathPos := strings.IndexByte(url, '/')
if pathPos != -1 {
host = url[:pathPos]
url = url[pathPos:]
}
queryPos := strings.IndexByte(url, '?')
if queryPos != -1 {
path = url[:queryPos]
query = url[queryPos+1:]
return
}
path = url
return
}