diff --git a/args/args.go b/args/args.go index a495f0b..5403154 100644 --- a/args/args.go +++ b/args/args.go @@ -3,13 +3,21 @@ package args /* This file manages declaration of, parsing of, and returning copies of command line arguments. */ -import "flag" +import ( + "flag" + "os" +) /* Method to trigger flag parsing. Can be called multiple times safely. */ func Parse() { if (flagsParsed) {return} flag.Parse(); flagsParsed = true; + + // Process DBUS socket location + if socketLocation == nil || *socketLocation == "" { + *socketLocation = os.Getenv("DBUS_SYSTEM_BUS_ADDRESS"); + } } /* module-specific variable to avoid re-parsing flags */ var flagsParsed bool = false; @@ -39,7 +47,7 @@ func GetSocketLocation() (port string, set bool) { } /* Where the signal-cli binary is */ -var binaryLocation = flag.String("binary", "", "Location of the signal-cli binary.") +var binaryLocation = flag.String("binary", "/usr/local/bin/signal-cli", "Location of the signal-cli binary.") /* @return set boolean will be true if argument is not nil */ func GetBinaryLocation() (port string, set bool) { if binaryLocation == nil {return "", false} diff --git a/http/listen.go b/http/listen.go index 3f372eb..1a0934e 100644 --- a/http/listen.go +++ b/http/listen.go @@ -4,8 +4,10 @@ package http import ( "signal-cli-http/conf" + "signal-cli-http/subprocess" "fmt" + "io" "log" "net/http" ) @@ -20,17 +22,43 @@ func StartWebserver(port int) { func getRoot(w http.ResponseWriter, r *http.Request) { // Check that Authentication header exists authArr, ok := r.Header["Authentication"] - if (!ok) || (len(authArr) == 0) {w.WriteHeader(400); return} + if (!ok) || (len(authArr) == 0) { + w.WriteHeader(400); + w.Write([]byte("Authentication header missing\n")) + return; + } bearer := authArr[0]; // Check that the request is allowed for the path if !conf.GlobalConfig.ValidateBearerKey(bearer, r.URL.Path) { w.WriteHeader(403); + w.Write([]byte("Bearer key not whitelisted for this path\n")) return; } - log.Default().Print("HTTP Request: ", bearer, " " , r.URL.Path) - // OK authentication wise - w.WriteHeader(200); + + body, err := io.ReadAll(r.Body) + if err != nil { + w.WriteHeader(500); + w.Write([]byte("Error reading body\n")) + return; + } + + // Call subprocess + status, bodyContent, err := subprocess.Run(r.URL.Path, body) + + // Error + if err != nil { + w.WriteHeader(500); + w.Write([]byte("Internal server error: " + err.Error() + "\n")); + return + } + + // Respond to client with status + w.WriteHeader(status); + w.Write(bodyContent); + + // Log the request + log.Default().Print("HTTP Request: ", bearer, " " , r.URL.Path, " ", status) } \ No newline at end of file diff --git a/subprocess/command.go b/subprocess/command.go new file mode 100644 index 0000000..2b53020 --- /dev/null +++ b/subprocess/command.go @@ -0,0 +1,21 @@ +package subprocess + +/* This file manages creating the command line arguments to the subprocess */ + +/* Method which module http calls to create the subprocess */ +func Run(path string, body []byte) (status int, bodyContents []byte, err error) { + arguments := getArguments(path, body); + + // Don't know what to do with this request + if arguments == nil {return 404, []byte("Unknown request\n"), nil;} + + // Call subprocess + status, bodyContents, err = runCommand(arguments); + + return +} + +/* Converts a request into the correct binary arguments */ +func getArguments(path string, body []byte) []string { + return nil // For now +} \ No newline at end of file diff --git a/subprocess/subprocess.go b/subprocess/subprocess.go new file mode 100644 index 0000000..a1ea05f --- /dev/null +++ b/subprocess/subprocess.go @@ -0,0 +1,44 @@ +package subprocess + +import ( + "signal-cli-http/args" + + "errors" + "os/exec" + "strings" +) + +/* This file manages calling signal-cli */ + +/* Runs the command */ +func runCommand(arguments []string) (returnStatus int, bodyContent []byte, err error) { + // Get binary location + binary, ok := args.GetBinaryLocation(); + if !ok { + err = errors.New("Binary cannot be found!"); + return; + } + + // Create command using binary location and arguments + command := exec.Command(binary, strings.Join(arguments, " ")); + + // Duplicate pointer into command.Stdout + //command.Stdout = &bodyContent; + + // Run the command + err = command.Run(); + if err != nil {return} + + // Extract exit code if possible + if exitError, ok := err.(*exec.ExitError); ok { + returnStatus = exitError.ExitCode(); + } else { + err = errors.New("Cannot get exit code!"); + } + + // Get output + bodyContent, err = command.Output(); + + // Named return values allow this + return; +} \ No newline at end of file