1 // Package httprpc creates an HTTP POST endpoint that wraps an RPC server 2 package httprpc // import "vimagination.zapto.org/httprpc" 3 4 import ( 5 "io" 6 "net/http" 7 "net/rpc" 8 ) 9 10 type httpRPC struct { 11 server *rpc.Server 12 serverCodec func(io.ReadWriteCloser) rpc.ServerCodec 13 readLimit int64 14 contentType string 15 } 16 17 // Handle returns a new http.Handler that wraps an RPC server 18 func Handle(server *rpc.Server, serverCodec func(io.ReadWriteCloser) rpc.ServerCodec, readLimit int64, contentType string) http.Handler { 19 if server == nil { 20 server = rpc.DefaultServer 21 } 22 return httpRPC{ 23 server: server, 24 serverCodec: serverCodec, 25 readLimit: readLimit, 26 contentType: contentType, 27 } 28 } 29 30 type conn struct { 31 io.Reader 32 io.Closer 33 io.Writer 34 } 35 36 func (h httpRPC) ServeHTTP(w http.ResponseWriter, r *http.Request) { 37 if h.contentType != "" { 38 w.Header().Set("Content-Type", h.contentType) 39 } 40 c := conn{ 41 Reader: r.Body, 42 Closer: r.Body, 43 Writer: w, 44 } 45 if h.readLimit > 0 { 46 c.Reader = io.LimitReader(r.Body, h.readLimit) 47 } 48 h.server.ServeCodec(h.serverCodec(&c)) 49 }