Golang : Get HTTP protocol version example
Upgraded socketloop.com's NGINX web server to serve via HTTP/2
and wanted to find out if Golang can detect the HTTP/2
protocol version. However, at this moment (Go 1.5), Golang's client will always return protocol version HTTP/1.1
From https://golang.org/pkg/net/http/#Request :
// The protocol version for incoming requests.
// Client requests always use HTTP/1.1.
Pretty sure HTTP/2
detection is available at https://godoc.org/golang.org/x/net/http2#ClientConn, but better to wait till it is incorporated into Go 1.6.
Here is a simple example on how to find out the protocol version use by the client in making request to server.
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
client := &http.Client{}
url := "https://www.google.com"
resp, err := client.Get(url) // can use http directly instead of client
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// get protocol version
protocol := resp.Request.Proto
fmt.Println("URL is : ", url)
fmt.Println("Protocol is : ", protocol)
}
Sample outputs :
URL is : //www.socketloop.com
Protocol is : <----- missing protocol!
URL is : https://www.socketloop.com
Protocol is : HTTP/1.1
URL is : http://www.google.com
Protocol is : HTTP/1.1
URL is : https://www.google.com
Protocol is : HTTP/1.1
Apparently, attempt to get protocol version from NON-HTTPS (//www.socketloop.com) version of socketloop.com will return empty string. Upon further investigation with curl -I
command, Golang's net/http.Request.Proto
will only returns value if the HTTP status code is 200 - OK.
>curl -I //www.socketloop.com
HTTP/1.1 301 Moved Permanently
>curl -I https://www.socketloop.com
HTTP/1.1 200 OK
Tried to improve the protocol detection by getting Request header information from the final/effective URL, but it seems that after resolving to the final/effective URL, the protocol variable will still be returned as empty string. (See how to get the HTTP status code https://www.socketloop.com/tutorials/golang-intercept-and-compare-http-response-code-example)
Hence, it is best to check for the protocol string length first before displaying the version.
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
client := &http.Client{}
url := "//www.socketloop.com" // has 301 redirect
resp, err := client.Get(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// get protocol version
protocol := resp.Request.Proto
if len(protocol) > 0 {
fmt.Println("URL is : ", url)
fmt.Println("Protocol is : ", protocol)
} else {
fmt.Println("URL is : ", url)
fmt.Println("Unable to determine protocol version. Check URL with curl -I to see if HTTP status code is 301")
fmt.Println("Golang will resolve to the final/effective URL and will not return HTTP status 301, but 200. However, it will still return empty string for Proto ")
}
}
Output :
With 301 redirect :
URL is : //www.socketloop.com
Unable to determine protocol version. Check URL with curl -I to see if HTTP status code is 301
Golang will resolve to the final/effective URL and will not return HTTP status 301, but 200. However, it will still return empty string for Proto
and with 200 - OK :
URL is : https://www.socketloop.com
Protocol is : HTTP/1.1
References :
https://godoc.org/golang.org/x/net/http2
https://golang.org/pkg/net/http/#Request
https://www.socketloop.com/tutorials/golang-intercept-and-compare-http-response-code-example
https://www.socketloop.com/tutorials/golang-get-final-or-effective-url-with-request-url-example
See also : Golang : Get final or effective URL with Request.URL example
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+15.9k Golang : How to check if input from os.Args is integer?
+31.3k Golang : How to convert(cast) string to IP address?
+23.8k Golang : Upload to S3 with official aws-sdk-go package
+12.4k Golang : Pass database connection to function called from another package and HTTP Handler
+10.4k Golang : Flip coin example
+10.6k PHP : Convert(cast) bigInt to string
+6.6k Golang : Get expvar(export variables) to work with multiplexer
+10.9k Golang : Roll the dice example
+4.8k Google : Block or disable caching of your website content
+6.8k Golang : Gargish-English language translator
+4.9k Golang : Display packages names during compilation
+7.3k Golang : Dealing with struct's private part