Creating HTTP API with extra '/' (without quotes) at the end of the route, takes only 'GET' request.

29 views
Skip to first unread message

Mayank Gupta

unread,
Jun 7, 2019, 8:46:16 AM6/7/19
to golang-nuts
Hi All,

I wanted to make sure before filing an issue on Github.
Here's the code using net/http package to create a restful web API.
If I hit any route using Postman app, no matter the type of request (POST, PUT, DELETE, etc.) it always hits the API as a GET request.

package main

import (
   
"context"
   
"fmt"
   
"io"
   
"log"
   
"net/http"
)

func registerHandler
(responseWriter http.ResponseWriter, request *http.Request) {
   
if request.Method == "GET" {
        io
.WriteString(responseWriter, "This is a get request")
   
} else if request.Method == "POST" {
        io
.WriteString(responseWriter, "This is a post request")
   
} else {
        io
.WriteString(responseWriter, "This is not a valid request request")

   
}    
}

func statsHandler
(responseWriter http.ResponseWriter, request *http.Request) {

   
if request.Method == "GET" {
        io
.WriteString(responseWriter, "This is a get request")
   
} else if request.Method == "POST" {
        io
.WriteString(responseWriter, "This is a post request")
   
} else {
        io
.WriteString(responseWriter, "This is not a valid request request")

   
}
}


func main
() {

    mux
:= http.NewServeMux()
    mux
.HandleFunc("/register/", registerHandler)
    mux
.HandleFunc("/stats/", statsHandler)

    log
.Fatal(http.ListenAndServe(":5000", mux))

}


If I hit 'http://localhost:5000/stats' using POST, it'll always hit the API as a GET request.

Changing main() function to:
func main() {

    mux
:= http.NewServeMux()
    mux
.HandleFunc("/register", registerHandler)
    mux
.HandleFunc("/stats", statsHandler)

    log
.Fatal(http.ListenAndServe(":5000", mux))

}
Works like a charm, the only change is I removed '/' from the routes at end.

I believe it's a bug. Please let me know if what I believe is wrong.

Thanks,
Mayank Gupta

Steven Hartland

unread,
Jun 7, 2019, 9:13:11 AM6/7/19
to Mayank Gupta, golang-nuts
I believe this is documented here: https://golang.org/pkg/net/http/#ServeMux
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/52a497c0-0c94-4005-94c1-f0ac3ee170d6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ben Burwell

unread,
Jun 7, 2019, 9:14:31 AM6/7/19
to Mayank Gupta, golan...@googlegroups.com
If I am correctly understanding the situation you're describing, I think
this actually may be a bug with Postman.

I ran your code (removed the unused imports) with the trailing slashes,
then I used curl to make a request to /stats:

~ curl -v -L -X POST http://localhost:5000/stats
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 5000 (#0)
> POST /stats HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: /stats/
< Date: Fri, 07 Jun 2019 13:00:45 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:5000/stats/'
* Found bundle for host localhost: 0x7fddd9e01370 [can pipeline]
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (::1) port 5000 (#0)
> POST /stats/ HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 07 Jun 2019 13:00:45 GMT
< Content-Length: 22
< Content-Type: text/plain; charset=utf-8
<
* Connection #0 to host localhost left intact
This is a post request%

As you can see, the server responds to the request to /stats with a 301
redirect to /stats/. In the above curl log, you can see that a second
POST request is sent to /stats/ and your handler correctly receives a
POST request.

However, with Postman, the second request is issued but performs a GET
request for whatever reason. Here is a log I took using mitmproxy to
inspect the traffic being sent/received by Postman:

~ mitmdump -p 5001 --mode reverse:http://localhost:5000
Proxy server listening at http://*:5001
[::1]:57178: clientconnect
[::1]:57179: clientconnect
[::1]:57178: clientdisconnect
[::1]:57179: POST http://localhost:5000/stats
<< 301 Moved Permanently 0b
[::1]:57179: GET http://localhost:5000/stats/
<< 200 OK 21b

Hope this helps!

Ben
Reply all
Reply to author
Forward
0 new messages