Initial commit
This commit is contained in:
145
cmd/httpserver/main.go
Normal file
145
cmd/httpserver/main.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"httpfromtcp/internal/headers"
|
||||
"httpfromtcp/internal/server"
|
||||
"httpfromtcp/internal/request"
|
||||
"httpfromtcp/internal/response"
|
||||
)
|
||||
|
||||
const port = 42069
|
||||
|
||||
func respond200() []byte{
|
||||
return []byte(`
|
||||
<html>
|
||||
<head>
|
||||
<title>200 OK</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Success!</h1>
|
||||
<p>Your request was an absolute banger.</p>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
func respond400() []byte{
|
||||
return []byte(`
|
||||
<html>
|
||||
<head>
|
||||
<title>400 Bad Request</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Bad Request</h1>
|
||||
<p>Your request honestly kinda sucked.</p>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
func respond500() []byte{
|
||||
return []byte(`
|
||||
<html>
|
||||
<head>
|
||||
<title>500 Internal Server Error</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Internal Server Error</h1>
|
||||
<p>Okay, you know what? This one is on me.</p>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
func toStr(bytes []byte) string{
|
||||
out := ""
|
||||
for _,b := range bytes {
|
||||
out += fmt.Sprintf("%02x",b)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func main() {
|
||||
s, err := server.Serve(port, func(w *response.Writer, req *request.Request){
|
||||
h := response.GetDefaultHeaders(0)
|
||||
body := respond200()
|
||||
status := response.StatusOK
|
||||
|
||||
if req.RequestLine.RequestTarget == "/yourproblem"{
|
||||
body = respond400()
|
||||
status = response.StatusBadRequest
|
||||
}else if req.RequestLine.RequestTarget == "/myproblem"{
|
||||
body = respond500()
|
||||
status = response.StatusInternalServerError
|
||||
}else if req.RequestLine.RequestTarget == "/video"{
|
||||
f, _ := os.ReadFile("assets/vim.mp4")
|
||||
h.Replace("content-type","video/mp4")
|
||||
h.Replace("content-length", fmt.Sprintf("%d",len(f)))
|
||||
w.WriteStatusLine(response.StatusOK)
|
||||
w.WriteHeaders(*h)
|
||||
w.WriteBody(f)
|
||||
}else if strings.HasPrefix(req.RequestLine.RequestTarget, "/httpbin/"){
|
||||
target := req.RequestLine.RequestTarget
|
||||
|
||||
res,err := http.Get("https://httpbin.org/" +target[len("/httpbin/"):])
|
||||
if err != nil{
|
||||
body = respond500()
|
||||
status = response.StatusInternalServerError
|
||||
}else {
|
||||
w.WriteStatusLine(response.StatusOK)
|
||||
h.Delete("Content-length")
|
||||
h.Set("Transfer-Encoding","chunked")
|
||||
h.Replace("Content-Type","text/plain")
|
||||
h.Set("Trailer","X-Content-SHA256")
|
||||
h.Set("Trailer","X-Content-Length")
|
||||
w.WriteHeaders(*h)
|
||||
|
||||
fullBody := []byte{}
|
||||
for {
|
||||
data := make([]byte,32)
|
||||
n,err := res.Body.Read(data)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
fullBody = append(fullBody, data[:n]...)
|
||||
w.WriteBody([]byte(fmt.Sprintf("%x\r\n",n)))
|
||||
w.WriteBody(data[:n])
|
||||
w.WriteBody([]byte("\r\n"))
|
||||
}
|
||||
w.WriteBody([]byte("0\r\n"))
|
||||
trailers := headers.NewHeaders()
|
||||
out := sha256.Sum256(fullBody)
|
||||
trailers.Set("X-Content-SHA256",toStr(out[:]))
|
||||
trailers.Set("X-Content-Length",fmt.Sprintf("%d",len(fullBody)))
|
||||
w.WriteHeaders(*trailers)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
h.Replace("Content-length",fmt.Sprintf("%d",len(body)))
|
||||
h.Replace("Content-Type","text/html")
|
||||
w.WriteStatusLine(status)
|
||||
w.WriteHeaders(*h)
|
||||
w.WriteBody(body)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Error starting server: %v", err)
|
||||
}
|
||||
defer s.Close()
|
||||
log.Println("Server started on port", port)
|
||||
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigChan
|
||||
log.Println("Server gracefully stopped")
|
||||
}
|
||||
41
cmd/tcplistener/main.go
Normal file
41
cmd/tcplistener/main.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"httpfromtcp/internal/request"
|
||||
)
|
||||
|
||||
func main() {
|
||||
listener, err := net.Listen("tcp", ":42069")
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't open messages.txt:", err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Fatal("error", "error", err)
|
||||
}
|
||||
|
||||
r, err := request.RequestFromReader(conn)
|
||||
if err != nil {
|
||||
log.Fatal("error", "error", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Request line: \n")
|
||||
fmt.Printf("- Method: %s\n", r.RequestLine.Method)
|
||||
fmt.Printf("- Target: %s\n", r.RequestLine.RequestTarget)
|
||||
fmt.Printf("- Version: %s\n", r.RequestLine.HttpVersion)
|
||||
|
||||
fmt.Printf("Headers:\n")
|
||||
r.Headers.ForEach(func(n, v string) {
|
||||
fmt.Printf("- %s: %s\n", n, v)
|
||||
})
|
||||
fmt.Printf("Body:\n")
|
||||
fmt.Printf("%s\n", r.Body)
|
||||
}
|
||||
}
|
||||
63
cmd/udpsender/main.go
Normal file
63
cmd/udpsender/main.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package udpsender
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func getLinesChannel(f io.ReadCloser) <-chan string {
|
||||
out := make(chan string, 1)
|
||||
|
||||
go func() {
|
||||
defer f.Close()
|
||||
defer close(out)
|
||||
|
||||
str := ""
|
||||
for {
|
||||
data := make([]byte, 8)
|
||||
n, err := f.Read(data)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("error reading file:", err)
|
||||
return
|
||||
}
|
||||
data = data[:n]
|
||||
if i := bytes.IndexByte(data, '\n'); i != -1 {
|
||||
str += string(data[:i])
|
||||
data = data[i+1:]
|
||||
out <- str
|
||||
str = ""
|
||||
}
|
||||
str += string(data)
|
||||
}
|
||||
if len(str) != 0 {
|
||||
out <- str
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
//for line := range getLinesChannel(conn){
|
||||
// fmt.Printf("read: %s\n",line)
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// var body []byte = nil
|
||||
// var status response.StatusCode = response.StatusOK
|
||||
|
||||
// if handlerError != nil{
|
||||
// status = handlerError.StatusCode
|
||||
// body = []byte(handlerError.Message)
|
||||
// }else{
|
||||
// body = writer.Bytes()
|
||||
// }
|
||||
|
||||
// headers.Replace("Content-Length", fmt.Sprintf("%d", len(body)))
|
||||
// response.WriteStatusLine(conn,status)
|
||||
// response.WriteHeaders(conn,headers)
|
||||
// conn.Write(body)
|
||||
Reference in New Issue
Block a user