Skip to content

feat: add healthcheck #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode
.history
6 changes: 5 additions & 1 deletion http_middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import (
"time"
)

const (
healthcheckPath = "/healthcheck"
)

// mwMultiMethod - produce handler for several http methods
func mwMultiMethod(in map[string]http.HandlerFunc) (http.HandlerFunc, error) {
switch len(in) {
Expand Down Expand Up @@ -57,7 +61,7 @@ func mwMethodOnly(handler http.HandlerFunc, method string) http.HandlerFunc {
func mwBasicAuth(handler http.HandlerFunc, users authUsers) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) {
reqUser, reqPass, ok := req.BasicAuth()
if !ok || !users.isAllow(reqUser, reqPass) {
if (!ok || !users.isAllow(reqUser, reqPass)) && req.URL.Path != healthcheckPath {
rw.Header().Set("WWW-Authenticate", `Basic realm="Please enter user and password"`)
http.Error(rw, "name/password is required", http.StatusUnauthorized)
return
Expand Down
9 changes: 9 additions & 0 deletions shell2http.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,15 @@ func setupHandlers(cmdHandlers []command, appConfig Config, cacheTTL raphanus.DB
})
}

//healthcheck
resultHandlers = append(resultHandlers, command{
path: healthcheckPath,
cmd: "healthcheck",
handler: func(rw http.ResponseWriter, _ *http.Request) {
responseWrite(rw, "ok")
},
})

return resultHandlers, nil
}

Expand Down
57 changes: 57 additions & 0 deletions shell2http_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"flag"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -247,6 +248,62 @@ func Test_main(t *testing.T) {
},
"8. POST with GET",
)

}

func Test_mainBasicAuth(t *testing.T) {
port := getFreePort(t)
os.Args = []string{"shell2http",
"-basic-auth=user:pass",
"-one-thread",
"-port=" + port,
"GET:/echoauth", "echo 123",
}

//clean before launching another test
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) //flags are now reset
http.DefaultServeMux = new(http.ServeMux)
// end clean

go main()
time.Sleep(100 * time.Millisecond) // wait for up http server

// hide stderr
oldStderr := os.Stderr // keep backup of the real stderr
newStderr, err := os.Open("/dev/null")
if err != nil {
t.Errorf("open /dev/null: %s", err)
}
os.Stderr = newStderr
defer func() {
os.Stderr = oldStderr
err := newStderr.Close()
if err != nil {
t.Errorf("Stderr Close failed: %s", err)
}
}()

testHTTP(t, "GET", "http://localhost:"+port+"/echoauth", "",
func(res string) bool {
return res == "name/password is required\n"
},
"1. no auth",
)

testHTTP(t, "GET", "http://user:pass@localhost:"+port+"/echoauth", "",
func(res string) bool {
return res == "123\n"
},
"2. auth",
)

testHTTP(t, "GET", "http://localhost:"+port+"/healthcheck", "",
func(res string) bool {
return res == "ok"
},
"3. healthcheck",
)

}

func Test_errChain(t *testing.T) {
Expand Down