From e7a69858ca981b513191e4e56e669c8dad1ed0c0 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Thu, 23 Jan 2025 20:26:58 +0100 Subject: [PATCH 01/12] Added JSON as an option and pretty print the response for plain text --- main.go | 84 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index 70c9177..799183d 100644 --- a/main.go +++ b/main.go @@ -1,41 +1,103 @@ package main import ( + "encoding/json" "fmt" + "io" "log" "net/http" - "net/http/httputil" "os" + "strconv" + "strings" ) -const HelpText = `Usage: whttp [] +const HelpText = `Usage: whttp [] -Provide the port number as part of the host or as a single argument. -For example: localhost:5000, :5000, or localhost 5000.` +host : The TCP network host to accept connections on; e.g. localhost:5000 or :5000 +JSON : Serve any response in JSON format; Default: false + +For example: wget :5000 true` + +const PrettyHeaderFormat = "Header\n======\n%s" +const PrettyBodyFormat = "Body\n====\n%s" + +type RequestData struct { + Header map[string][]string + Body string +} + +func (data RequestData) prettyPrintHeader() string { + var output string + for key, values := range data.Header { + output += fmt.Sprintf("%s: %s\n", key, strings.Join(values, ", ")) + } + return output +} + +func (data RequestData) PrettyPrint() string { + prettyHeader := fmt.Sprintf(PrettyHeaderFormat, data.prettyPrintHeader()) + var prettyBody string + if len(data.Body) > 0 { + prettyBody = fmt.Sprintf(PrettyBodyFormat, data.Body) + } + return fmt.Sprintf("%s\n%s", prettyHeader, prettyBody) +} + +func NewRequestData(r *http.Request) (RequestData, error) { + var data RequestData + data.Header = r.Header + if body, err := io.ReadAll(r.Body); err == nil { + data.Body = string(body) + } else { + return data, err + } + return data, nil +} // This function simply prints a dump of the http request. func handleAny(w http.ResponseWriter, r *http.Request) { - dump, err := httputil.DumpRequest(r, true) - if err != nil { + if requestData, err := NewRequestData(r); err == nil { + fmt.Fprintf(w, "%s", requestData.PrettyPrint()) + } else { + w.WriteHeader(500) + fmt.Fprintf(w, "%e", err) + return + } +} + +func handleAnyJson(w http.ResponseWriter, r *http.Request) { + if requestData, err := NewRequestData(r); err == nil { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(requestData) + } else { w.WriteHeader(500) fmt.Fprintf(w, "%e", err) return } - fmt.Fprintf(w, "%s", dump) } func main() { var addr string + var serveJson bool if len(os.Args[1:]) == 1 { addr = os.Args[1] } else if len(os.Args[1:]) == 2 { - addr = fmt.Sprintf("%s:%s", os.Args[1], os.Args[2]) + addr = os.Args[1] + if _serveJson, err := strconv.ParseBool(os.Args[2]); err == nil { + serveJson = _serveJson + } else { + log.Fatal(err) + } } else { - log.Panic(HelpText) - return + log.Fatal(HelpText) } - handler := http.HandlerFunc(handleAny) + var handler http.Handler + if serveJson { + handler = http.HandlerFunc(handleAnyJson) + } else { + handler = http.HandlerFunc(handleAny) + } log.Fatal(http.ListenAndServe(addr, handler)) } From e125530f30892e05faed1841ec2a1e59a8331c55 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:18:58 +0100 Subject: [PATCH 02/12] Added CI job to go workflow --- .github/workflows/go.yml | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c908e28..aca7e4b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,27 +2,41 @@ name: Go on: push: - branches: ["main"] + branches: ["main", "develop"] pull_request: - branches: ["main"] paths-ignore: - "**/Readme.md" - ".editorconfig" +permissions: + contents: read + pull-requests: read + checks: write + jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.23.4" + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.60 build: + depends_on: + - golangci runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v4 + - uses: actions/setup-go@v4 with: go-version: "1.23.4" - - name: Build run: make build - - uses: actions/upload-artifact@v4 with: name: whttp From 4db656f3a4a51a1f7306397467f7f7ca891c9222 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:21:52 +0100 Subject: [PATCH 03/12] Fixed workflow file --- .github/workflows/go.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index aca7e4b..b5a6951 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -18,14 +18,14 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: "1.23.4" - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: v1.60 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.23.4" + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.60 build: depends_on: - golangci From b1d9e01bbb5d83233751ad91365cbf6bc4ffe6db Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:24:41 +0100 Subject: [PATCH 04/12] Fixed workflow file --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b5a6951..57c902d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -4,6 +4,7 @@ on: push: branches: ["main", "develop"] pull_request: + branches: ["main", "develop"] paths-ignore: - "**/Readme.md" - ".editorconfig" @@ -27,8 +28,7 @@ jobs: with: version: v1.60 build: - depends_on: - - golangci + needs: golangci runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From bfb37f33520cd0007549df65a37d490fa9589aef Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:27:30 +0100 Subject: [PATCH 05/12] Fixed workflow file --- .github/workflows/go.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 57c902d..6c15525 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,9 +2,13 @@ name: Go on: push: - branches: ["main", "develop"] + branches: + - main + - develop pull_request: - branches: ["main", "develop"] + branches: + - main + - develop paths-ignore: - "**/Readme.md" - ".editorconfig" From ec07191a93924a247416e345d56a9b86b5fcc55b Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:38:53 +0100 Subject: [PATCH 06/12] Added prettier config --- .prettierrc.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .prettierrc.yml diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 0000000..27851cf --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,8 @@ +semi: false +tabWidth: 4 +overrides: + - files: + - "**/*.yml" + - "**/*.yaml" + options: + tabWidth: 2 From 5f641ab5083901c8b645ecdcc08594b9e81c9d97 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:39:04 +0100 Subject: [PATCH 07/12] Formatted workflow files --- .github/workflows/docker.yml | 46 ++++++++++---------- .github/workflows/go.yml | 83 +++++++++++++++++------------------- 2 files changed, 63 insertions(+), 66 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a0ad87d..97afd01 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,34 +1,34 @@ name: Docker Image CI on: - push: - tags: ["v*.*.*"] + push: + tags: ["v*.*.*"] env: - DOCKER_USER: marcelstolin - IMAGE_NAME: wildcardhttp + DOCKER_USER: marcelstolin + IMAGE_NAME: wildcardhttp jobs: - build: - runs-on: ubuntu-latest + build: + runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 + steps: + - name: Checkout repository + uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - - name: Log into Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ env.DOCKER_USER }} - password: ${{ secrets.DOCKER_TOKEN }} + - name: Log into Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USER }} + password: ${{ secrets.DOCKER_TOKEN }} - - name: Build and push Docker image - id: build-and-push - uses: docker/build-push-action@v6 - with: - context: . - push: ${{ github.event_name != 'pull_request' }} - tags: "${{ env.DOCKER_USER }}/${{ env.IMAGE_NAME }}:latest,${{ env.DOCKER_USER }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}" + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v6 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: "${{ env.DOCKER_USER }}/${{ env.IMAGE_NAME }}:latest,${{ env.DOCKER_USER }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}" diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6c15525..b8d44f7 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,47 +1,44 @@ -name: Go - +name: Go CI on: - push: - branches: - - main - - develop - pull_request: - branches: - - main - - develop - paths-ignore: - - "**/Readme.md" - - ".editorconfig" + push: + branches: + - main + pull_request: + branches: + - main + paths-ignore: + - "**/Readme.md" + - .editorconfig + - prettierrc.yml permissions: - contents: read - pull-requests: read - checks: write - + contents: read + pull-requests: read + checks: write jobs: - golangci: - name: lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: "1.23.4" - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: v1.60 - build: - needs: golangci - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 - with: - go-version: "1.23.4" - - name: Build - run: make build - - uses: actions/upload-artifact@v4 - with: - name: whttp - path: whttp + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: 1.23.4 + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.60 + build: + needs: golangci + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: 1.23.4 + - name: Build + run: make build + - uses: actions/upload-artifact@v4 + with: + name: whttp + path: whttp From 5221b0ef3aca4ff2db92e1750b84351606f66f0c Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:39:18 +0100 Subject: [PATCH 08/12] Added editorconfig --- .editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index c6e540b..654c1e0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,6 @@ indent_style = tab [*.md] trim_trailing_whitespace = false eclint_indent_style = unset + +[*.yml,*.yaml] +indent_size = 2 From 2d07afc7e64b0cb22a83db237d4e45e561014e85 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:40:20 +0100 Subject: [PATCH 09/12] This is a pain to debug --- .github/workflows/go.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b8d44f7..20b8e1d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -3,13 +3,6 @@ on: push: branches: - main - pull_request: - branches: - - main - paths-ignore: - - "**/Readme.md" - - .editorconfig - - prettierrc.yml permissions: contents: read From f3cbc2ebdc65df5f629cca26e239a5e7ac1cbfc8 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:41:02 +0100 Subject: [PATCH 10/12] Active Go CI for PRs --- .github/workflows/go.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 20b8e1d..6bf9d75 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -3,6 +3,9 @@ on: push: branches: - main + pull_request: + branches: + - main permissions: contents: read From 546fe5bf4f68ab4b0079966b0ad1c39fa0807d23 Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:44:44 +0100 Subject: [PATCH 11/12] Updated paths to ignore --- .github/workflows/go.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6bf9d75..8ba8efc 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -6,6 +6,9 @@ on: pull_request: branches: - main + paths-ignore: + - Readme.md + - .editorconfig permissions: contents: read From dcdd582030b977d91ca42962950b820c15f0b1ec Mon Sep 17 00:00:00 2001 From: Marcel Stolin Date: Fri, 24 Jan 2025 19:46:13 +0100 Subject: [PATCH 12/12] Fixed to handle encoding errors --- main.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 799183d..76d15ad 100644 --- a/main.go +++ b/main.go @@ -68,7 +68,11 @@ func handleAny(w http.ResponseWriter, r *http.Request) { func handleAnyJson(w http.ResponseWriter, r *http.Request) { if requestData, err := NewRequestData(r); err == nil { w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(requestData) + if err := json.NewEncoder(w).Encode(requestData); err != nil { + w.WriteHeader(500) + fmt.Fprintf(w, "%e", err) + return + } } else { w.WriteHeader(500) fmt.Fprintf(w, "%e", err)