1

I am trying to write a simple Unix domain socket based http server in golang. Here is the code:

package main

import (
    "fmt"
    "log"
    "net/http"
    "net"
    "os"
    "encoding/json"
    "os/signal"
    "syscall"
)

type UnixListener struct {
    ServerMux *http.ServeMux
    SocketPath string
    UID int
    GID int
    SocketFileMode os.FileMode
}

//////////////////////////////////////////////////////////////////////
// Start the HTTP server with UNIX socket.
//////////////////////////////////////////////////////////////////////
func (l *UnixListener) Start() error {
    listener, err := net.Listen("unix", l.SocketPath)
    if err != nil {
        return err
    }
    if err := os.Chown(l.SocketPath, l.UID, l.GID); err != nil {
        return err
    }
    if err := os.Chmod(l.SocketPath, l.SocketFileMode); err != nil {
        return err
    }
    go func(){
        shutdown(listener)
    }()

    svr := http.Server{ 
        Handler: l.ServerMux,
    }

    if err := svr.Serve(listener); err != nil {
        return err
    } else {
        return nil
    }
}


//////////////////////////////////////////////////////////////////////
// Shutdown the HTTP server.
//////////////////////////////////////////////////////////////////////
func shutdown(listener net.Listener) {
    c := make(chan os.Signal, 1)
    signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
    s := <-c
    listener.Close()
    log.Fatalf("[FATAL] Caught a signal. sinal=%s", s)
}


func hello(w http.ResponseWriter, r *http.Request) {
    log.Println("Received request %s", r.RequestURI)
    fmt.Fprintf(w, "Hello World!\n")
    w.Header().Set("ContentType", "application/json")
    w.WriteHeader(http.StatusOK)
    data := map[string]string { "name" : "satish"}
    resp, _ := json.Marshal(data)
    if _, err := w.Write(resp); err != nil {
        fmt.Printf("Error writing response")
    }
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/hello", hello)
    unixListener := UnixListener{
        ServerMux: mux,
        SocketPath: "/temp/test.sock",
        UID: 501,
        GID: 20,
        SocketFileMode: 0644,
    }
    if err := unixListener.Start(); err != nil {
        log.Fatalf("[FATAL] HTTP server error: %s", err)
    }
}

But when I send the request to this UDS based server like below, the handler does not seem to be invoked, giving 404 not found error. What is the right way to implement UDS based http server and how to send the http request to it?

curl -vvv  --unix-socket /temp/test.sock  http:/hello
*   Trying /Users/sburnwal/Projects/ACI/temp/test.sock:0...
* Connected to hello (/temp/test.sock) port 80 (#0)
> GET / HTTP/1.1
> Host: hello
> User-Agent: curl/7.84.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Date: Mon, 14 Nov 2022 02:38:11 GMT
< Content-Length: 19
< 
404 page not found
* Connection #0 to host hello left intact
1
  • You can see from the GET / in the error error that curl is not requesting /hello because the url is incorrect. You are also trying to write the response header a second time, which does nothing because you cannot change the response after it has already been sent. Commented Nov 14, 2022 at 14:33

1 Answer 1

2

It appears it's interpreting http:/hello in your command line as the host name and using that for the header. And then requesting / as the path

Try replacing http:/hello in your command line with http://hello/hello. I'm not sure if the single slash vs double-slash is significant. It just looks suspicious.

curl -vvv  --unix-socket /temp/test.sock  http://hello/hello

Or change your Go code to have a response handler for "/" instead of just for "/hello"

mux.HandleFunc("/hello", hello)
mux.HandleFunc("/", hello)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.