@@ -4,13 +4,19 @@ package proxy
4
4
5
5
import (
6
6
"bufio"
7
+ "bytes"
7
8
"context"
9
+ "io"
8
10
"net"
9
11
"net/http"
12
+ "os"
13
+ "path/filepath"
10
14
"regexp"
11
15
"strconv"
12
16
"time"
13
17
18
+ "github.com/lima-vm/lima/pkg/downloader"
19
+
14
20
"github.com/elazarl/goproxy"
15
21
"github.com/sirupsen/logrus"
16
22
)
@@ -47,11 +53,56 @@ func Start(opts ServerOptions) (*Server, error) {
47
53
return server , nil
48
54
}
49
55
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
+
50
80
func 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
+
51
88
addr := net .JoinHostPort (opts .Address , strconv .Itoa (opts .TCPPort ))
52
89
proxy := goproxy .NewProxyHttpServer ()
53
90
proxy .OnRequest (goproxy .ReqHostMatches (regexp .MustCompile ("^.*$" ))).
54
91
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
+ })
55
106
proxy .OnRequest (goproxy .ReqHostMatches (regexp .MustCompile ("^.*:80$" ))).
56
107
HijackConnect (func (req * http.Request , client net.Conn , ctx * goproxy.ProxyCtx ) {
57
108
defer func () {
@@ -61,8 +112,6 @@ func listenAndServe(opts ServerOptions) (*http.Server, error) {
61
112
}
62
113
client .Close ()
63
114
}()
64
- url := req .URL .String ()
65
- ctx .Logf ("URL: %s" , url )
66
115
clientBuf := bufio .NewReadWriter (bufio .NewReader (client ), bufio .NewWriter (client ))
67
116
remote , err := net .Dial ("tcp" , req .URL .Host )
68
117
if err != nil {
0 commit comments