diff --git a/.gitignore b/.gitignore index c32fa26..f4bd72d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,8 @@ _testmain.go *.prof vendor +rbaskets +.DS_Store + +.idea +baskets.db \ No newline at end of file diff --git a/handlers.go b/handlers.go index 281e4d9..394481e 100644 --- a/handlers.go +++ b/handlers.go @@ -16,6 +16,37 @@ import ( "github.com/julienschmidt/httprouter" ) +func createTemplateData(r *RequestData) map[string]interface{} { + data := make(map[string]interface{}) + + // Parse query parameters from the Query string + queryValues, err := url.ParseQuery(r.Query) + if err != nil { + // If parsing fails, create empty url.Values + queryValues = make(url.Values) + } + + // Add query parameters (maintain backward compatibility) + for k, v := range queryValues { + data[k] = v + } + + data["query"] = queryValues + data["headers"] = r.Header + data["method"] = r.Method + + // Add request body and try to parse JSON + if len(r.Body) > 0 && r.Header.Get("Content-Type") == "application/json" { + // Try to parse JSON body + var jsonData interface{} + if err := json.Unmarshal([]byte(r.Body), &jsonData); err == nil { + data["body"] = jsonData + } + } + + return data +} + const ( ModePublic = "public" ModeRestricted = "restricted" @@ -416,7 +447,7 @@ func AcceptBasketRequests(w http.ResponseWriter, r *http.Request) { go forwardAndForget(request, config, name) } - writeBasketResponse(w, r, name, basket) + writeBasketResponse(w, request, name, basket) } else { w.WriteHeader(http.StatusNotFound) } @@ -477,8 +508,8 @@ func forwardAndProxyResponse(w http.ResponseWriter, request *RequestData, config } } -func writeBasketResponse(w http.ResponseWriter, r *http.Request, name string, basket Basket) { - response := basket.GetResponse(r.Method) +func writeBasketResponse(w http.ResponseWriter, request *RequestData, name string, basket Basket) { + response := basket.GetResponse(request.Method) if response == nil { response = &defaultResponse } @@ -491,7 +522,7 @@ func writeBasketResponse(w http.ResponseWriter, r *http.Request, name string, ba // body if response.IsTemplate && len(response.Body) > 0 { // template - t, err := template.New(name + "-" + r.Method).Parse(response.Body) + t, err := template.New(name + "-" + request.Method).Parse(response.Body) if err != nil { // invalid template http.Error(w, "Error in "+err.Error(), http.StatusInternalServerError) @@ -499,7 +530,7 @@ func writeBasketResponse(w http.ResponseWriter, r *http.Request, name string, ba // status w.WriteHeader(response.Status) // templated body - t.Execute(w, r.URL.Query()) + t.Execute(w, createTemplateData(request)) } } else { // status diff --git a/handlers_test.go b/handlers_test.go index 0d19e3a..6b243c9 100644 --- a/handlers_test.go +++ b/handlers_test.go @@ -1,8 +1,10 @@ package main import ( + "bytes" "encoding/json" "fmt" + "html/template" "net/http" "net/http/httptest" "strings" @@ -1963,3 +1965,33 @@ func TestSanitizeForLog(t *testing.T) { assert.Equal(t, "multi-^n^r^n^r^rmulti-^nmulti-^r^nlines", sanitizeForLog("multi-\n\r\n\r\rmulti-\nmulti-\r\nlines"), "unexpected result of sanitizing") } + +func TestCreateTemplateData(t *testing.T) { + r := &RequestData{ + Body: "{\n \"data\": {\n \"authorizationId\": \"4bc09f83-19d3-41ca-b6ee-68d5fb293ae7\"\n },\n \"eventName\": \"request\",\n \"eventType\": \"authorization\"\n}", + Header: http.Header{ + "Content-Type": []string{"application/json"}, + }, + Query: "name=ming&test=aa", + } + templateData := createTemplateData(r) + templateResponse := ` +{ + "authorizationId":"{{.body.data.authorizationId}}", + "query":"{{index .query.name 0}}", + "query-back-compatibility":"{{index .name 0}}", + "responseCode":"00" +} +` + var result bytes.Buffer + tmpl, _ := template.New("testTemplateResponse").Parse(templateResponse) + _ = tmpl.Execute(&result, templateData) + assert.Equal(t, ` +{ + "authorizationId":"4bc09f83-19d3-41ca-b6ee-68d5fb293ae7", + "query":"ming", + "query-back-compatibility":"ming", + "responseCode":"00" +} +`, result.String()) +}