From 4838f45f1306a87666322350a8c5e1b4b3105efb Mon Sep 17 00:00:00 2001 From: Blallo Date: Mon, 5 Nov 2018 11:53:26 +0100 Subject: [PATCH 1/2] [http] Stricter behaviour with l= --- cmd/circologd/http.go | 48 ++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/cmd/circologd/http.go b/cmd/circologd/http.go index 5832a11..c5d3432 100644 --- a/cmd/circologd/http.go +++ b/cmd/circologd/http.go @@ -1,9 +1,8 @@ package main import ( - "fmt" + "log" "net/http" - "os" "strconv" "time" @@ -26,43 +25,36 @@ func getHTTPHandler(hub circolog.Hub) http.HandlerFunc { err := r.ParseForm() if err != nil { - fmt.Fprintln(os.Stderr, "error parsing http request", err) + log.Println("error parsing http request", err) } // Looking for known parameter in the request // TODO: write specialized function var requestMessageLen int if reqL, ok := r.Form["l"]; ok { - var err error - switch { - case len(reqL) == 1: + if len(reqL) == 1 { requestMessageLen, err = strconv.Atoi(reqL[0]) - if requestMessageLen <= 0 { - fmt.Fprintln(os.Stderr, "malformed request, l non positive:", requestMessageLen) - //requestMessageLen := 0 + if err != nil || requestMessageLen <= 0 { + log.Println("malformed request on parameter l") + requestMessageLen = -1 + w.WriteHeader(400) } - if err != nil { - fmt.Fprintln(os.Stderr, "malformed request on parameter l:", err) - } - case len(reqL) > 1: - requestMessageLen, err = strconv.Atoi(reqL[len(reqL)-1]) - fmt.Fprintln(os.Stderr, "multiple values of l parameter, taking last:", - requestMessageLen) - if err != nil { - fmt.Fprintln(os.Stderr, "malformed request on parameter l:", err) - } - default: - fmt.Fprintln(os.Stderr, "empty parameter l in request") + } else { + log.Println("malformed request on parameter l") + requestMessageLen = -1 + w.WriteHeader(400) } } - i := 1 - for x := range client.Messages { - w.Write([]byte(circolog.FormatSyslog(x))) - w.Write([]byte("\n")) - if requestMessageLen != 0 && i >= requestMessageLen { - break + if requestMessageLen >= 0 { + i := 1 + for x := range client.Messages { + w.Write([]byte(circolog.FormatSyslog(x))) + w.Write([]byte("\n")) + if requestMessageLen != 0 && i >= requestMessageLen { + break + } + i++ } - i++ } } } From 5ae6078805bbbb7f1d2002af860e109928422800 Mon Sep 17 00:00:00 2001 From: Blallo Date: Thu, 8 Nov 2018 12:37:31 +0100 Subject: [PATCH 2/2] [http] Better handling of parameters and added LastMsg to Client --- cmd/circologd/http.go | 80 ++++++++++++++++++++++++++----------------- hub.go | 1 + 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/cmd/circologd/http.go b/cmd/circologd/http.go index c5d3432..718d4a2 100644 --- a/cmd/circologd/http.go +++ b/cmd/circologd/http.go @@ -1,6 +1,7 @@ package main import ( + "errors" "log" "net/http" "strconv" @@ -11,50 +12,65 @@ import ( "gopkg.in/mcuadros/go-syslog.v2/format" ) +type requestParams struct { + // Add here the expected request parameters + errorList map[string]error + requestMessageLen int +} + func setupHTTP(hub circolog.Hub) { http.HandleFunc("/", getHTTPHandler(hub)) http.HandleFunc("/ws", getWSHandler(hub)) } +func parseParameterL(r *http.Request) (int, error) { + var requestMessageLen int + var err error + if reqL, ok := r.Form["l"]; ok { + if len(reqL) == 1 { + requestMessageLen, err = strconv.Atoi(reqL[0]) + if err != nil { + return 0, err + } + if requestMessageLen <= 0 { + return 0, errors.New("malformed request") + } + } else { + return 0, errors.New("malformed request") + } + } + return requestMessageLen, nil +} + +func (p *requestParams) parseParameters(w http.ResponseWriter, r *http.Request) { + err := r.ParseForm() + if err != nil { + log.Println("error parsing http request", err) + } + p.errorList = make(map[string]error, 1) + p.requestMessageLen, p.errorList["l"] = parseParameterL(r) +} + func getHTTPHandler(hub circolog.Hub) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // Looking for known parameter in the request + var params requestParams + params.parseParameters(w, r) + if params.errorList["l"] != nil { + log.Println("Request parameter \"l\":", params.errorList["l"]) + w.WriteHeader(400) + return + } + client := circolog.Client{ Messages: make(chan format.LogParts, 20), + LastMsg: params.requestMessageLen, Nofollow: true} hub.Register <- client - err := r.ParseForm() - if err != nil { - log.Println("error parsing http request", err) - } - // Looking for known parameter in the request - // TODO: write specialized function - var requestMessageLen int - if reqL, ok := r.Form["l"]; ok { - if len(reqL) == 1 { - requestMessageLen, err = strconv.Atoi(reqL[0]) - if err != nil || requestMessageLen <= 0 { - log.Println("malformed request on parameter l") - requestMessageLen = -1 - w.WriteHeader(400) - } - } else { - log.Println("malformed request on parameter l") - requestMessageLen = -1 - w.WriteHeader(400) - } - } - - if requestMessageLen >= 0 { - i := 1 - for x := range client.Messages { - w.Write([]byte(circolog.FormatSyslog(x))) - w.Write([]byte("\n")) - if requestMessageLen != 0 && i >= requestMessageLen { - break - } - i++ - } + for x := range client.Messages { + w.Write([]byte(circolog.FormatSyslog(x))) + w.Write([]byte("\n")) } } } diff --git a/hub.go b/hub.go index b653dc1..dfa0199 100644 --- a/hub.go +++ b/hub.go @@ -11,6 +11,7 @@ import ( // new messages are sent. type Client struct { Messages chan format.LogParts // only hub should write/close this + LastMsg int // The number of last messages to display Nofollow bool // if Nofollow is true, the hub will not keep this client permanently. Rather, it will send every message to "Messages" and close the channel. Use this if you want to get the messages one-shot }