/
server.go
50 lines (43 loc) · 1.32 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Copyright (c) 2015 Western Digital Corporation or its affiliates. All rights reserved.
// SPDX-License-Identifier: MIT
package rpc
import (
"io"
"log"
"net/http"
"net/rpc"
"sync"
)
const (
bulkRPCPath = "/_goRPC_bulk_crc_"
connectedStatus = "200 Connected to Go RPC" // rpc.connected is not exported
)
var handleHTTPOnce sync.Once
// RegisterName wraps rpc.RegisterName, which uses the default RPC server.
func RegisterName(name string, rcvr interface{}) error {
handleHTTPOnce.Do(func() {
rpc.HandleHTTP()
http.HandleFunc(bulkRPCPath, bulkServeHTTP)
})
return rpc.RegisterName(name, rcvr)
}
// StartStandaloneRPCServer starts the default RPC server.
func StartStandaloneRPCServer(addr string) {
go http.ListenAndServe(addr, nil)
}
func bulkServeHTTP(w http.ResponseWriter, req *http.Request) {
// Copied from go 1.7.5 net/rpc/server.go, replacing ServeConn with ServeCodec.
if req.Method != "CONNECT" {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(http.StatusMethodNotAllowed)
io.WriteString(w, "405 must CONNECT\n")
return
}
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())
return
}
io.WriteString(conn, "HTTP/1.0 "+connectedStatus+"\n\n")
rpc.DefaultServer.ServeCodec(newBulkGobCodec(conn))
}