1
1
package main
2
2
3
3
import (
4
+ "crypto/tls"
4
5
"net/http"
5
6
"net/url"
7
+ "os"
8
+ "strings"
6
9
7
10
over "github.com/adrienaury/zeromdc"
8
11
"github.com/cgi-fr/pimo/internal/app/pimo"
@@ -11,13 +14,31 @@ import (
11
14
"github.com/cgi-fr/pimo/pkg/uri"
12
15
"github.com/rs/zerolog/log"
13
16
"github.com/spf13/cobra"
17
+ "golang.org/x/term"
14
18
)
15
19
16
20
// pimo --serve ":8080" --mask 'name=[{add: true}, {randomChoiceInUri: "pimo://nameFR"}]'
17
21
// pimo -v5 mock -p :8081 http://localhost:8080
18
22
23
+ func askPassword (prompt string ) string {
24
+ if term .IsTerminal (int (os .Stdin .Fd ())) {
25
+ os .Stdout .Write ([]byte (prompt ))
26
+ bytePassword , err := term .ReadPassword (int (os .Stdin .Fd ()))
27
+ os .Stdout .Write ([]byte ("\n " ))
28
+ if err != nil {
29
+ os .Exit (1 )
30
+ }
31
+ return string (bytePassword )
32
+ }
33
+ return ""
34
+ }
35
+
19
36
func setupMockCommand (rootCmd * cobra.Command ) {
20
37
mockAddr := ":8080"
38
+ proxyURL := ""
39
+ proxyAuth := ""
40
+ serverAuth := ""
41
+ insecure := false
21
42
22
43
mockCmd := & cobra.Command {
23
44
Use : "mock" ,
@@ -34,12 +55,57 @@ func setupMockCommand(rootCmd *cobra.Command) {
34
55
if cmd .Flags ().Changed ("seed" ) {
35
56
globalSeed = & seedValue
36
57
}
37
- runMockCommand (backendURL , mockAddr , mockConfigFile , globalSeed )
58
+
59
+ client := http .DefaultClient
60
+ if proxyURL != "" {
61
+ proxyURLParsed , err := url .Parse (proxyURL )
62
+ if err != nil {
63
+ log .Fatal ().Err (err ).Msg ("Failed to parse proxy URL" )
64
+ }
65
+ if proxyAuth != "" {
66
+ if ! strings .Contains (proxyAuth , ":" ) {
67
+ password := askPassword ("enter password for proxy authentication: " )
68
+ proxyAuth = proxyAuth + ":" + password
69
+ }
70
+ proxyURLParsed .User = url .UserPassword (strings .Split (proxyAuth , ":" )[0 ], strings .Split (proxyAuth , ":" )[1 ])
71
+ }
72
+ client .Transport = & http.Transport {
73
+ Proxy : http .ProxyURL (proxyURLParsed ),
74
+ }
75
+ }
76
+
77
+ if insecure {
78
+ if client .Transport == nil {
79
+ client .Transport = & http.Transport {
80
+ TLSClientConfig : & tls.Config {InsecureSkipVerify : true }, //nolint:gosec
81
+ }
82
+ } else {
83
+ client .Transport .(* http.Transport ).TLSClientConfig = & tls.Config {InsecureSkipVerify : true } //nolint:gosec
84
+ }
85
+ }
86
+
87
+ if serverAuth != "" {
88
+ if ! strings .Contains (serverAuth , ":" ) {
89
+ password := askPassword ("enter password for server authentication: " )
90
+ proxyAuth = proxyAuth + ":" + password
91
+ }
92
+ client .Transport = & TransportWithAuth {
93
+ wrapped : client .Transport ,
94
+ user : strings .Split (serverAuth , ":" )[0 ],
95
+ pass : strings .Split (serverAuth , ":" )[1 ],
96
+ }
97
+ }
98
+
99
+ runMockCommand (backendURL , mockAddr , mockConfigFile , globalSeed , client )
38
100
},
39
101
Args : cobra .ExactArgs (1 ),
40
102
}
41
103
42
104
mockCmd .PersistentFlags ().StringVarP (& mockAddr , "port" , "p" , mockAddr , "address and port number" )
105
+ mockCmd .PersistentFlags ().StringVarP (& proxyURL , "proxy" , "x" , proxyURL , "use the specified proxy to perform backend request" )
106
+ mockCmd .PersistentFlags ().StringVarP (& proxyAuth , "proxy-user" , "U" , proxyAuth , "specify user:password to use for proxy authentication" )
107
+ mockCmd .PersistentFlags ().StringVarP (& serverAuth , "user" , "u" , serverAuth , "specify user:password to use for server authentication" )
108
+ mockCmd .PersistentFlags ().BoolVarP (& insecure , "insecure" , "k" , insecure , "allow insecure server connections when using SSL" )
43
109
addFlag (mockCmd , flagBufferSize )
44
110
// addFlag(mockCmd, flagCatchErrors) // could use
45
111
addFlag (mockCmd , flagConfigRoute )
@@ -56,7 +122,21 @@ func setupMockCommand(rootCmd *cobra.Command) {
56
122
rootCmd .AddCommand (mockCmd )
57
123
}
58
124
59
- func runMockCommand (backendURL , mockAddr , configFile string , globalSeed * int64 ) {
125
+ type TransportWithAuth struct {
126
+ wrapped http.RoundTripper
127
+ user string
128
+ pass string
129
+ }
130
+
131
+ func (t * TransportWithAuth ) RoundTrip (req * http.Request ) (* http.Response , error ) {
132
+ req .SetBasicAuth (t .user , t .pass )
133
+ if t .wrapped == nil {
134
+ return http .DefaultTransport .RoundTrip (req )
135
+ }
136
+ return t .wrapped .RoundTrip (req )
137
+ }
138
+
139
+ func runMockCommand (backendURL , mockAddr , configFile string , globalSeed * int64 , client * http.Client ) {
60
140
pimo .InjectMasks ()
61
141
statistics .Reset ()
62
142
@@ -72,7 +152,7 @@ func runMockCommand(backendURL, mockAddr, configFile string, globalSeed *int64)
72
152
log .Fatal ().Err (err ).Msg ("Failed to parse backend URL" )
73
153
}
74
154
75
- ctx , err := cfg .Build (backend , globalSeed , cachesToLoad )
155
+ ctx , err := cfg .Build (backend , globalSeed , cachesToLoad , client )
76
156
if err != nil {
77
157
log .Fatal ().Err (err ).Msgf ("Failed to build routes from %s" , configFile )
78
158
}
0 commit comments