func (s *RpcServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { serveCtx := getServerContext(req) // TODO: get user scope from context // check access if req.Method != "POST" { err := errors.BadRequest("go.micro.server", "Method not allowed") http.Error(w, err.Error(), http.StatusMethodNotAllowed) return } defer req.Body.Close() b, err := ioutil.ReadAll(req.Body) if err != nil { errr := errors.InternalServerError("go.micro.server", fmt.Sprintf("Error reading request body: %v", err)) w.WriteHeader(500) w.Write([]byte(errr.Error())) log.Errorf("Erroring reading request body: %v", err) return } rbq := bytes.NewBuffer(b) rsp := bytes.NewBuffer(nil) defer rsp.Reset() defer rbq.Reset() buf := &buffer{ rbq, rsp, } var cc rpc.ServerCodec switch req.Header.Get("Content-Type") { case "application/octet-stream": cc = pb.NewServerCodec(buf) case "application/json": cc = js.NewServerCodec(buf) default: err = errors.InternalServerError("go.micro.server", fmt.Sprintf("Unsupported content-type: %v", req.Header.Get("Content-Type"))) w.WriteHeader(500) w.Write([]byte(err.Error())) return } ctx := newContext(&ctx{}, serveCtx) err = s.rpc.ServeRequestWithContext(ctx, cc) if err != nil { // This should not be possible. w.WriteHeader(500) w.Write([]byte(err.Error())) log.Errorf("Erroring serving request: %v", err) return } w.Header().Set("Content-Type", req.Header.Get("Content-Type")) w.Header().Set("Content-Length", strconv.Itoa(rsp.Len())) w.Write(rsp.Bytes()) }
func (c *rpcPlusCodec) ReadRequestHeader(r *rpc.Request) error { c.rbuf.Reset() c.rbuf.Write(c.req.Body) buf := &buffer{c.rbuf} switch c.req.Header["Content-Type"] { case "application/octet-stream": c.codec = pb.NewServerCodec(buf) case "application/json": c.codec = js.NewServerCodec(buf) default: return fmt.Errorf("unsupported content type %s", c.req.Header["Content-Type"]) } return c.codec.ReadRequestHeader(r) }
func (c *rpcPlusCodec) WriteResponse(r *rpc.Response, body interface{}, last bool) error { c.wbuf.Reset() buf := &buffer{c.wbuf} var cc rpc.ServerCodec switch c.req.Header["Content-Type"] { case "application/octet-stream": cc = pb.NewServerCodec(buf) case "application/json": cc = js.NewServerCodec(buf) default: return fmt.Errorf("unsupported request type: %s", c.req.Header["Content-Type"]) } if err := cc.WriteResponse(r, body, last); err != nil { return err } return c.socket.Send(&transport.Message{ Header: map[string]string{"Content-Type": c.req.Header["Content-Type"]}, Body: c.wbuf.Bytes(), }) }