From 50791c9ca06a5f21a5ddbe212e27538399816762 Mon Sep 17 00:00:00 2001 From: Ken2mer Date: Sun, 28 Feb 2021 18:16:25 +0900 Subject: [PATCH] net.Listen, net.Accept HTTPServer inspired by https://ascii.jp/elem/000/001/276/1276572/ --- net/listen.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++ net/listen_test.go | 41 ++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 net/listen.go create mode 100644 net/listen_test.go diff --git a/net/listen.go b/net/listen.go new file mode 100644 index 0000000..201de86 --- /dev/null +++ b/net/listen.go @@ -0,0 +1,66 @@ +package net + +import ( + "bufio" + "fmt" + "io" + "net" + "net/http" + "net/http/httputil" + "os" + "os/signal" + "strings" +) + +// HTTPServer inspired by https://ascii.jp/elem/000/001/276/1276572/ +func HTTPServer(port string) error { + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + + ln, err := net.Listen("tcp", "localhost:"+port) + if err != nil { + return err + } + + go func() { + s := <-c + fmt.Println("Got signal:", s) + ln.Close() + }() + + fmt.Println("Server is running at localhost:" + port) + + for { + conn, err := ln.Accept() + if err != nil { + return err + } + go func() { + fmt.Printf("Accept %v\n", conn.RemoteAddr()) + + // リクエストを読み込む + request, err := http.ReadRequest(bufio.NewReader(conn)) + if err != nil { + fmt.Println(err) + return + } + dump, err := httputil.DumpRequest(request, true) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(dump)) + + // レスポンスを書き込む + response := http.Response{ + StatusCode: 200, + ProtoMajor: 1, + ProtoMinor: 0, + Body: io.NopCloser(strings.NewReader("Hello World\n")), + } + response.Write(conn) + + conn.Close() + }() + } +} diff --git a/net/listen_test.go b/net/listen_test.go new file mode 100644 index 0000000..33fdb48 --- /dev/null +++ b/net/listen_test.go @@ -0,0 +1,41 @@ +package net + +import ( + "fmt" + "io" + "net/http" + "syscall" + "testing" + "time" +) + +func TestHTTPServer(t *testing.T) { + port := "8080" + errCh := make(chan error) + go func() { + errCh <- HTTPServer(port) + }() + time.Sleep(time.Second * 1) + + resp, err := http.Get("http://localhost:" + port) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + + status := resp.StatusCode + body, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + + if status != 200 { + t.Fatalf("expected: 200, got: %d", resp.StatusCode) + } + if string(body) != "Hello World\n" { + t.Fatalf("expected: Hello World\n, got: %s", body) + } + + syscall.Kill(syscall.Getpid(), syscall.SIGINT) + fmt.Println(<-errCh) +}