func main() {
	var (
		listen      = flag.String("listen", ":5000", "Port to listen on")
		http1       = flag.Bool("http1", false, "Serve via HTTP/1.1")
		disableGzip = flag.Bool("nogzip", false, "Disable GZIP content compression")
		cors        = flag.String("cors", "*", "Set allowed origins")
	)
	flag.Parse()

	server := &http.Server{
		Addr:         *listen,
		ReadTimeout:  1 * time.Minute,
		WriteTimeout: 1 * time.Minute,
	}

	pushMap := PushManifest{}
	if !*http1 {
		var err error
		pushMap, err = readPushMap("push.json")
		if err != nil {
			log.Printf("Error decoding push map: %s", err)
		}
		http2.ConfigureServer(server, &http2.Server{})
	}

	fs := http.FileServer(http.Dir("."))
	if !*disableGzip {
		oldfs := fs
		fs = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Content-Encoding", "gzip")
			grw := GzipResponseWriter{gzip.NewWriter(w), w}
			oldfs.ServeHTTP(grw, r)
			grw.WriteCloser.Close()
		})
	}

	server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", *cors)
		w.Header().Set("Access-Control-Allow-Methods", "GET, OPTION, HEAD, PATCH, PUT, POST, DELETE")
		log.Printf("Request for %s (Accept-Encoding: %s)", r.URL.Path, r.Header.Get("Accept-Encoding"))
		defer fs.ServeHTTP(w, r)
		if *http1 {
			return
		}
		pushes, ok := pushMap[r.URL.Path]
		if !ok {
			log.Printf("No pushes defined for %s", r.URL.Path)
			return
		}
		pusher, ok := w.(http2.Pusher)
		if !ok {
			log.Printf("Connection is not a pusher")
			return
		}
		for key, pushInstruction := range pushes {
			_ = pushInstruction // No use just yet
			log.Printf("Pushing %s", key)
			pusher.Push("GET", key, http.Header{})
		}
	})

	if err := configureTLS(server); err != nil {
		log.Fatalf("Error configuring TLS: %s", err)
	}

	ln, err := net.Listen("tcp", server.Addr)
	if err != nil {
		log.Fatalf("Error opening socket: %s", err)
	}

	tlsListener := tls.NewListener(ln, server.TLSConfig)
	tcl := tlsListener
	if strings.HasPrefix(*listen, ":") {
		*listen = "localhost" + *listen
	}
	log.Printf("Listening on https://%s...", *listen)
	if err := server.Serve(tcl); err != nil {
		log.Fatalf("Error starting webserver: %s", err)
	}
}
func main() {
	flag.Parse()

	server := &http.Server{
		Addr:         *listen,
		ReadTimeout:  1 * time.Minute,
		WriteTimeout: 1 * time.Minute,
	}

	if !*http1 {
		http2.ConfigureServer(server, &http2.Server{})
	}

	fs := http.FileServer(http.Dir("."))
	if !*disableGzip {
		oldfs := fs
		fs = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
				w.Header().Set("Content-Encoding", "gzip")
				grw := GzipResponseWriter{gzip.NewWriter(w), w}
				defer grw.WriteCloser.Close()
				w = grw
			}
			oldfs.ServeHTTP(w, r)
		})
	}

	server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", *cors)
		w.Header().Set("Access-Control-Allow-Methods", "GET, OPTION, HEAD, PATCH, PUT, POST, DELETE")
		log.Printf("Request for %s (Accept-Encoding: %s)", r.URL.Path, r.Header.Get("Accept-Encoding"))

		if *throttle != 0 {
			trw := NewThrottledResponseWriter(w, iothrottler.Bandwidth(*throttle)*iothrottler.Kbps)
			defer trw.Free()
			w = trw
		}

		delay := 0
		if *maxDelay > *minDelay {
			delay = mrand.Intn(*maxDelay-*minDelay) + *minDelay
		}
		if queryDelay := r.FormValue("delay"); queryDelay != "" {
			delay, _ = strconv.Atoi(queryDelay)
		}
		time.Sleep(time.Duration(delay) * time.Millisecond)

		if *spa != "" {
			path := r.URL.Path
			if _, err := os.Stat("." + path); err == nil {
				fs.ServeHTTP(w, r)
			} else {
				spaContents, err := readSPAFile(*spa)
				if err != nil {
					http.Error(w, fmt.Sprintf("Could not read SPA file: %s", err), http.StatusInternalServerError)
					return
				}
				w.Write(spaContents)
			}
		} else {
			fs.ServeHTTP(w, r)
		}

		if !*http1 && r.Header.Get("X-Is-Push") != "true" {
			pushResources(w, r)
		}
	})

	if err := configureTLS(server); err != nil {
		log.Fatalf("Error configuring TLS: %s", err)
	}

	ln, err := net.Listen("tcp", server.Addr)
	if err != nil {
		log.Fatalf("Error opening socket: %s", err)
	}

	tlsListener := tls.NewListener(ln, server.TLSConfig)
	tcl := tlsListener
	if strings.HasPrefix(*listen, ":") {
		*listen = "localhost" + *listen
	}
	log.Printf("Listening on https://%s...", *listen)
	if err := server.Serve(tcl); err != nil {
		log.Fatalf("Error starting webserver: %s", err)
	}
}