From the public account: New World grocery store

In HTTP1.x, when a page is accessed, the browser first gets the HTML resources, then incrementally gets the other resources as the page is parsed, and the server must wait for the browser to make a request before delivering the resources within the page. The server actually knows what resources are on the page, and if the server can push resources to the browser before the browser explicitly requests them, the page loading speed will be greatly improved, which is the point of this article.

This article is divided into two parts, the first part is a server push example implemented with GO, and the second part is a self-signed certificate. Read on for more details on why self-signed certificates exist.

Server Push example

Currently only HTTP2 supports server push, http1.x does not support server push, so how should we determine in the code whether the current server supports push?

In Go, we can determine whether the current server supports push by determining whether the HTTP.ResponseWriter implements the HTTP.

Here is my first server push example:

http.HandleFunc("/".func(w http.ResponseWriter, r *http.Request) {
	ifr.URL.Path ! ="/" {
		http.NotFound(w, r)
		return
	}
	pusher, ok := w.(http.Pusher)
	if ok {
		// Push service resources actively
		if err := pusher.Push("/static/app.js".nil); err ! =nil {
			log.Printf("Failed to push: %v", err)
		}
		if err := pusher.Push("/static/style.css".nil); err ! =nil {
			log.Printf("Failed to push: %v", err)
		}
	}
	// Deliver the first screen resources of the browser
	fmt.Fprintf(w, < img style =" text-align: center; text-align: center; text-align: center The new grocery store < / div > < div id = "content" > < / div > < script SRC = "/ static/app. Js" > < / script > < / body > < / HTML > `)
})
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.ListenAndServe(": 8080".nil)
Copy the code

The app.js content in the above code is as follows:

document.getElementById("content").innerHTML = 'new World grocery' from JS '
Copy the code

After running the above code, go to http://localhost:8080/ in your browser and get the following results:

We find that JS resources and style resources are not pushed by the server, and HTTP1.1 is used. In combination with the author’s previous articles, WE know that Go supports HTTP2 and HTTP2 needs to use SSL/TLS, that is, HTTPS. Therefore, the author modified the listening code as follows:

http.ListenAndServeTLS(": 8080"."ca.crt"."ca.key".nil)
Copy the code

Run the above code again and go to https://localhost:8080/ in your browser to get the following:

The red part of the figure shows that this request uses the HTTP2 protocol and the static resource is pushed by the server.

CRT and ca.key are self-signed certificates and private keys respectively. The certificates and private keys have been uploaded to my Github. See the github link at the end of this article.

Generate a self-signed certificate

Note: The author generated the certificate environment for macOS

When I generate a self-signed certificate, I first use the search method, then use the online command to generate the certificate, and finally the certificate is generated, but the browser access results after running the above example are not satisfactory.

First, run the following command to generate the certificate:

Openssl genrsa -out old.key 2048 // Generate a certificate signing request, CSR // Issue a certificate. Openssl x509 -req -days 365 -in old.csr -signkey old.key  -out old.crtCopy the code

Change the certificate and private key in the example to old.crt and old.key.

Being a mild obsessive-compulsive, I feel a little uncomfortable that I can’t continue to access the page without a security alert (Safari is available).

So I went to the OpenSSL website and finally improved the command for generating self-signed certificates.

First create a ca.cnf (optionally named) file in the directory where the command was executed and write the following to the file:

# more x509v3_config see https://www.openssl.org/docs/man1.1.1/man5/x509v3_config.html
[ ca_conf ]
extendedKeyUsage = serverAuth # Key to be able to continue insecure access
basicConstraints = CA:FALSE
Copy the code

The improved signature command is as follows:

Openssl genrsa -out ca.key 2048 // Generate a certificate signing request, Key -out ca. CSR // Issue a certificate. Openssl x509 -req -sha256 -extfile ca.cnf -extensions ca_conf -days 365 -in ca.csr -signkey ca.key -out ca.crtCopy the code

This certificate is the same one used in the previous example, and the first time you access it in the browser, you are prompted with the following:

Click the red box in the picture to access the page normally.

When to use push

After completing the above example, the author specially observed baidu, Taobao and Google’s home page found that everyone has begun to use HTTP2, but it seems that there is no company using server push.

Therefore, the following conclusions are based on personal experience:

  1. Server push should not be abused, only push affects the key resources displayed on the page, after all, the front-end lazy loading is very mature.
  2. Browsers can cache resources, but it is meaningless to push resources that have already been cached. Therefore, avoid pushing resources twice in this scenario.

Finally, I sincerely hope that this article can be of some help to all readers.

reference

blog.golang.org/h2push

Blog.csdn.net/qq_41874930…

Note:

  1. At the time of writing, the version of GO used by the author is GO1.15.2
  2. The full example used in the article: github.com/Isites/go-c…