From bb4f4cb4daba39c4cf39db7fc992351d3f2d672a Mon Sep 17 00:00:00 2001 From: tkc <181991+tkc@users.noreply.github.com> Date: Sat, 7 Mar 2020 20:35:53 +0900 Subject: [PATCH 1/3] Impl --- api.json | 21 +++++++++++++++++++++ example/api.json | 3 +-- go-json-server.go | 36 +++++++++++++++++++++++++----------- log.csv | 6 ++++++ user.json | 5 +++++ users.json | 6 ++++++ 6 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 api.json create mode 100644 log.csv create mode 100644 user.json create mode 100644 users.json diff --git a/api.json b/api.json new file mode 100644 index 0000000..b97d1e7 --- /dev/null +++ b/api.json @@ -0,0 +1,21 @@ +{ + "port": 3000, + "endpoints": [ + { + "method": "GET", + "status": 200, + "path": "/users", + "jsonPath": "./users.json" + }, + { + "method": "GET", + "status": 200, + "path": "/user/1", + "jsonPath": "./user.json" + }, + { + "path": "/file", + "folder": "./static" + } + ] +} \ No newline at end of file diff --git a/example/api.json b/example/api.json index 6cd00c8..b97d1e7 100644 --- a/example/api.json +++ b/example/api.json @@ -18,5 +18,4 @@ "folder": "./static" } ] -} - +} \ No newline at end of file diff --git a/go-json-server.go b/go-json-server.go index 48bff93..0230dcc 100644 --- a/go-json-server.go +++ b/go-json-server.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "encoding/csv" "encoding/json" "fmt" "io/ioutil" @@ -78,7 +79,6 @@ const ( HeaderXCSRFToken = "X-CSRF-Token" ) - type Endpoint struct { Type string `json:"type"` Method string `json:"method"` @@ -97,7 +97,6 @@ type API struct { var api API func main() { - raw, err := ioutil.ReadFile("./api.json") if err != nil { fmt.Println(err.Error()) @@ -114,31 +113,34 @@ func main() { if len(ep.Folder) > 0 { http.Handle(ep.Path+"/", http.StripPrefix(ep.Path+"/", http.FileServer(http.Dir(ep.Folder)))) } else { - http.HandleFunc(ep.Path, Response) + http.HandleFunc(ep.Path, response) } } err = http.ListenAndServe(":"+strconv.Itoa(api.Port), nil) + if err != nil { log.Fatal(" ", err) } } -func Response(w http.ResponseWriter, r *http.Request) { - - w.Header().Set( "Access-Control-Allow-Origin", "*" ) - w.Header().Set( "Access-Control-Allow-Credentials", "true" ) - w.Header().Set( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization" ) - w.Header().Set( "Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS" ) +func response(w http.ResponseWriter, r *http.Request) { r.ParseForm() + accessLog(r) + + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Credentials", "true") + w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + for _, ep := range api.Endpoints { if r.URL.Path == ep.Path && r.Method == ep.Method { fmt.Println("method:", r.Method) fmt.Println("path:", r.URL.Path) w.Header().Set(HeaderContentType, MIMETextPlainCharsetUTF8) w.WriteHeader(ep.Status) - s := Path2Response(ep.JsonPath) + s := path2Response(ep.JsonPath) b := []byte(s) w.Write(b) } @@ -146,7 +148,7 @@ func Response(w http.ResponseWriter, r *http.Request) { } } -func Path2Response(path string) string { +func path2Response(path string) string { file, err := os.Open(path) if err != nil { log.Print(err) @@ -157,3 +159,15 @@ func Path2Response(path string) string { buf.ReadFrom(file) return buf.String() } + +func accessLog(r *http.Request) { + file, err := os.OpenFile("log.csv", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Fatal(err) + } + defer file.Close() + s := []string{r.Method, r.Host, r.Proto, r.RequestURI, r.RemoteAddr} + writer := csv.NewWriter(file) + writer.Write(s) + writer.Flush() +} diff --git a/log.csv b/log.csv new file mode 100644 index 0000000..9951e6e --- /dev/null +++ b/log.csv @@ -0,0 +1,6 @@ +GET,localhost:3000,HTTP/1.1,/users,[::1]:56235,/users +GET,localhost:3000,HTTP/1.1,/users,[::1]:56259,/users +GET,localhost:3000,HTTP/1.1,/users,[::1]:56302 +GET,localhost:3000,HTTP/1.1,/users,[::1]:56302 +GET,localhost:3000,HTTP/1.1,/users,[::1]:56302 +GET,localhost:3000,HTTP/1.1,/user/1,[::1]:56302 diff --git a/user.json b/user.json new file mode 100644 index 0000000..ac41079 --- /dev/null +++ b/user.json @@ -0,0 +1,5 @@ +{ + "id": 1, + "name": "name", + "address": "address" +} \ No newline at end of file diff --git a/users.json b/users.json new file mode 100644 index 0000000..402f394 --- /dev/null +++ b/users.json @@ -0,0 +1,6 @@ +[ + { + "id": 1, + "name": "name" + } +] \ No newline at end of file From f75042d832b50eaebe7f3afca1fdbffa08e11306 Mon Sep 17 00:00:00 2001 From: tkc <181991+tkc@users.noreply.github.com> Date: Mon, 9 Mar 2020 00:58:58 +0900 Subject: [PATCH 2/3] Add logger --- example/health-check.json | 0 go-json-server.go | 17 ++------ go.mod | 8 ++++ go.sum | 14 +++++++ src/logger/logger.go | 87 +++++++++++++++++++++++++++++++++++++++ src/logger/logger_test.go | 26 ++++++++++++ test/main.go | 49 ++++++++++++++++++++++ 7 files changed, 187 insertions(+), 14 deletions(-) create mode 100644 example/health-check.json create mode 100644 go.mod create mode 100644 go.sum create mode 100644 src/logger/logger.go create mode 100644 src/logger/logger_test.go create mode 100644 test/main.go diff --git a/example/health-check.json b/example/health-check.json new file mode 100644 index 0000000..e69de29 diff --git a/go-json-server.go b/go-json-server.go index 0230dcc..c347283 100644 --- a/go-json-server.go +++ b/go-json-server.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "encoding/csv" "encoding/json" "fmt" "io/ioutil" @@ -10,6 +9,8 @@ import ( "net/http" "os" "strconv" + + "github.com/tkc/go-json-server/src/logger" ) const ( @@ -127,7 +128,7 @@ func main() { func response(w http.ResponseWriter, r *http.Request) { r.ParseForm() - accessLog(r) + logger.AccessLog(r) w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Credentials", "true") @@ -159,15 +160,3 @@ func path2Response(path string) string { buf.ReadFrom(file) return buf.String() } - -func accessLog(r *http.Request) { - file, err := os.OpenFile("log.csv", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - log.Fatal(err) - } - defer file.Close() - s := []string{r.Method, r.Host, r.Proto, r.RequestURI, r.RemoteAddr} - writer := csv.NewWriter(file) - writer.Write(s) - writer.Flush() -} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..408d4e3 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/tkc/go-json-server + +go 1.13 + +require ( + github.com/spf13/cast v1.3.1 + github.com/stretchr/testify v1.5.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fbc6894 --- /dev/null +++ b/go.sum @@ -0,0 +1,14 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/src/logger/logger.go b/src/logger/logger.go new file mode 100644 index 0000000..4fad359 --- /dev/null +++ b/src/logger/logger.go @@ -0,0 +1,87 @@ +package logger + +import ( + "encoding/csv" + "encoding/json" + "fmt" + "io" + "log" + stdlog "log" + "net/http" + "os" + "strconv" +) + +type stdLogger struct { + stderr *stdlog.Logger + stdout *stdlog.Logger +} + +func CreateLogger() *stdLogger { + return &stdLogger{ + stdout: stdlog.New(os.Stdout, "", 0), + stderr: stdlog.New(os.Stderr, "", 0), + } +} + +func (l *stdLogger) AccessLog(r *http.Request) { + file, err := os.OpenFile("log.csv", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Fatal(err) + } + + defer file.Close() + + jsonBody := dumpJsonBoddy(r) + + s := []string{r.Method, r.Host, r.Proto, r.RequestURI, r.RemoteAddr, jsonBody} + writer := csv.NewWriter(file) + writer.Write(s) + writer.Flush() +} + +func dumpJsonBoddy(req *http.Request) string { + + if req.Method == "GET" { + return "" + } + + if req.Header.Get("Content-Type") != "application/json" { + return "" + } + + length, err := strconv.Atoi(req.Header.Get("Content-Length")) + + if err != nil { + return "" + } + + body := make([]byte, length) + length, err = req.Body.Read(body) + + if err != nil && err != io.EOF { + return "" + } + + var jsonBody map[string]interface{} + err = json.Unmarshal(body[:length], &jsonBody) + + if err != nil { + return "" + } + + s := fmt.Sprintf("%v", jsonBody) + return s +} + +func (l *stdLogger) Printf(format string, args ...interface{}) { + l.stdout.Printf(format, args...) +} + +func (l *stdLogger) Errorf(format string, args ...interface{}) { + l.stderr.Printf(format, args...) +} + +func (l *stdLogger) Fatalf(format string, args ...interface{}) { + l.stderr.Fatalf(format, args...) +} diff --git a/src/logger/logger_test.go b/src/logger/logger_test.go new file mode 100644 index 0000000..2bd40b5 --- /dev/null +++ b/src/logger/logger_test.go @@ -0,0 +1,26 @@ +package logger + +import ( + "bytes" + "net/http" + "testing" + + "github.com/spf13/cast" + "github.com/stretchr/testify/assert" +) + +func TestGetNonReadRecord(t *testing.T) { + + url := "example.com" + content := `{"integer":1,"string":"xyz", "object": { "element": 1 } , "array": [1, 2, 3]}` + byte := []byte(content) + + body := bytes.NewReader(byte) + req, _ := http.NewRequest("POST", url, body) + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Content-Length", cast.ToString(len(content))) + + result := dumpJsonBoddy(req) + assert.Equal(t, result, "map[array:[1 2 3] integer:1 object:map[element:1] string:xyz]") +} diff --git a/test/main.go b/test/main.go new file mode 100644 index 0000000..bd4d264 --- /dev/null +++ b/test/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "strconv" +) + +func dumpJsonRequestHandlerFunc(w http.ResponseWriter, req *http.Request) { + + if req.Header.Get("Content-Type") != "application/json" { + w.WriteHeader(http.StatusBadRequest) + return + } + + length, err := strconv.Atoi(req.Header.Get("Content-Length")) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + log.Print(length) + + body := make([]byte, length) + length, err = req.Body.Read(body) + + if err != nil && err != io.EOF { + w.WriteHeader(http.StatusInternalServerError) + return + } + + var jsonBody map[string]interface{} + err = json.Unmarshal(body[:length], &jsonBody) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + fmt.Printf("%v\n", jsonBody) + // w.WriteHeader(http.StatusOK) +} + +func main() { + http.HandleFunc("/json", dumpJsonRequestHandlerFunc) + http.ListenAndServe(":8080", nil) +} From 8a1de2724a057418e5952ec497da6c6b078a3100 Mon Sep 17 00:00:00 2001 From: tkc <181991+tkc@users.noreply.github.com> Date: Mon, 9 Mar 2020 01:04:09 +0900 Subject: [PATCH 3/3] Fix CI --- go-json-server.go | 4 +++- src/logger/logger.go | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/go-json-server.go b/go-json-server.go index c347283..aa43dac 100644 --- a/go-json-server.go +++ b/go-json-server.go @@ -127,8 +127,10 @@ func main() { func response(w http.ResponseWriter, r *http.Request) { + appLogger := logger.CreateLogger() + r.ParseForm() - logger.AccessLog(r) + appLogger.AccessLog(r) w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Credentials", "true") diff --git a/src/logger/logger.go b/src/logger/logger.go index 4fad359..ecdba63 100644 --- a/src/logger/logger.go +++ b/src/logger/logger.go @@ -40,6 +40,18 @@ func (l *stdLogger) AccessLog(r *http.Request) { writer.Flush() } +func (l *stdLogger) Printf(format string, args ...interface{}) { + l.stdout.Printf(format, args...) +} + +func (l *stdLogger) Errorf(format string, args ...interface{}) { + l.stderr.Printf(format, args...) +} + +func (l *stdLogger) Fatalf(format string, args ...interface{}) { + l.stderr.Fatalf(format, args...) +} + func dumpJsonBoddy(req *http.Request) string { if req.Method == "GET" { @@ -73,15 +85,3 @@ func dumpJsonBoddy(req *http.Request) string { s := fmt.Sprintf("%v", jsonBody) return s } - -func (l *stdLogger) Printf(format string, args ...interface{}) { - l.stdout.Printf(format, args...) -} - -func (l *stdLogger) Errorf(format string, args ...interface{}) { - l.stderr.Printf(format, args...) -} - -func (l *stdLogger) Fatalf(format string, args ...interface{}) { - l.stderr.Fatalf(format, args...) -}