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/go-json-server.go b/go-json-server.go index fd51a11..b77b741 100644 --- a/go-json-server.go +++ b/go-json-server.go @@ -9,6 +9,8 @@ import ( "net/http" "os" "strconv" + + "github.com/tkc/go-json-server/src/logger" ) const ( @@ -78,7 +80,6 @@ const ( HeaderXCSRFToken = "X-CSRF-Token" ) - type Endpoint struct { Type string `json:"type"` Method string `json:"method"` @@ -97,7 +98,6 @@ type API struct { var api API func main() { - raw, err := ioutil.ReadFile("./api.json") if err != nil { fmt.Println(err.Error()) @@ -114,31 +114,37 @@ 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) { + +func response(w http.ResponseWriter, r *http.Request) { + + appLogger := logger.CreateLogger() + + r.ParseForm() + appLogger.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") - r.ParseForm() 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 +152,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) 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/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/src/logger/logger.go b/src/logger/logger.go new file mode 100644 index 0000000..ecdba63 --- /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 (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" { + 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 +} 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) +} 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