Skip to content

Instantly share code, notes, and snippets.

@chenchun
Created June 23, 2020 02:12
Show Gist options
  • Save chenchun/2d1abae74c93454741a09ad34ad5b656 to your computer and use it in GitHub Desktop.
Save chenchun/2d1abae74c93454741a09ad34ad5b656 to your computer and use it in GitHub Desktop.
golang unixsocket
package main
import (
"bytes"
"flag"
"io/ioutil"
"log"
"net"
"net/http"
"net/http/httputil"
"strings"
)
func curlUnixSocket(host string, data []byte) ([]byte, error) {
protoAddrParts := strings.SplitN(host, "://", 2)
contentReader := bytes.NewReader(data)
// http://d/
//req, err := http.NewRequest("POST", "http://d/", contentReader)
req, err := http.NewRequest("POST", "/d", contentReader)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.URL.Host = protoAddrParts[1]
dial, err := net.Dial(protoAddrParts[0], protoAddrParts[1])
if err != nil {
return nil, err
}
clientconn := httputil.NewClientConn(dial, nil)
defer clientconn.Close()
resp, err := clientconn.Do(req)
//fakeDial := func (proto, addr string) (conn net.Conn, err error) {
// return net.Dial("unix", protoAddrParts[1])
//}
//tr := &http.Transport{
// Dial: fakeDial,
//}
//client := &http.Client{Transport: tr}
//resp, err := client.Post("http://d", "application/json", contentReader)
if err != nil {
return nil, err
}
body, _ := ioutil.ReadAll(resp.Body)
return body, nil
}
// be sure to install go1.4.3 to /usr/local/go1.4.3
// export PATH=/usr/local/go1.4.3/bin:$PATH
// export GOROOT=/usr/local/go1.4.3
// go build -o client client.go
// ./client # request unix socket unix:///run/test.sock
// ./client -address tcp://127.0.0.1:80 # request tcp 80
func main() {
address := flag.String("address", "unix:///run/test.sock", "the address to request")
data := flag.String("data", "hello there", "the data to send to remote server")
flag.Parse()
body, err := curlUnixSocket(*address, []byte(*data))
if err != nil {
log.Printf("%v", err)
} else {
log.Printf("body: %s", string(body))
}
}
package main
import (
"flag"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"syscall"
)
type HelloServer struct {
}
func (HelloServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
data, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Printf("%v", err)
}
log.Printf("request from %s, %s: %s, body %s", req.RemoteAddr, req.Method, req.RequestURI, string(data))
resp.WriteHeader(http.StatusOK)
resp.Write([]byte("Hello server"))
}
func startUnixSocketServer(addr string) error {
var l net.Listener
var err error
if addr != "" {
log.Printf("listen on %s", addr)
l, err = net.Listen("tcp", addr)
} else {
socket := "/run/test.sock"
log.Printf("listen on %s", socket)
l, err = newUnixSocket(socket)
}
if err != nil {
return err
}
httpServer := &http.Server{Addr: addr}
httpServer.Handler = HelloServer{}
return httpServer.Serve(l)
}
func newUnixSocket(path string) (net.Listener, error) {
if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {
return nil, err
}
mask := syscall.Umask(0777)
defer syscall.Umask(mask)
l, err := net.Listen("unix", path)
if err != nil {
return nil, err
}
return l, nil
}
// ./server # serve unix socket
// ./server -address :80 # serve tcp 80
func main() {
address := flag.String("address", "", "the address to listen")
flag.Parse()
log.Fatal(startUnixSocketServer(*address))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment