gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.27k stars 7.98k forks source link

Gin server unreachable from windows with WSL #2800

Open OskarLiew opened 3 years ago

OskarLiew commented 3 years ago

Description

On ubuntu 20.04 in WSL2 on windows 10, the server is not reachable from a browser. Could it be because the server tries to start on 0.0.0.0:8080, but that doesn't resolve on windows? (I am fairly new to web programming).

With net/http this has not been an issue

How to reproduce

The problem can be observed with the quickstart example.

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run("localhost:8080") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

Expectations

$ curl http://localhost:8080/ping
{"message":"pong"}

Actual result

In WSL2:

$ curl localhost:8080/ping
{"message":"pong"}

In windows:

$ curl localhost:8080/ping
curl: (7) Failed to connect to localhost port 9000: Connection refused

$ curl 0.0.0.0:9000
curl: (7) Failed to connect to 0.0.0.0 port 9000: Address not available

And when opening in a browser on localhost:8080/ping and 0.0.0.0:8080/ping I get ERR_CONNECTION_REFUSED

Environment

BRO3886 commented 3 years ago

I've been using gin with WSL for a while now, never faced anything like this

Edit: logs with gin example running on WSL (Ubuntu 20.04)

❯ go mod tidy
go: finding module for package github.com/gin-gonic/gin
go: downloading github.com/gin-gonic/gin v1.7.2
go: found github.com/gin-gonic/gin in github.com/gin-gonic/gin v1.7.2
go: downloading github.com/go-playground/validator/v10 v10.4.1
❯ go run .
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on localhost:8080
[GIN] 2021/08/02 - 00:59:32 | 404 |         700ns |       127.0.0.1 | GET      "/"
[GIN] 2021/08/02 - 00:59:37 | 200 |        36.3µs |       127.0.0.1 | GET      "/ping"

curl:

❯ curl localhost:8080
404 page not found
❯ curl localhost:8080/ping
{"message":"pong"}
jimbirthday commented 3 years ago

@OskarLiew
OskarLiew you try this

r.Run(":8080") 

//or
engine.Run("[::]:8080")
OskarLiew commented 3 years ago

@jimbirthday engine.Run("[::]:8080") did the trick, thank you!

Would you mind explaining what happens when I change address to [::]?

jimbirthday commented 3 years ago

@jimbirthday engine.Run("[::]:8080") did the trick, thank you!

Would you mind explaining what happens when I change address to [::]?

I think the configuration of your network card is different.

engine.Run() The final call is

 package net

// Listen announces on the local network address.
//
// The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
//
// For TCP networks, if the host in the address parameter is empty or
// a literal unspecified IP address, Listen listens on all available
// unicast and anycast IP addresses of the local system.
// To only use IPv4, use network "tcp4".
// The address can use a host name, but this is not recommended,
// because it will create a listener for at most one of the host's IP
// addresses.
// If the port in the address parameter is empty or "0", as in
// "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
// The Addr method of Listener can be used to discover the chosen
// port.
//
// See func Dial for a description of the network and address
// parameters.
func Listen(network, address string) (Listener, error) {
    var lc ListenConfig
    return lc.Listen(context.Background(), network, address)
}