I tried looking it up, but couldn't find an already answered question.
How do I get the host part of the URL in Go?
For eg.
if the user enters http://localhost:8080 in the address bar, I wanted to extract "localhost" from the URL.
If you are talking about extracting the host from a *http.Request you can do the following:
func ExampleHander(w http.ResponseWriter, r *http.Request) {
host := r.Host // This is your host (and will include port if specified)
}
If you just want to access the host part without the port part you can do the following:
func ExampleHandler(w http.ResponseWriter, r *http.Request) {
host, port, _ := net.SplitHostPort(r.Host)
}
For the last one to work you also have to import net
Go has wonderful documentation, I would also recommend taking a look at that: net/http
Go has built in library that can do it for you.
package main
import "fmt"
import "net"
import "net/url"
func main() {
s := "http://localhost:8080"
u, err := url.Parse(s)
if err != nil {
panic(err)
}
host, _, _ := net.SplitHostPort(u.Host)
fmt.Println(host)
}
https://golang.org/pkg/net/url/#
Related
I am making an api and used swaggo/swag to build a swagger interface. Previously, I used the net/http package, and everything was working fine.
I switched to julienschmidt/httprouter, but I don't manage to make the swagger interface work again. Here is my code
package main
import (
"fmt"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
httpSwagger "github.com/swaggo/http-swagger"
)
func main() {
router := httprouter.New()
router.ServeFiles("/api/doc/static/*filepath", http.Dir("api/swagger/static"))
router.HandlerFunc(http.MethodGet, "/api/doc/index.html", swaggerHandler)
// router.HandlerFunc(http.MethodGet, "/api/doc", swaggerHandler)
fmt.Println("Server on port 8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
func swaggerHandler(w http.ResponseWriter, r *http.Request) {
swaggerFileUrl := "http://localhost:8080/api/doc/static/swagger.json"
handler := httpSwagger.Handler(httpSwagger.URL(swaggerFileUrl))
handler.ServeHTTP(w, r)
}
I checked if swaggerFileUrl variable is correct, and I am able to access the json file with this url. The interface is a complete blank page titled "Swagger UI". Because the title is replaced, I am assuming, that something happened, but I don't know if the issue comes from httpSwagger or httprouter.
Edit: Issue is caused because javascript files loading the interface are not present. See this github issue
You can do it like this:
routes := httprouter.New()
routes.GET("/doc/:any", swaggerHandler)
func swaggerHandler(res http.ResponseWriter, req *http.Request, p httprouter.Params) {
httpSwagger.WrapHandler(res, req)
}
Do not forget import doc files
import (
_ "example.project/docs"
)
I've been working on finding a way to try and override the default DNS server for a Go program for a while but still with no success sadly.
The current solution which I had thought would work was:
package main
import (
"context"
"fmt"
"net"
"time"
)
func main() {
DNS := "1.1.1.1"
net.DefaultResolver = &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Millisecond * time.Duration(3000),
}
return d.DialContext(ctx, "udp", fmt.Sprintf("%s:53", DNS))
},
}
resp, err := net.LookupHost("tsdfsdf.com")
if err != nil {
fmt.Printf(err.Error())
}
fmt.Printf("%+v", resp)
}
But the response from this is:
lookup tsdfsdf.com on 192.168.0.1:53: no such host[]
Which is sadly my default DNS server set in my reslov.conf
I have tried forcing to use the Go Resolver by setting export GODEBUG=netdns=go
The long term solution is to be able to over the default resolver for the HTTP Client which would, in turn be consumed by some AWS SDK stuff.
Has any faced this or knows how I can get around this?
FYI, I know "tsdfsdf.com" is not a real domain I'm just using it to spit a No such host error to see what DNS it asked.
this is my actual code :
package main
import (
"net/http"
"net/http/httputil"
"net/url"
)
const BaseUrl = "http://127.0.01:5000"
const ListeningPort = "80"
func main() {
// intercept call
http.HandleFunc("/test", Test)
// all other traffic pass on
http.HandleFunc("/", ProxyFunc)
http.ListenAndServe(":"+ListeningPort, nil)
}
func ProxyFunc(w http.ResponseWriter, r *http.Request) {
u, err := url.Parse(BaseUrl)
if err != nil {
w.Write([]byte(err.Error()))
return
}
proxy := httputil.NewSingleHostReverseProxy(u)
proxy.ServeHTTP(w, r)
}
func Test(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("TEST"))
}
first to accept client connexion, i want to check if browser have enabled javascript, how i can do this in my actual code ?
i want check with this method :
https://pastebin.com/ZASFQumf
It is not possible to do that in Golang since it is a server side language. I don't even think it is possible with JavaScript.
It is not something you can add/set/get from the headers.
What you are trying to do is check browser specific flags.
You might be able to find third party libraries used to manage Chrome flags or Firefox flags etc. That is your best option.
Please, I searched this a lot and after not been able to find, I am writing and not that I didn't try to search all over first. Couldn't get the right answer. I even tried to check Revel's function and couldn't get the answer from there as well.
When I run this program I get this error for line
./test.go:11: use of package http without selector
This error points at the line below where I have written
*http
inside the struct
Confusing part is that with test and dot I even get auto complete with VIM. So I don't know why is the error. Is it that it has to be somewhat like
*(net/http)
or something like that ?
package main
import (
"fmt"
"net/http"
)
type HandleHTTP struct {
*http
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Path is %s", r.URL.Path[1:])
}
func main() {
test := HandleHTTP{}
test.http.HandleFunc("/", handler)
test.http.ListenAndServe(":8080", nil)
}
If you want to have two or more instances serving from different ports you need to spin up two, or more, server. Would something like this, perhaps, work for you?
package main
import (
"fmt"
"net/http"
)
type HandleHTTP struct {
http *http.Server
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Path is %s", r.URL.Path[1:])
}
func main() {
mux1 := http.NewServeMux()
mux1.HandleFunc("/", handler)
test1 := HandleHTTP{http:&http.Server{Addr:":8081", Handler:mux1}}
mux2 := http.NewServeMux()
mux2.HandleFunc("/", handler)
test2 := HandleHTTP{http:&http.Server{Addr:":8082", Handler:mux2}}
// run the first one in a goroutine so that the second one is executed
go test1.http.ListenAndServe()
test2.http.ListenAndServe()
}
I want to write a simple webserver in go that does the following: when i go to http://example.go:8080/image, it returns a static image.
I'm following an example i found here. In this example they implement this method:
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
and then refer to it here :
...
...
http.HandleFunc("/", handler)
Now, what i wanna do is serve an image instead of writing to the string.
How would i go about that?
You can serve static files using the http.FileServer function.
package main
import (
"log"
"net/http"
)
func main() {
http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("path/to/file"))))
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
EDIT: More idiomatic code.
EDIT 2: This code above will return an image image.png when the browser requests http://example.go/image.png
The http.StripPrefix function here is strictly unnecessary in this case as the path being handled is the web root. If the images were to be served from the path http://example.go/images/image.png then the line above would need to be http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("path/to/file")))).
Playground