github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/plugin/rpcplugin/http.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package rpcplugin
     5  
     6  import (
     7  	"io"
     8  	"net/http"
     9  	"net/rpc"
    10  )
    11  
    12  type LocalHTTPResponseWriter struct {
    13  	w http.ResponseWriter
    14  }
    15  
    16  func (w *LocalHTTPResponseWriter) Header(args struct{}, reply *http.Header) error {
    17  	*reply = w.w.Header()
    18  	return nil
    19  }
    20  
    21  func (w *LocalHTTPResponseWriter) Write(args []byte, reply *struct{}) error {
    22  	_, err := w.w.Write(args)
    23  	return err
    24  }
    25  
    26  func (w *LocalHTTPResponseWriter) WriteHeader(args int, reply *struct{}) error {
    27  	w.w.WriteHeader(args)
    28  	return nil
    29  }
    30  
    31  func (w *LocalHTTPResponseWriter) SyncHeader(args http.Header, reply *struct{}) error {
    32  	dest := w.w.Header()
    33  	for k := range dest {
    34  		if _, ok := args[k]; !ok {
    35  			delete(dest, k)
    36  		}
    37  	}
    38  	for k, v := range args {
    39  		dest[k] = v
    40  	}
    41  	return nil
    42  }
    43  
    44  func ServeHTTPResponseWriter(w http.ResponseWriter, conn io.ReadWriteCloser) {
    45  	server := rpc.NewServer()
    46  	server.Register(&LocalHTTPResponseWriter{
    47  		w: w,
    48  	})
    49  	server.ServeConn(conn)
    50  }
    51  
    52  type RemoteHTTPResponseWriter struct {
    53  	client *rpc.Client
    54  	header http.Header
    55  }
    56  
    57  var _ http.ResponseWriter = (*RemoteHTTPResponseWriter)(nil)
    58  
    59  func (w *RemoteHTTPResponseWriter) Header() http.Header {
    60  	if w.header == nil {
    61  		w.client.Call("LocalHTTPResponseWriter.Header", struct{}{}, &w.header)
    62  	}
    63  	return w.header
    64  }
    65  
    66  func (w *RemoteHTTPResponseWriter) Write(b []byte) (int, error) {
    67  	if err := w.client.Call("LocalHTTPResponseWriter.SyncHeader", w.header, nil); err != nil {
    68  		return 0, err
    69  	}
    70  	if err := w.client.Call("LocalHTTPResponseWriter.Write", b, nil); err != nil {
    71  		return 0, err
    72  	}
    73  	return len(b), nil
    74  }
    75  
    76  func (w *RemoteHTTPResponseWriter) WriteHeader(statusCode int) {
    77  	if err := w.client.Call("LocalHTTPResponseWriter.SyncHeader", w.header, nil); err != nil {
    78  		return
    79  	}
    80  	w.client.Call("LocalHTTPResponseWriter.WriteHeader", statusCode, nil)
    81  }
    82  
    83  func (h *RemoteHTTPResponseWriter) Close() error {
    84  	return h.client.Close()
    85  }
    86  
    87  func ConnectHTTPResponseWriter(conn io.ReadWriteCloser) *RemoteHTTPResponseWriter {
    88  	return &RemoteHTTPResponseWriter{
    89  		client: rpc.NewClient(conn),
    90  	}
    91  }