alexedwards/flow

Unexpected % Appended To Param Value.

christhornham opened this issue · 7 comments

I'm working through Let's Go Further for the second time. I'm using the Flow router this time. I'm on chapter 2 of the book and I've built out 3 basic routes.

package main

import (
	"net/http"

	"github.com/alexedwards/flow"
)

func (app *application) routes() http.Handler {

	// initialize a new router (flow router from Alex Edwards)
	router := flow.New()

	// Routes --------------------------------------------- //
	router.HandleFunc("/v1/healthcheck", app.healthcheckHandler, "GET")
	router.HandleFunc("/v1/widgets", app.createWidgetHandler, "POST")
	router.HandleFunc("/v1/widgets/:id", app.getWidgetHandler, "GET")

	return router

}

Here's my getWidgetHandler function:

func (app *application) getWidgetHandler(w http.ResponseWriter, r *http.Request) {

	// get the id value as a string.
	stringId := flow.Param(r.Context(), "id")

	fmt.Fprintf(w, "id: %s", stringId)

}

I sent the following curl request:

curl localhost:4000/v1/widgets/123

I would expect to get the following output:

id: 123

However, I'm getting:

id: 123%

Oddly enough, if I use fmt.Println(stringId) the output is 123.

Am I doing something wrong? Or is this a bug?

Thanks,

Chris

For reference, I rebuilt the code above with httprouter and the % character is not there.

@christhornham I'm afraid that I can't replicate this problem.

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/alexedwards/flow"
)

func main() {
    mux := flow.New()

    mux.HandleFunc("/v1/widgets/:id", getWidgetHandler, "GET")

    err := http.ListenAndServe(":2323", mux)
    log.Fatal(err)
}

func getWidgetHandler(w http.ResponseWriter, r *http.Request) {
    stringId := flow.Param(r.Context(), "id")
    fmt.Fprintf(w, "id: %s", stringId)
}
$ curl localhost:2323/v1/widgets/123
id: 123

When you run your code, what is the length of stringId for /v1/widgets/123? If the length is 3, but fmt.Fprintf(w, "id: %s", stringId) is printing id: 123% then it suggests something is amiss either in the line fmt.Fprintf(w, "id: %s", stringId) or elsewhere in the program.

Do you still have the complete code that you can share?

I rebuilt a copy of the code with the error.

Here's a github link to the project: https://github.com/christhornham/flow-router--

Note: I've made some progress since posting this issue. Please excuse all of the code that I commented out.

Thanks. When I clone that repo and run the code:

$ git clone git@github.com:christhornham/flow-router--.git
$ cd flow-router--/
$ go run ./cmd/api/

I'm not seeing a trailing slash in the response:

$ curl -i localhost:4000/v1/widgets/123
HTTP/1.1 200 OK
Date: Sun, 26 Nov 2023 17:41:25 GMT
Content-Length: 7
Content-Type: text/plain; charset=utf-8

id: 123

I started from scratch to see if it was something I did. I'm still having the same issue when using curl, but not chrome.

Here's a screenshot using curl:

Screenshot 2023-11-26 at 11 12 05 AM

Here's a screen shot in the browser:

Screenshot 2023-11-26 at 11 11 19 AM

I built a new repository for the new code base: https://github.com/christhornham/flow-router-test-v2

I think this issue is related to your terminal. The Content-Length of the response from curl is 7, which matches id: 123 (7 characters including the space). That confirms that the web application isn't sending back the extra %.

What shell are you using? A quick search shows that ZSH adds % signs when something doesn't end in a newline, which would explain why fmt.Println(stringId) worked but fmt.Fprintf(w, "id: %s", stringId) doesn't. https://unix.stackexchange.com/questions/167582/why-zsh-ends-a-line-with-a-highlighted-percent-symbol

That's it! I'm using ZSH and it's definitely appending the highlighted %.

I'm sorry for wasting your time. I'll try to be better at Googling in the future.

I appreciate the help,

Chris