diff --git a/g/net/ghttp/http_client_request.go b/g/net/ghttp/http_client_request.go index f79a96e25..8c032bd0e 100644 --- a/g/net/ghttp/http_client_request.go +++ b/g/net/ghttp/http_client_request.go @@ -174,7 +174,7 @@ func (r *ClientRequest) GetRaw() string { func (r *ClientRequest) GetJson() *gjson.Json { data := r.GetRaw() if data != "" { - if j, err := gjson.DecodeToJson(data); err == nil { + if j, err := gjson.DecodeToJson([]byte(data)); err == nil { return j } } diff --git a/g/net/ghttp/http_server.go b/g/net/ghttp/http_server.go index 6e67819ac..34d057925 100644 --- a/g/net/ghttp/http_server.go +++ b/g/net/ghttp/http_server.go @@ -31,14 +31,18 @@ type Server struct { } // 域名、URI与回调函数的绑定记录表 -type HandlerMap map[string]HandlerFunc +type HandlerMap map[string]HandlerItem // http回调函数注册信息 -type HandlerFunc struct { +type HandlerItem struct { ctype reflect.Type // 控制器类型 fname string // 回调方法名称 + faddr HandlerFunc // 准确的执行方法内存地址(与以上两个参数二选一) } +// http注册函数 +type HandlerFunc func(*Server, *ClientRequest, *ServerResponse) + // Server表,用以存储和检索名称与Server对象之间的关联关系 var serverMapping = gmap.NewStringInterfaceMap() @@ -226,26 +230,26 @@ func (s *Server) handlerKey(domain, method, pattern string) string { } // 设置请求处理方法 -func (s *Server) setHandler(domain, method, pattern string, handler HandlerFunc) { +func (s *Server) setHandler(domain, method, pattern string, hitem HandlerItem) { s.hmu.Lock() defer s.hmu.Unlock() if method == gDEFAULT_METHOD { - s.handlerMap[s.handlerKey(domain, "GET", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "PUT", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "POST", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "DELETE", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "PATCH", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "HEAD", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "CONNECT", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "OPTIONS", pattern)] = handler - s.handlerMap[s.handlerKey(domain, "TRACE", pattern)] = handler + s.handlerMap[s.handlerKey(domain, "GET", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "PUT", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "POST", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "DELETE", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "PATCH", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "HEAD", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "CONNECT", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "OPTIONS", pattern)] = hitem + s.handlerMap[s.handlerKey(domain, "TRACE", pattern)] = hitem } else { - s.handlerMap[s.handlerKey(domain, method, pattern)] = handler + s.handlerMap[s.handlerKey(domain, method, pattern)] = hitem } } // 查询请求处理方法 -func (s *Server) getHandler(domain, method, pattern string) *HandlerFunc { +func (s *Server) getHandler(domain, method, pattern string) *HandlerItem { s.hmu.RLock() defer s.hmu.RUnlock() key := s.handlerKey(domain, method, pattern) @@ -258,7 +262,7 @@ func (s *Server) getHandler(domain, method, pattern string) *HandlerFunc { // 绑定URI到操作函数/方法 // pattern的格式形如:/user/list, put:/user, delete:/user, post:/user@johng.cn // 支持RESTful的请求格式,具体业务逻辑由绑定的处理方法来执行 -func (s *Server)bindHandler(pattern string, handler HandlerFunc) error { +func (s *Server)bindHandlerItem(pattern string, hitem HandlerItem) error { if s.status == 1 { return errors.New("server handlers cannot be changed while running") } @@ -279,27 +283,27 @@ func (s *Server)bindHandler(pattern string, handler HandlerFunc) error { if uri == "" { return errors.New("invalid pattern") } - s.setHandler(domain, method, uri, handler) + s.setHandler(domain, method, uri, hitem) return nil } // 通过映射数组绑定URI到操作函数/方法 func (s *Server)bindHandlerByMap(m HandlerMap) error { for p, h := range m { - if err := s.bindHandler(p, h); err != nil { + if err := s.bindHandlerItem(p, h); err != nil { return err } } return nil } -// 绑定方法,pattern支持http method -// pattern的格式形如:/user/list, put:/user, delete:/user -func (s *Server)BindMethod(pattern string, c Controller, method string) error { - return s.bindHandler(pattern, HandlerFunc{reflect.ValueOf(c).Elem().Type(), method}) +// 注意该方法是直接绑定方法的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑 +func (s *Server)BindHandler(pattern string, handler HandlerFunc) error { + return s.bindHandlerItem(pattern, HandlerItem{nil, "", handler}) } // 绑定控制器,控制器需要实现gmvc.Controller接口 +// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话 func (s *Server)BindController(uri string, c Controller) error { // 遍历控制器,获取方法列表,并构造成uri m := make(HandlerMap) @@ -317,7 +321,14 @@ func (s *Server)BindController(uri string, c Controller) error { } key += strings.ToLower(string(name[i])) } - m[key] = HandlerFunc{v.Elem().Type(), name} + m[key] = HandlerItem{v.Elem().Type(), name, nil} } return s.bindHandlerByMap(m) } + +// 绑定方法,pattern支持http method +// pattern的格式形如:/user/list, put:/user, delete:/user +// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话 +func (s *Server)BindControllerMethod(pattern string, c Controller, method string) error { + return s.bindHandlerItem(pattern, HandlerItem{reflect.ValueOf(c).Elem().Type(), method, nil}) +} diff --git a/g/net/ghttp/http_server_config.go b/g/net/ghttp/http_server_config.go index 0860d444f..97bce549a 100644 --- a/g/net/ghttp/http_server_config.go +++ b/g/net/ghttp/http_server_config.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "time" "log" - "gitee.com/johng/gf/g/os/gfile" ) // HTTP Server 设置结构体 @@ -37,7 +36,7 @@ var defaultServerConfig = ServerConfig { IndexFiles : []string{"index.html", "index.htm"}, IndexFolder : false, ServerAgent : "gf", - ServerRoot : gfile.SelfDir(), + ServerRoot : "", } // 获取默认的http server设置 diff --git a/g/net/ghttp/http_server_domain.go b/g/net/ghttp/http_server_domain.go index d32e847be..e405c5374 100644 --- a/g/net/ghttp/http_server_domain.go +++ b/g/net/ghttp/http_server_domain.go @@ -32,8 +32,8 @@ func (s *Server) Domain(domain string) *Domain { } // 绑定方法 -func (d *Domain) BindMethod(pattern string, c Controller, method string) error { - return d.s.BindMethod(pattern, c, method) +func (d *Domain) BindControllerMethod(pattern string, c Controller, method string) error { + return d.s.BindControllerMethod(pattern, c, method) } // 绑定控制器 diff --git a/g/net/ghttp/http_server_handler.go b/g/net/ghttp/http_server_handler.go index a9d66fe08..bb8a71c1b 100644 --- a/g/net/ghttp/http_server_handler.go +++ b/g/net/ghttp/http_server_handler.go @@ -28,10 +28,10 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { request.Request = *r response.ResponseWriter = w if h := s.getHandler(gDEFAULT_DOMAIN, r.Method, r.URL.Path); h != nil { - s.initController(h, request, response) + s.callHandler(h, request, response) } else { if h := s.getHandler(strings.Split(r.Host, ":")[0], r.Method, r.URL.Path); h != nil { - s.initController(h, request, response) + s.callHandler(h, request, response) } else { s.serveFile(w, r) } @@ -39,11 +39,15 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { } // 初始化控制器 -func (s *Server)initController(h *HandlerFunc, r *ClientRequest, w *ServerResponse) { - c := reflect.New(h.ctype) - c.MethodByName("Init").Call([]reflect.Value{reflect.ValueOf(s), reflect.ValueOf(r), reflect.ValueOf(w)}) - c.MethodByName(h.fname).Call(nil) - c.MethodByName("Shut").Call(nil) +func (s *Server)callHandler(h *HandlerItem, r *ClientRequest, w *ServerResponse) { + if h.faddr == nil { + c := reflect.New(h.ctype) + c.MethodByName("Init").Call([]reflect.Value{reflect.ValueOf(s), reflect.ValueOf(r), reflect.ValueOf(w)}) + c.MethodByName(h.fname).Call(nil) + c.MethodByName("Shut").Call(nil) + } else { + h.faddr(s, r, w) + } } // 处理静态文件请求 diff --git a/g/net/ghttp/http_server_response.go b/g/net/ghttp/http_server_response.go index b8e451950..bf89f28f7 100644 --- a/g/net/ghttp/http_server_response.go +++ b/g/net/ghttp/http_server_response.go @@ -52,6 +52,13 @@ func (r *ServerResponse) WriteHeaderEncoding(encoding string) { r.Header().Set("Content-Type", "text/plain; charset=" + encoding) } +// 获取缓冲区数据 +func (r *ServerResponse) Buffer() []byte { + r.bufmu.RLock() + defer r.bufmu.RUnlock() + return r.buffer +} + // 输出缓冲区数据到客户端 func (r *ServerResponse) Output() { r.bufmu.RLock() diff --git a/geg/frame/mvc/controller/user/user.go b/geg/frame/mvc/controller/user/user.go index b859b4ea8..c538d6a65 100644 --- a/geg/frame/mvc/controller/user/user.go +++ b/geg/frame/mvc/controller/user/user.go @@ -3,7 +3,6 @@ package user import ( "gitee.com/johng/gf/g/net/ghttp" "gitee.com/johng/gf/g/frame/gmvc" - "fmt" ) // 定义业务相关的控制器对象 @@ -11,21 +10,23 @@ type ControllerUser struct { gmvc.Controller } -func Add(i1, i2 int) int { - return i1 + i2 +func Test(s *ghttp.Server, r *ghttp.ClientRequest, w *ghttp.ServerResponse) { + w.WriteString("Test") + w.Output() } // 初始化控制器对象,并绑定操作到Web Server func init() { //ghttp.GetServer("johng").Domain("localhost").BindHandler("/user", u.Info) + ghttp.GetServer("johng").BindHandler("/test", Test) ghttp.GetServer("johng").BindController("/user", &ControllerUser{}) } // 定义操作逻辑 func (c *ControllerUser) Info() { - fmt.Println(c.Db) - c.View.Assign("name", "john") - c.View.Display("user/index") + c.Response.WriteString("hello world!") + //c.View.Assign("name", "john") + //c.View.Display("user/index") }