12// Server represents an HTTP server
18// ListenAndServe will serve traffic on HTTP or HTTPS depending on TLS options
19func (s *Server) ListenAndServe() {
20 if s.Opts.TLSKeyFile != "" || s.Opts.TLSCertFile != "" {
27// Used with gcpHealthcheck()
28const userAgentHeader = "User-Agent"
29const googleHealthCheckUserAgent = "GoogleHC/1.0"
32// gcpHealthcheck handles healthcheck queries from GCP.
33func gcpHealthcheck(h http.Handler) http.Handler {
34 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
35 // Check for liveness and readiness: used for Google App Engine
36 if r.URL.EscapedPath() == "/liveness_check" {
37 w.WriteHeader(http.StatusOK)
41 if r.URL.EscapedPath() == "/readiness_check" {
42 w.WriteHeader(http.StatusOK)
47 // Check for GKE ingress healthcheck: The ingress requires the root
48 // path of the target to return a 200 (OK) to indicate the service's good health. This can be quite a challenging demand
49 // depending on the application's path structure. This middleware filters out the requests from the health check by
51 // 1. checking that the request path is indeed the root path
52 // 2. ensuring that the User-Agent is "GoogleHC/1.0", the health checker
53 // 3. ensuring the request method is "GET"
54 if r.URL.Path == rootPath &&
55 r.Header.Get(userAgentHeader) == googleHealthCheckUserAgent &&
56 r.Method == http.MethodGet {
58 w.WriteHeader(http.StatusOK)
66// ServeHTTP constructs a net.Listener and starts handling HTTP requests
67func (s *Server) ServeHTTP() {
68 HTTPAddress := s.Opts.HTTPAddress
71 i := strings.Index(HTTPAddress, "://")
73 scheme = HTTPAddress[0:i]
76 var networkType string
84 slice := strings.SplitN(HTTPAddress, "//", 2)
85 listenAddr := slice[len(slice)-1]
87 listener, err := net.Listen(networkType, listenAddr)
89 log.Fatalf("FATAL: listen (%s, %s) failed - %s", networkType, listenAddr, err)
91 log.Printf("HTTP: listening on %s", listenAddr)
93 server := &http.Server{Handler: s.Handler}
94 err = server.Serve(listener)
95 if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
96 log.Printf("ERROR: http.Serve() - %s", err)
99 log.Printf("HTTP: closing %s", listener.Addr())
102// ServeHTTPS constructs a net.Listener and starts handling HTTPS requests
103func (s *Server) ServeHTTPS() {
104 addr := s.Opts.HTTPSAddress
105 config := &tls.Config{
106 MinVersion: tls.VersionTLS12,
107 MaxVersion: tls.VersionTLS12,
109 if config.NextProtos == nil {
110 config.NextProtos = []string{"http/1.1"}
114 config.Certificates = make([]tls.Certificate, 1)
115 config.Certificates[0], err = tls.LoadX509KeyPair(s.Opts.TLSCertFile, s.Opts.TLSKeyFile)
117 log.Fatalf("FATAL: loading tls config (%s, %s) failed - %s", s.Opts.TLSCertFile, s.Opts.TLSKeyFile, err)
120 ln, err := net.Listen("tcp", addr)
122 log.Fatalf("FATAL: listen (%s) failed - %s", addr, err)
124 log.Printf("HTTPS: listening on %s", ln.Addr())
126 tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
127 srv := &http.Server{Handler: s.Handler}
128 err = srv.Serve(tlsListener)
130 if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
131 log.Printf("ERROR: https.Serve() - %s", err)
134 log.Printf("HTTPS: closing %s", tlsListener.Addr())
137// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
138// connections. It's used by ListenAndServe and ListenAndServeTLS so
139// dead TCP connections (e.g. closing laptop mid-download) eventually
141type tcpKeepAliveListener struct {
145func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
146 tc, err := ln.AcceptTCP()
150 tc.SetKeepAlive(true)
151 tc.SetKeepAlivePeriod(3 * time.Minute)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list