Rework use of context
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go.net/context"
|
||||
)
|
||||
|
||||
type ctx struct{}
|
||||
|
||||
func (ctx *ctx) Deadline() (deadline time.Time, ok bool) {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func (ctx *ctx) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *ctx) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *ctx) Value(key interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newContext(parent context.Context, s *serverContext) context.Context {
|
||||
return context.WithValue(parent, "serverContext", s)
|
||||
}
|
||||
|
||||
// return server.Context
|
||||
func NewContext(ctx context.Context) (Context, bool) {
|
||||
c, ok := ctx.Value("serverContext").(*serverContext)
|
||||
return c, ok
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package server
|
||||
|
||||
type Headers interface {
|
||||
Add(string, string)
|
||||
Del(string)
|
||||
Get(string) string
|
||||
Set(string, string)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package server
|
||||
|
||||
type Request interface {
|
||||
Headers() Headers
|
||||
Session(string) string
|
||||
}
|
||||
@@ -4,11 +4,14 @@ import (
|
||||
"bytes"
|
||||
"sync"
|
||||
|
||||
log "github.com/golang/glog"
|
||||
c "github.com/myodc/go-micro/context"
|
||||
"github.com/myodc/go-micro/transport"
|
||||
|
||||
log "github.com/golang/glog"
|
||||
rpc "github.com/youtube/vitess/go/rpcplus"
|
||||
js "github.com/youtube/vitess/go/rpcplus/jsonrpc"
|
||||
pb "github.com/youtube/vitess/go/rpcplus/pbrpc"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -26,7 +29,6 @@ var (
|
||||
)
|
||||
|
||||
func (s *RpcServer) accept(sock transport.Socket) {
|
||||
// serveCtx := getServerContext(req)
|
||||
var msg transport.Message
|
||||
if err := sock.Recv(&msg); err != nil {
|
||||
return
|
||||
@@ -50,17 +52,21 @@ func (s *RpcServer) accept(sock transport.Socket) {
|
||||
cc = js.NewServerCodec(buf)
|
||||
default:
|
||||
return
|
||||
// return nil, errors.InternalServerError("go.micro.server", fmt.Sprintf("Unsupported content-type: %v", req.Header.Get("Content-Type")))
|
||||
}
|
||||
|
||||
//ctx := newContext(&ctx{}, serveCtx)
|
||||
if err := s.rpc.ServeRequestWithContext(context.Background(), cc); err != nil {
|
||||
// strip our headers
|
||||
ct := msg.Header["Content-Type"]
|
||||
delete(msg.Header, "Content-Type")
|
||||
|
||||
ctx := c.WithMetaData(context.Background(), msg.Header)
|
||||
|
||||
if err := s.rpc.ServeRequestWithContext(ctx, cc); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sock.Send(&transport.Message{
|
||||
Header: map[string]string{
|
||||
"Content-Type": msg.Header["Content-Type"],
|
||||
"Content-Type": ct,
|
||||
},
|
||||
Body: rsp.Bytes(),
|
||||
})
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/myodc/go-micro/client"
|
||||
)
|
||||
|
||||
var ctxs = struct {
|
||||
sync.Mutex
|
||||
m map[*http.Request]*serverContext
|
||||
}{
|
||||
m: make(map[*http.Request]*serverContext),
|
||||
}
|
||||
|
||||
// A server context interface
|
||||
type Context interface {
|
||||
Request() Request // the request made to the server
|
||||
Headers() Headers // the response headers
|
||||
NewRequest(string, string, interface{}) client.Request // a new scoped client request
|
||||
NewProtoRequest(string, string, interface{}) client.Request // a new scoped client request
|
||||
NewJsonRequest(string, string, interface{}) client.Request // a new scoped client request
|
||||
}
|
||||
|
||||
// context represents the context of an in-flight HTTP request.
|
||||
// It implements the appengine.Context and http.ResponseWriter interfaces.
|
||||
type serverContext struct {
|
||||
req *serverRequest
|
||||
outCode int
|
||||
outHeader http.Header
|
||||
outBody []byte
|
||||
}
|
||||
|
||||
// Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status
|
||||
// codes do not permit a response body (nor response entity headers such as
|
||||
// Content-Length, Content-Type, etc).
|
||||
func bodyAllowedForStatus(status int) bool {
|
||||
switch {
|
||||
case status >= 100 && status <= 199:
|
||||
return false
|
||||
case status == 204:
|
||||
return false
|
||||
case status == 304:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getServerContext(req *http.Request) *serverContext {
|
||||
ctxs.Lock()
|
||||
c := ctxs.m[req]
|
||||
ctxs.Unlock()
|
||||
|
||||
if c == nil {
|
||||
// Someone passed in an http.Request that is not in-flight.
|
||||
panic("NewContext passed an unknown http.Request")
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *serverContext) NewRequest(service, method string, request interface{}) client.Request {
|
||||
req := client.NewRequest(service, method, request)
|
||||
// TODO: set headers and scope
|
||||
req.Headers().Set("X-User-Session", c.Request().Session("X-User-Session"))
|
||||
return req
|
||||
}
|
||||
|
||||
func (c *serverContext) NewProtoRequest(service, method string, request interface{}) client.Request {
|
||||
req := client.NewProtoRequest(service, method, request)
|
||||
// TODO: set headers and scope
|
||||
req.Headers().Set("X-User-Session", c.Request().Session("X-User-Session"))
|
||||
return req
|
||||
}
|
||||
|
||||
func (c *serverContext) NewJsonRequest(service, method string, request interface{}) client.Request {
|
||||
req := client.NewJsonRequest(service, method, request)
|
||||
// TODO: set headers and scope
|
||||
req.Headers().Set("X-User-Session", c.Request().Session("X-User-Session"))
|
||||
return req
|
||||
}
|
||||
|
||||
// The response headers
|
||||
func (c *serverContext) Headers() Headers {
|
||||
return c.outHeader
|
||||
}
|
||||
|
||||
// The response headers
|
||||
func (c *serverContext) Header() http.Header {
|
||||
return c.outHeader
|
||||
}
|
||||
|
||||
// The request made to the server
|
||||
func (c *serverContext) Request() Request {
|
||||
return c.req
|
||||
}
|
||||
|
||||
func (c *serverContext) Write(b []byte) (int, error) {
|
||||
if c.outCode == 0 {
|
||||
c.WriteHeader(http.StatusOK)
|
||||
}
|
||||
if len(b) > 0 && !bodyAllowedForStatus(c.outCode) {
|
||||
return 0, http.ErrBodyNotAllowed
|
||||
}
|
||||
c.outBody = append(c.outBody, b...)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (c *serverContext) WriteHeader(code int) {
|
||||
if c.outCode != 0 {
|
||||
log.Error("WriteHeader called multiple times on request.")
|
||||
return
|
||||
}
|
||||
c.outCode = code
|
||||
}
|
||||
|
||||
func GetContext(r *http.Request) *serverContext {
|
||||
return getServerContext(r)
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type serverRequest struct {
|
||||
req *http.Request
|
||||
}
|
||||
|
||||
func (s *serverRequest) Headers() Headers {
|
||||
return s.req.Header
|
||||
}
|
||||
|
||||
func (s *serverRequest) Session(name string) string {
|
||||
if sess := s.Headers().Get(name); len(sess) > 0 {
|
||||
return sess
|
||||
}
|
||||
|
||||
c, err := s.req.Cookie(name)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return c.Value
|
||||
}
|
||||
Reference in New Issue
Block a user