1// Copyright 2016 Michal Witkowski. All Rights Reserved.
2// See LICENSE for licensing terms.
3
4package main
5
6import (
7	"crypto/tls"
8	"flag"
9	"fmt"
10	"log"
11	"net"
12	"net/http"
13	"time"
14
15	"github.com/mwitkow/go-conntrack"
16	"github.com/mwitkow/go-conntrack/connhelpers"
17	"github.com/prometheus/client_golang/prometheus/promhttp"
18	"golang.org/x/net/context/ctxhttp"
19	_ "golang.org/x/net/trace"
20)
21
22var (
23	port            = flag.Int("port", 9090, "whether to use tls or not")
24	useTls          = flag.Bool("tls", true, "Whether to use TLS and HTTP2.")
25	tlsCertFilePath = flag.String("tls_cert_file", "certs/localhost.crt", "Path to the CRT/PEM file.")
26	tlsKeyFilePath  = flag.String("tls_key_file", "certs/localhost.key", "Path to the private key file.")
27)
28
29func main() {
30	flag.Parse()
31
32	// Make sure all outbound connections use the wrapped dialer.
33	http.DefaultTransport.(*http.Transport).DialContext = conntrack.NewDialContextFunc(
34		conntrack.DialWithTracing(),
35		conntrack.DialWithDialer(&net.Dialer{
36			Timeout:   30 * time.Second,
37			KeepAlive: 30 * time.Second,
38		}),
39	)
40	// Since we're using a dynamic name, let's preregister it with prometheus.
41	conntrack.PreRegisterDialerMetrics("google")
42
43	handler := func(resp http.ResponseWriter, req *http.Request) {
44		resp.WriteHeader(http.StatusOK)
45		resp.Header().Add("Content-Type", "application/json")
46		resp.Write([]byte(`{"msg": "hello"}`))
47		callCtx := conntrack.DialNameToContext(req.Context(), "google")
48		_, err := ctxhttp.Get(callCtx, http.DefaultClient, "https://www.google.comx")
49		log.Printf("Google reached with err: %v", err)
50		log.Printf("Got request: %v", req)
51	}
52
53	http.DefaultServeMux.Handle("/", http.HandlerFunc(handler))
54	http.DefaultServeMux.Handle("/metrics", promhttp.Handler())
55
56	httpServer := http.Server{
57		Handler: http.DefaultServeMux,
58	}
59	var httpListener net.Listener
60	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
61	if err != nil {
62		log.Fatalf("Failed to listen: %v", err)
63	}
64	listener = conntrack.NewListener(listener, conntrack.TrackWithTracing())
65	if !*useTls {
66		httpListener = listener
67	} else {
68		tlsConfig, err := connhelpers.TlsConfigForServerCerts(*tlsCertFilePath, *tlsKeyFilePath)
69		if err != nil {
70			log.Fatalf("Failed configuring TLS: %v", err)
71		}
72		tlsConfig, err = connhelpers.TlsConfigWithHttp2Enabled(tlsConfig)
73		if err != nil {
74			log.Fatalf("Failed configuring TLS: %v", err)
75		}
76		log.Printf("Listening with TLS")
77		tlsListener := tls.NewListener(listener, tlsConfig)
78		httpListener = tlsListener
79	}
80	//httpListener.Addr()
81	log.Printf("Listening on: %s", listener.Addr().String())
82	if err := httpServer.Serve(httpListener); err != nil {
83		log.Fatalf("Failed listning: %v", err)
84	}
85}
86