@@ -2,12 +2,17 @@ package grpc
2
2
3
3
import (
4
4
"context"
5
+ "net"
6
+ "net/url"
7
+ "os"
5
8
"sync"
6
9
"time"
7
10
8
11
"github.com/operator-framework/operator-registry/pkg/client"
9
12
10
13
"github.com/sirupsen/logrus"
14
+ "golang.org/x/net/http/httpproxy"
15
+ "golang.org/x/net/proxy"
11
16
"google.golang.org/grpc"
12
17
"google.golang.org/grpc/connectivity"
13
18
@@ -100,10 +105,71 @@ func (s *SourceStore) Get(key registry.CatalogKey) *SourceConn {
100
105
return & source
101
106
}
102
107
108
+ func grpcProxyURL (addr string ) (* url.URL , error ) {
109
+ // Handle ip addresses
110
+ host , _ , err := net .SplitHostPort (addr )
111
+ if err != nil {
112
+ return nil , err
113
+ }
114
+
115
+ url , err := url .Parse (host )
116
+ if err != nil {
117
+ return nil , err
118
+ }
119
+
120
+ // Hardcode fields required for proxy resolution
121
+ url .Host = addr
122
+ url .Scheme = "http"
123
+
124
+ // Override HTTPS_PROXY and HTTP_PROXY with GRPC_PROXY
125
+ proxyConfig := & httpproxy.Config {
126
+ HTTPProxy : getGRPCProxyEnv (),
127
+ HTTPSProxy : getGRPCProxyEnv (),
128
+ NoProxy : getEnvAny ("NO_PROXY" , "no_proxy" ),
129
+ CGI : os .Getenv ("REQUEST_METHOD" ) != "" ,
130
+ }
131
+
132
+ // Check if a proxy should be used based on environment variables
133
+ return proxyConfig .ProxyFunc ()(url )
134
+ }
135
+
136
+ func getGRPCProxyEnv () string {
137
+ return getEnvAny ("GRPC_PROXY" , "grpc_proxy" )
138
+ }
139
+
140
+ func getEnvAny (names ... string ) string {
141
+ for _ , n := range names {
142
+ if val := os .Getenv (n ); val != "" {
143
+ return val
144
+ }
145
+ }
146
+ return ""
147
+ }
148
+
149
+ func grpcConnection (address string ) (* grpc.ClientConn , error ) {
150
+ dialOptions := []grpc.DialOption {grpc .WithInsecure ()}
151
+ proxyURL , err := grpcProxyURL (address )
152
+ if err != nil {
153
+ return nil , err
154
+ }
155
+
156
+ if proxyURL != nil {
157
+ dialOptions = append (dialOptions , grpc .WithContextDialer (func (ctx context.Context , addr string ) (net.Conn , error ) {
158
+ dialer , err := proxy .FromURL (proxyURL , & net.Dialer {})
159
+ if err != nil {
160
+ return nil , err
161
+ }
162
+ return dialer .Dial ("tcp" , addr )
163
+ }))
164
+ }
165
+
166
+ return grpc .Dial (address , dialOptions ... )
167
+ }
168
+
103
169
func (s * SourceStore ) Add (key registry.CatalogKey , address string ) (* SourceConn , error ) {
104
170
_ = s .Remove (key )
105
171
106
- conn , err := grpc . Dial (address , grpc . WithInsecure () )
172
+ conn , err := grpcConnection (address )
107
173
if err != nil {
108
174
return nil , err
109
175
}
0 commit comments