commit 9a192c70157978a1e1dcba9e6b7c15acfbea7288 Author: crusader Date: Fri Apr 6 21:00:01 2018 +0900 ing diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3733e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1,68 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Go template +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ +.idea/ +*.iml + +vendor/ +glide.lock +.DS_Store +dist/ +debug diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2ca2b1d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug", + "type": "go", + "request": "launch", + "mode": "debug", + "remotePath": "", + "port": 2345, + "host": "127.0.0.1", + "program": "${workspaceRoot}/main.go", + "env": {}, + "args": [], + "showLog": true + }, + { + "name": "File Debug", + "type": "go", + "request": "launch", + "mode": "debug", + "remotePath": "", + "port": 2345, + "host": "127.0.0.1", + "program": "${fileDirname}", + "env": {}, + "args": [], + "showLog": true + } + + ] +} \ No newline at end of file diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 0000000..31733d8 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,4 @@ +package: git.loafle.net/overflow/gateway_rest +import: +- package: github.com/valyala/fasthttp + version: ^20160617.0.0 diff --git a/server/server-handler.go b/server/server-handler.go new file mode 100644 index 0000000..1a27e65 --- /dev/null +++ b/server/server-handler.go @@ -0,0 +1,25 @@ +package server + +import ( + "net" + + "git.loafle.net/commons/server-go" + cswf "git.loafle.net/commons/server-go/web/fasthttp" +) + +type ServerHandler interface { + cswf.ServerHandler +} + +type ServerHandlers struct { + cswf.ServerHandlers +} + +func (sh *ServerHandlers) Listener(serverCtx server.ServerCtx) (net.Listener, error) { + l, err := net.Listen("tcp", "192.168.1.101:44449") + if nil != err { + return nil, err + } + + return l, nil +} diff --git a/servlet/rest-servlet.go b/servlet/rest-servlet.go new file mode 100644 index 0000000..2e44255 --- /dev/null +++ b/servlet/rest-servlet.go @@ -0,0 +1,110 @@ +package servlet + +import ( + "fmt" + + crp "git.loafle.net/commons/rpc-go/protocol" + crr "git.loafle.net/commons/rpc-go/registry" + "git.loafle.net/commons/server-go" + csw "git.loafle.net/commons/server-go/web" + cswf "git.loafle.net/commons/server-go/web/fasthttp" + "github.com/valyala/fasthttp" +) + +type MethodMapping struct { + Method string + ParamKeys []string +} + +type RESTServlet interface { + cswf.Servlet +} + +type RESTServlets struct { + cswf.Servlets + + ServerCodec crp.ServerCodec + RPCInvoker crr.RPCInvoker + + MethodMapping map[string]MethodMapping +} + +func (s *RESTServlets) Handle(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx) *csw.Error { + method := string(ctx.Method()) + + switch method { + case "GET": + return s.HandleGet(servletCtx, ctx) + case "POST": + return s.HandlePost(servletCtx, ctx) + } + + return nil +} + +func (s *RESTServlets) HandleGet(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx) *csw.Error { + path := string(ctx.Path()) + if nil == s.MethodMapping { + return csw.NewError(fasthttp.StatusNotFound, fmt.Errorf("Not Found for %s", path)) + } + mapping, ok := s.MethodMapping[path] + if !ok { + return csw.NewError(fasthttp.StatusNotFound, fmt.Errorf("Not Found for %s", path)) + } + + method := mapping.Method + params := make([]string, 0) + if nil != mapping.ParamKeys && 0 < len(mapping.ParamKeys) { + qargs := ctx.QueryArgs() + if nil == qargs { + return csw.NewError(fasthttp.StatusBadRequest, fmt.Errorf("Parameter is not valied")) + } + + for _, k := range mapping.ParamKeys { + buf := qargs.Peek(k) + if nil == buf { + return csw.NewError(fasthttp.StatusBadRequest, fmt.Errorf("Parameter for %s is not valied", k)) + } + params = append(params, string(buf)) + } + } + + reqCodec, err := s.ServerCodec.NewRequestWithString(method, params, nil) + if nil != err { + return csw.NewError(fasthttp.StatusBadRequest, err) + } + + reply, err := s.RPCInvoker.Invoke(reqCodec, servletCtx, ctx) + + buf, err := reqCodec.NewResponseWithString(reply.(string), err) + if nil != err { + return csw.NewError(fasthttp.StatusInternalServerError, err) + } + + ctx.SetBody(buf) + + return nil +} + +func (s *RESTServlets) HandlePost(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx) *csw.Error { + buf := ctx.PostBody() + if nil == buf { + return csw.NewError(fasthttp.StatusBadRequest, fmt.Errorf("Parameter is not valied")) + } + + reqCodec, err := s.ServerCodec.NewRequest(buf) + if nil != err { + return csw.NewError(fasthttp.StatusBadRequest, err) + } + + reply, err := s.RPCInvoker.Invoke(reqCodec, servletCtx, ctx) + + buf, err = reqCodec.NewResponseWithString(reply.(string), err) + if nil != err { + return csw.NewError(fasthttp.StatusInternalServerError, err) + } + + ctx.SetBody(buf) + + return nil +}