diff options
author | Chris <ccbrown112@gmail.com> | 2017-08-28 11:27:18 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-28 11:27:18 -0500 |
commit | 6215c9159acb85033616d2937edf3d87ef7ca79b (patch) | |
tree | 54e53392804bda3a30aa9615fef0cd01ca189152 /plugin/rpcplugin/hooks.go | |
parent | 510b1a18f5282981a70503c0cde474e121c9e651 (diff) | |
download | chat-6215c9159acb85033616d2937edf3d87ef7ca79b.tar.gz chat-6215c9159acb85033616d2937edf3d87ef7ca79b.tar.bz2 chat-6215c9159acb85033616d2937edf3d87ef7ca79b.zip |
add plugin http handler (#7289)
Diffstat (limited to 'plugin/rpcplugin/hooks.go')
-rw-r--r-- | plugin/rpcplugin/hooks.go | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/plugin/rpcplugin/hooks.go b/plugin/rpcplugin/hooks.go index 5b97742aa..995f4ae1a 100644 --- a/plugin/rpcplugin/hooks.go +++ b/plugin/rpcplugin/hooks.go @@ -1,7 +1,10 @@ package rpcplugin import ( + "bytes" "io" + "io/ioutil" + "net/http" "net/rpc" "reflect" @@ -83,6 +86,33 @@ func (h *LocalHooks) OnDeactivate(args, reply *struct{}) (err error) { return } +type ServeHTTPArgs struct { + ResponseWriterStream int64 + Request *http.Request + RequestBodyStream int64 +} + +func (h *LocalHooks) ServeHTTP(args ServeHTTPArgs, reply *struct{}) error { + w := ConnectHTTPResponseWriter(h.muxer.Connect(args.ResponseWriterStream)) + defer w.Close() + + r := args.Request + if args.RequestBodyStream != 0 { + r.Body = ConnectIOReader(h.muxer.Connect(args.RequestBodyStream)) + } else { + r.Body = ioutil.NopCloser(&bytes.Buffer{}) + } + defer r.Body.Close() + + if hook, ok := h.hooks.(http.Handler); ok { + hook.ServeHTTP(w, r) + } else { + http.NotFound(w, r) + } + + return nil +} + func ServeHooks(hooks interface{}, conn io.ReadWriteCloser, muxer *Muxer) { server := rpc.NewServer() server.Register(&LocalHooks{ @@ -95,6 +125,7 @@ func ServeHooks(hooks interface{}, conn io.ReadWriteCloser, muxer *Muxer) { const ( remoteOnActivate = iota remoteOnDeactivate + remoteServeHTTP maxRemoteHookCount ) @@ -133,6 +164,45 @@ func (h *RemoteHooks) OnDeactivate() error { return h.client.Call("LocalHooks.OnDeactivate", struct{}{}, nil) } +func (h *RemoteHooks) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !h.implemented[remoteServeHTTP] { + http.NotFound(w, r) + return + } + + responseWriterStream, stream := h.muxer.Serve() + defer stream.Close() + go ServeHTTPResponseWriter(w, stream) + + requestBodyStream := int64(0) + if r.Body != nil { + rid, rstream := h.muxer.Serve() + defer rstream.Close() + go ServeIOReader(r.Body, rstream) + requestBodyStream = rid + } + + forwardedRequest := &http.Request{ + Method: r.Method, + URL: r.URL, + Proto: r.Proto, + ProtoMajor: r.ProtoMajor, + ProtoMinor: r.ProtoMinor, + Header: r.Header, + Host: r.Host, + RemoteAddr: r.RemoteAddr, + RequestURI: r.RequestURI, + } + + if err := h.client.Call("LocalHooks.ServeHTTP", ServeHTTPArgs{ + ResponseWriterStream: responseWriterStream, + Request: forwardedRequest, + RequestBodyStream: requestBodyStream, + }, nil); err != nil { + http.Error(w, "500 internal server error", http.StatusInternalServerError) + } +} + func (h *RemoteHooks) Close() error { if h.apiCloser != nil { h.apiCloser.Close() @@ -157,6 +227,8 @@ func ConnectHooks(conn io.ReadWriteCloser, muxer *Muxer) (*RemoteHooks, error) { remote.implemented[remoteOnActivate] = true case "OnDeactivate": remote.implemented[remoteOnDeactivate] = true + case "ServeHTTP": + remote.implemented[remoteServeHTTP] = true } } return remote, nil |