github.com/webdestroya/awsmocker@v0.2.6/https.go (about) 1 package awsmocker 2 3 import ( 4 "bufio" 5 "crypto/tls" 6 "errors" 7 "io" 8 "net" 9 "net/http" 10 "net/url" 11 "regexp" 12 ) 13 14 const ( 15 imdsHost4 = "169.254.169.254" 16 imdsHost6 = "fd00:ec2::254" 17 ) 18 19 var ( 20 httpsRegexp = regexp.MustCompile(`^https:\/\/`) 21 22 globalTlsConfig = &tls.Config{ 23 InsecureSkipVerify: true, 24 GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) { 25 return globalCertStore.Fetch(chi.ServerName), nil 26 }, 27 } 28 ) 29 30 func (m *mocker) handleHttps(w http.ResponseWriter, r *http.Request) { 31 hij, ok := w.(http.Hijacker) 32 if !ok { 33 panic("httpserver does not support hijacking") 34 } 35 36 proxyClient, _, e := hij.Hijack() 37 if e != nil { 38 panic("Cannot hijack connection " + e.Error()) 39 } 40 41 // respond with success to acknowledge the proxy request 42 _, _ = proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) 43 44 // handle the request 45 go m.handleAwsRequestHttps(proxyClient, r) 46 47 } 48 49 func (m *mocker) handleAwsRequestHttps(proxyClient net.Conn, r *http.Request) { 50 rawClientTls := tls.Server(proxyClient, globalTlsConfig) 51 if err := rawClientTls.Handshake(); err != nil { 52 m.Warnf("Cannot handshake client %v %v", r.Host, err) 53 return 54 } 55 defer rawClientTls.Close() 56 57 clientTlsReader := bufio.NewReader(rawClientTls) 58 for !isEof(clientTlsReader) { 59 req, err := http.ReadRequest(clientTlsReader) 60 if err != nil && !errors.Is(err, io.EOF) { 61 return 62 } 63 if err != nil { 64 m.Warnf("Cannot read TLS request from mitm'd client %v %v", r.Host, err) 65 return 66 } 67 req.RemoteAddr = r.RemoteAddr 68 69 if !httpsRegexp.MatchString(req.URL.String()) { 70 req.URL, _ = url.Parse("https://" + r.Host + req.URL.String()) 71 } 72 73 _, resp := m.handleRequest(req) 74 origBody := resp.Body 75 defer origBody.Close() 76 77 // defer resp.Body.Close() 78 79 resp.Header.Set("Connection", "close") 80 81 if err := resp.Write(rawClientTls); err != nil { 82 m.Warnf("Failed to write response: %s", err) 83 } 84 } 85 }