Golang HTTP2 client and server using non-TLS mode (H2C)

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Studied the HTTP2 usage of Golang.

There are several concepts to be popularized first.

    • H2, HTTP/2 built on top of TLS, as alpn identifier, two bytes, 0x68, 0x32, or HTTPS
    • H2C, HTTP/2, which is built directly on TCP, lacks security assurances that HTTP
      Before the HTTP/2 RFC document appears, the above version fields need to be added to the draft version number, similar to the H2-11,H2C-17

First wrote the code of a server

Import ("FMT" "html" "Net/http" "GOLANG.ORG/X/NET/HTTP2") func main () {var server http. Server HTTP2. Verboselogs = True server. ADDR = ": 8080" http2. Configureserver (&server, &HTTP2. server{}) http. Handlefunc ("/", Func (w http.) Responsewriter, R *http. Request) {fmt. fprintf (W, "URL:%q\n", HTML. Escapestring (R.url. Path)) Showrequestinfohandler (W, R)}) server. Listenandserve ()///Do not enable HTTPS, only http1.x//log is supported by default. Fatal (server. Listenandservetls ("Localhost.cert", "Localhost.key"))}func Showrequestinfohandler (w http. Responsewriter, R *http. Request) {//FMT. fprintf (W, "======")//Return W.header (). Set ("Content-type", "Text/plain") fmt. fprintf (W, "Method:%s\n", R.method) fmt. fprintf (W, "Protocol:%s\n", R.proto) fmt. fprintf (W, "Host:%s\n", R.host) fmt. fprintf (W, "Remoteaddr:%s\n", r.remoteaddr) fmt. fprintf (W, "RequestUri:%q\n", R.requesturi) fmt. fprintf (W, "URL:% #v \ n", R.url) fmt. fprintf (W, "Body.contenTlength:%d ( -1 means unknown) \ n ", R.contentlength) fmt. fprintf (W, "Close:%v (relevant for HTTP/1 only) \ n", R.close) fmt. fprintf (W, "TLS:% #v \ n", R.tls) fmt. fprintf (W, "\nheaders:\n") R.header.write (W)}

Server is used because you do not want to use HTTPS. Listenandserve (), I didn't think there was a hole here, wait for the introduction

Since the server uses HTTP non-TLS then the client uses non-TLS, see the code

  Package Mainimport ("Crypto/tls" "FMT" "Io/ioutil" "Log" "Net" "Net/http" "golang.org/x/n ET/HTTP2 ") Func main () {URL: =" http://localhost:8080/"Client (URL)}func client (URL string) {log. SetFlags (log. Llongfile) TR: = &HTTP2. transport{//Unfortunately the server has degenerated into a http1.x allowhttp:true,//A non-encrypted link//tlsclientconfig: &tls. config{//Insecureskipverify:true,//}, Dialtls:func (NETW, addr string, cfg *tls. Config) (NET. Conn, error) {return net. Dial (NETW, addr)},} httpClient: = http. CLIENT{TRANSPORT:TR} resp, err: = Httpclient.get (URL) if err! = Nil {log. Fatal (ERR)} Defer resp. Body.close () If Resp. StatusCode! = http. Statusok {fmt. Println ("Resp StatusCode:", resp. StatusCode) return} body, err: = Ioutil. ReadAll (resp. Body) If err! = Nil {log. Fatal (Err)} FMT. Println ("resp. Body:\n ", String (Body)}  

Since the HTTP2 client did not expose H2C mode, a

AllowHTTP: true, //充许非加密的链接DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {            return net.Dial(netw, addr)        },

The intention is to implement the client H2C

We're done. Run the server, execute the client, print the results

Get http://localhost:8080/: Unexpected EOF

Look at the foggy, and then grab a bag to see


Paste picture. png

The server sent a http1.1 package to the client, and also close the clients link.

Server. Listenandserve ()//Do not enable HTTPS, only http1.x is supported by default


1.png

Since the server only supports HTTP1, then the client sends a HTTP2 request, of course, the server must close the link.

Then there is no way to solve, that is, the server and the client use H2C, the client is better to do allowhttp:true the non-encrypted link and

DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {            return net.Dial(netw, addr)        },

The

server considers using a lower-level library HTTP2 library implementation, mostly using Servcon to directly replace Serv functions in net/http/, such as

Import ("FMT" "GOLANG.ORG/X/NET/HTTP2" "Net/http" "Net" "Time")//net/http package can be serviced by HTTP2 and opened on a service without HTTPS h2,//needs to modify Listenandserver's default H2 service type Serverhandler struct {}func (sh *serverhandler) servehttp (w http). Responsewriter, req *http. Request) {fmt. PRINTLN (req) W.header (). Set ("Server", "H2test") W.write ([]byte ("This is a HTTP2 Test Sever"))}func main () {server: = &http. server{Addr: ": 8080", Handler: &serverhandler{}, Readtimeout:5 * time. Second, Writetimeout:5 * time. Second,}//http2. Server.serveconn () S2: = &HTTP2. server{idletimeout:1 * time. Minute,} http2. Configureserver (server, S2) L, _: = Net. Listen ("TCP", ": 8080") defer l.close () fmt. PRINTLN ("Start server ...") for {RWC, err: = L.accept () if err! = Nil {fmt. Println ("Accept err:", err) Continue} go s2. Serveconn (RWC, &HTTP2. Serveconnopts{baseconfig:server})}//http. Listenandserve (": 8888", &serverhandler{})}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.