mirror of
https://github.com/cupcakearmy/codecrafters-http-server-go.git
synced 2024-12-22 08:06:27 +00:00
cleanup
This commit is contained in:
parent
899f7828a5
commit
de8a68ac05
@ -5,7 +5,7 @@ import (
|
||||
"compress/gzip"
|
||||
)
|
||||
|
||||
func gzipCompress(data []byte) *bytes.Buffer {
|
||||
func gzipCompress(data []byte) []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
gz := gzip.NewWriter(buf)
|
||||
if _, err := gz.Write(data); err != nil {
|
||||
@ -14,7 +14,5 @@ func gzipCompress(data []byte) *bytes.Buffer {
|
||||
if err := gz.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// fmt.Println("Hexadecimal Representation:", hex.EncodeToString(buf.Bytes()))
|
||||
return buf
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
var DIR string = ""
|
||||
|
||||
func getFilepath(filename string) string {
|
||||
// Set the DIR if not already set
|
||||
if DIR == "" {
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
log.Fatal("Not enough args")
|
||||
}
|
||||
|
34
app/http.go
34
app/http.go
@ -13,10 +13,6 @@ const (
|
||||
HTTPDelimiter = "\r\n"
|
||||
)
|
||||
|
||||
// type Header struct {
|
||||
// Name string
|
||||
// Value string
|
||||
// }
|
||||
type Request struct {
|
||||
Method string
|
||||
Path string
|
||||
@ -64,37 +60,44 @@ type Routes struct {
|
||||
}
|
||||
|
||||
func Respond(conn net.Conn, req Request, res Response) {
|
||||
// Create headers if not existent
|
||||
if res.Headers == nil {
|
||||
res.Headers = make(map[string]string)
|
||||
}
|
||||
|
||||
// isGzip := false
|
||||
isGzip := strings.Contains(req.Headers["Accept-Encoding"], "gzip")
|
||||
// if isGzip {
|
||||
// res.Headers["Content-Encoding"] = "gzip"
|
||||
// }
|
||||
|
||||
// Base response line
|
||||
fmt.Fprintf(conn, "%s %d %s%s", res.Version, res.Code.Code, res.Code.Message, HTTPDelimiter)
|
||||
|
||||
var body []byte
|
||||
if res.Body != "" {
|
||||
body = []byte(res.Body)
|
||||
} else {
|
||||
body = res.BodyRaw
|
||||
}
|
||||
if isGzip && len(body) > 0 {
|
||||
res.Headers["Content-Encoding"] = "gzip"
|
||||
body = gzipCompress(body).Bytes()
|
||||
}
|
||||
bodySize := len(body)
|
||||
|
||||
// Check if gzip is accepted and encode the body
|
||||
isGzip := strings.Contains(req.Headers["Accept-Encoding"], "gzip")
|
||||
if isGzip && bodySize > 0 {
|
||||
body = gzipCompress(body)
|
||||
bodySize = len(body)
|
||||
res.Headers["Content-Encoding"] = "gzip"
|
||||
}
|
||||
|
||||
// Set the size of the content
|
||||
if bodySize > 0 {
|
||||
res.Headers["Content-Length"] = strconv.Itoa(bodySize)
|
||||
}
|
||||
|
||||
// Write headers
|
||||
for header, value := range res.Headers {
|
||||
fmt.Fprintf(conn, "%s: %s%s", header, value, HTTPDelimiter)
|
||||
}
|
||||
|
||||
// Delimiter for the body, always present
|
||||
fmt.Fprint(conn, HTTPDelimiter)
|
||||
|
||||
// Write body if available
|
||||
if bodySize > 0 {
|
||||
conn.Write(body)
|
||||
}
|
||||
@ -112,6 +115,7 @@ func parseRequest(conn net.Conn) (Request, bool) {
|
||||
request := Request{Headers: map[string]string{}}
|
||||
isBody := false
|
||||
for i, part := range parts {
|
||||
// The first part is always the basic information
|
||||
if i == 0 {
|
||||
head := strings.Split(part, " ")
|
||||
if len(head) != 3 {
|
||||
@ -123,6 +127,7 @@ func parseRequest(conn net.Conn) (Request, bool) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Body
|
||||
if isBody {
|
||||
request.Body = part
|
||||
break
|
||||
@ -130,6 +135,7 @@ func parseRequest(conn net.Conn) (Request, bool) {
|
||||
|
||||
// Headers
|
||||
if part == "" {
|
||||
// If the header is "empty" it means that we have arrived at the body, and we'll skip to it
|
||||
isBody = true
|
||||
continue
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ var routes = Routes{
|
||||
},
|
||||
},
|
||||
|
||||
// Read file
|
||||
{
|
||||
regex: regexp.MustCompile(`^/files/([A-Za-z0-9_\-.]+)`),
|
||||
method: "GET",
|
||||
@ -60,6 +61,7 @@ var routes = Routes{
|
||||
},
|
||||
},
|
||||
|
||||
// Write file
|
||||
{
|
||||
regex: regexp.MustCompile(`^/files/([A-Za-z0-9_\-.]+)`),
|
||||
method: "POST",
|
||||
|
@ -6,17 +6,6 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// type Handler = func(req Request, res Response)
|
||||
// type Middleware = func(next Handler) Handler
|
||||
|
||||
// var m Middleware = func(next Handler) Handler {
|
||||
// return func(req Request, res Response) {
|
||||
// fmt.Println("Start")
|
||||
// next(req, res)
|
||||
// fmt.Println("End")
|
||||
// }
|
||||
// }
|
||||
|
||||
func handleConnection(conn net.Conn, routes Routes) {
|
||||
defer conn.Close()
|
||||
|
||||
@ -28,6 +17,7 @@ func handleConnection(conn net.Conn, routes Routes) {
|
||||
|
||||
fmt.Println(req)
|
||||
|
||||
// Loop over the available routes. First string, then regexp
|
||||
for _, route := range routes.stringRoutes {
|
||||
if req.Path == route.path && req.Method == route.method {
|
||||
Respond(conn, req, route.handler(req))
|
||||
@ -45,12 +35,11 @@ func handleConnection(conn net.Conn, routes Routes) {
|
||||
}
|
||||
}
|
||||
|
||||
// Catch all 404
|
||||
Respond(conn, req, Response{Version: req.Version, Code: NotFound})
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Logs from your program will appear here!")
|
||||
|
||||
l, err := net.Listen("tcp", "0.0.0.0:4221")
|
||||
if err != nil {
|
||||
fmt.Println("Failed to bind to port 4221")
|
||||
|
@ -38,8 +38,11 @@ func checkResponse(t *testing.T, res *http.Response, expected Expected) {
|
||||
t.Errorf(`Expected body to be "%s" but got "%s"`, expected.body, body)
|
||||
}
|
||||
|
||||
log.Println("HEADERS", res.Header)
|
||||
for header, value := range expected.headers {
|
||||
if actual := res.Header[header][0]; actual != value {
|
||||
if res.Header[header] == nil {
|
||||
t.Errorf(`Expected "%s" header to be present`, header)
|
||||
} else if actual := res.Header[header][0]; actual != value {
|
||||
t.Errorf(`Expected "%s" header to be "%s" but got "%s"`, header, value, actual)
|
||||
}
|
||||
}
|
||||
@ -64,23 +67,24 @@ func TestEcho(t *testing.T) {
|
||||
}})
|
||||
}
|
||||
|
||||
// func TestEchoGzip(t *testing.T) {
|
||||
// input := "abc"
|
||||
// req, _ := http.NewRequest("GET", fmt.Sprintf("http://localhost:4221/echo/%s", input), nil)
|
||||
// req.Header.Set("Accept-Encoding", "gzip")
|
||||
// client := &http.Client{}
|
||||
// res, _ := client.Do(req)
|
||||
func TestEchoGzip(t *testing.T) {
|
||||
input := "abc"
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("http://localhost:4221/echo/%s", input), nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
client := &http.Client{}
|
||||
res, _ := client.Do(req)
|
||||
|
||||
// checkResponse(t, res, Expected{status: 200, body: input, headers: map[string]string{
|
||||
// "Content-Length": strconv.Itoa(len(input)),
|
||||
// "Content-Type": "text/plain",
|
||||
// "Content-Encoding": "gzip",
|
||||
// }})
|
||||
// }
|
||||
checkResponse(t, res, Expected{status: 200, body: input, headers: map[string]string{
|
||||
"Content-Length": "27", // Size of gzip "abc"
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Encoding": "gzip",
|
||||
}})
|
||||
}
|
||||
|
||||
func TestUserAgent(t *testing.T) {
|
||||
input := "CodeCrafters/1.0"
|
||||
req, _ := http.NewRequest("GET", "http://localhost:4221/user-agent", nil)
|
||||
req.Header.Del("")
|
||||
req.Header.Set("User-Agent", input)
|
||||
client := &http.Client{}
|
||||
res, _ := client.Do(req)
|
||||
|
Loading…
Reference in New Issue
Block a user