Skip to content

Instantly share code, notes, and snippets.

@chenchun
Created June 23, 2020 02:12
Show Gist options
  • Select an option

  • Save chenchun/2d1abae74c93454741a09ad34ad5b656 to your computer and use it in GitHub Desktop.

Select an option

Save chenchun/2d1abae74c93454741a09ad34ad5b656 to your computer and use it in GitHub Desktop.

Revisions

  1. chenchun created this gist Jun 23, 2020.
    68 changes: 68 additions & 0 deletions client.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    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))
    }
    }
    64 changes: 64 additions & 0 deletions server.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    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))
    }