@@ -4,13 +4,19 @@ package proxy
44
55import (
66 "bufio"
7+ "bytes"
78 "context"
9+ "io"
810 "net"
911 "net/http"
12+ "os"
13+ "path/filepath"
1014 "regexp"
1115 "strconv"
1216 "time"
1317
18+ "github.com/lima-vm/lima/pkg/downloader"
19+
1420 "github.com/elazarl/goproxy"
1521 "github.com/sirupsen/logrus"
1622)
@@ -47,11 +53,56 @@ func Start(opts ServerOptions) (*Server, error) {
4753 return server , nil
4854}
4955
56+ func sendFile (req * http.Request , path string , lastModified time.Time , contentType string ) (* http.Response , error ) {
57+ resp := & http.Response {}
58+ resp .Request = req
59+ resp .TransferEncoding = req .TransferEncoding
60+ resp .Header = make (http.Header )
61+ status := http .StatusOK
62+ resp .StatusCode = status
63+ resp .Status = http .StatusText (status )
64+ b , err := os .ReadFile (path )
65+ if err != nil {
66+ return nil , err
67+ }
68+ resp .Body = io .NopCloser (bytes .NewBuffer (b ))
69+ if contentType == "" {
70+ contentType = "application/octet-stream"
71+ }
72+ resp .Header .Set ("Content-Type" , contentType )
73+ if ! lastModified .IsZero () {
74+ resp .Header .Set ("Last-Modified" , lastModified .Format (http .TimeFormat ))
75+ }
76+ resp .ContentLength = int64 (len (b ))
77+ return resp , nil
78+ }
79+
5080func listenAndServe (opts ServerOptions ) (* http.Server , error ) {
81+ ucd , err := os .UserCacheDir ()
82+ if err != nil {
83+ return nil , err
84+ }
85+ cacheDir := filepath .Join (ucd , "lima" )
86+ downloader .HideProgress = true
87+
5188 addr := net .JoinHostPort (opts .Address , strconv .Itoa (opts .TCPPort ))
5289 proxy := goproxy .NewProxyHttpServer ()
5390 proxy .OnRequest (goproxy .ReqHostMatches (regexp .MustCompile ("^.*$" ))).
5491 HandleConnect (goproxy .AlwaysMitm )
92+ proxy .OnRequest ().DoFunc (func (req * http.Request , _ * goproxy.ProxyCtx ) (* http.Request , * http.Response ) {
93+ url := req .URL .String ()
94+ if res , err := downloader .Cached (url , downloader .WithCacheDir (cacheDir )); err == nil {
95+ if resp , err := sendFile (req , res .CachePath , res .LastModified , res .ContentType ); err == nil {
96+ return nil , resp
97+ }
98+ }
99+ if res , err := downloader .Download (context .Background (), "" , url , downloader .WithCacheDir (cacheDir )); err == nil {
100+ if resp , err := sendFile (req , res .CachePath , res .LastModified , res .ContentType ); err == nil {
101+ return nil , resp
102+ }
103+ }
104+ return req , nil
105+ })
55106 proxy .OnRequest (goproxy .ReqHostMatches (regexp .MustCompile ("^.*:80$" ))).
56107 HijackConnect (func (req * http.Request , client net.Conn , ctx * goproxy.ProxyCtx ) {
57108 defer func () {
@@ -61,8 +112,6 @@ func listenAndServe(opts ServerOptions) (*http.Server, error) {
61112 }
62113 client .Close ()
63114 }()
64- url := req .URL .String ()
65- ctx .Logf ("URL: %s" , url )
66115 clientBuf := bufio .NewReadWriter (bufio .NewReader (client ), bufio .NewWriter (client ))
67116 remote , err := net .Dial ("tcp" , req .URL .Host )
68117 if err != nil {
0 commit comments