1
- import { AxiosInstance } from "axios" ;
1
+ import { AxiosInstance , AxiosResponse } from "axios" ;
2
2
import { spawn } from "child_process" ;
3
3
import { Api } from "coder/site/src/api/api" ;
4
4
import {
@@ -19,47 +19,104 @@ import { expandPath } from "./util";
19
19
20
20
export const coderSessionTokenHeader = "Coder-Session-Token" ;
21
21
22
+ function getCertFilePath ( ) : string {
23
+ return config ( "coder.tlsCertFile" ) . trim ( ) ;
24
+ }
25
+
26
+ function getKeyFilePath ( ) : string {
27
+ return config ( "coder.tlsKeyFile" ) . trim ( ) ;
28
+ }
29
+
30
+ function config ( key :string ) : string {
31
+ return vscode . workspace . getConfiguration ( ) . get ( key ) ?? "" ;
32
+ }
33
+
34
+ function readFile ( filePath : string ) : Promise < string | undefined > {
35
+ if ( ! checkEmptyString ( filePath ) ) {
36
+ return Promise . resolve ( undefined )
37
+ }
38
+ return fs . readFile ( filePath , "utf8" )
39
+ }
40
+
41
+ function checkEmptyString ( str : string ) : string | undefined {
42
+ if ( ! str || str . trim ( ) === "" ) {
43
+ return undefined ;
44
+ }
45
+ return str ;
46
+ }
47
+
48
+ function getPath ( key :string ) : string {
49
+ const path = config ( key ) . trim ( ) ;
50
+ if ( ! path ) {
51
+ return "" ;
52
+ }
53
+ return expandPath ( path ) ;
54
+ }
55
+
56
+ function getHost ( key :string ) : string {
57
+ const value = config ( key ) . trim ( ) ;
58
+ if ( ! value ) {
59
+ return "" ;
60
+ }
61
+ return value ;
62
+ }
63
+
64
+ function getStreamFromResponse ( response : AxiosResponse < any , any > ) : ReadableStream < Buffer > {
65
+ return new ReadableStream ( {
66
+ start ( controller ) {
67
+ response . data . on ( "data" , ( chunk : Buffer ) => {
68
+ controller . enqueue ( chunk ) ;
69
+ } ) ;
70
+
71
+ response . data . on ( "end" , ( ) => {
72
+ controller . close ( ) ;
73
+ } ) ;
74
+
75
+ response . data . on ( "error" , ( err : Error ) => {
76
+ controller . error ( err ) ;
77
+ } ) ;
78
+ } ,
79
+
80
+ cancel ( ) {
81
+ response . data . destroy ( ) ;
82
+ return Promise . resolve ( ) ;
83
+ } ,
84
+ } ) ;
85
+ }
86
+
87
+
22
88
/**
23
89
* Return whether the API will need a token for authorization.
24
90
* If mTLS is in use (as specified by the cert or key files being set) then
25
91
* token authorization is disabled. Otherwise, it is enabled.
26
92
*/
27
93
export function needToken ( ) : boolean {
28
- const cfg = vscode . workspace . getConfiguration ( ) ;
29
- const certFile = expandPath (
30
- String ( cfg . get ( "coder.tlsCertFile" ) ?? "" ) . trim ( ) ,
31
- ) ;
32
- const keyFile = expandPath ( String ( cfg . get ( "coder.tlsKeyFile" ) ?? "" ) . trim ( ) ) ;
33
- return ! certFile && ! keyFile ;
94
+ return ! getCertFilePath ( ) && ! getKeyFilePath ( ) ;
34
95
}
35
96
36
97
/**
37
98
* Create a new agent based off the current settings.
38
99
*/
39
100
export async function createHttpAgent ( ) : Promise < ProxyAgent > {
40
- const cfg = vscode . workspace . getConfiguration ( ) ;
41
- const insecure = Boolean ( cfg . get ( "coder.insecure" ) ) ;
42
- const certFile = expandPath (
43
- String ( cfg . get ( "coder.tlsCertFile" ) ?? "" ) . trim ( ) ,
44
- ) ;
45
- const keyFile = expandPath ( String ( cfg . get ( "coder.tlsKeyFile" ) ?? "" ) . trim ( ) ) ;
46
- const caFile = expandPath ( String ( cfg . get ( "coder.tlsCaFile" ) ?? "" ) . trim ( ) ) ;
47
- const altHost = expandPath ( String ( cfg . get ( "coder.tlsAltHost" ) ?? "" ) . trim ( ) ) ;
101
+ const insecure = Boolean ( config ( "coder.insecure" ) ) ;
102
+ const certFile = getPath ( "coder.tlsCertFile" ) ;
103
+ const keyFile = getPath ( "coder.tlsKeyFile" ) ;
104
+ const caFile = getPath ( "coder.tlsCaFile" ) ;
105
+ const altHost = getHost ( "coder.tlsAltHost" ) ;
48
106
49
107
return new ProxyAgent ( {
50
108
// Called each time a request is made.
51
109
getProxyForUrl : ( url : string ) => {
52
- const cfg = vscode . workspace . getConfiguration ( ) ;
53
110
return getProxyForUrl (
54
111
url ,
55
- cfg . get ( "http.proxy" ) ,
56
- cfg . get ( "coder.proxyBypass" ) ,
112
+ config ( "http.proxy" ) ,
113
+ config ( "coder.proxyBypass" ) ,
57
114
) ;
58
115
} ,
59
- cert : certFile === "" ? undefined : await fs . readFile ( certFile ) ,
60
- key : keyFile === "" ? undefined : await fs . readFile ( keyFile ) ,
61
- ca : caFile === "" ? undefined : await fs . readFile ( caFile ) ,
62
- servername : altHost === "" ? undefined : altHost ,
116
+ cert : await readFile ( certFile ) ,
117
+ key : await readFile ( keyFile ) ,
118
+ ca : await readFile ( caFile ) ,
119
+ servername : checkEmptyString ( altHost ) ,
63
120
// rejectUnauthorized defaults to true, so we need to explicitly set it to
64
121
// false if we want to allow self-signed certificates.
65
122
rejectUnauthorized : ! insecure ,
@@ -127,40 +184,25 @@ export function createStreamingFetchAdapter(axiosInstance: AxiosInstance) {
127
184
responseType : "stream" ,
128
185
validateStatus : ( ) => true , // Don't throw on any status code
129
186
} ) ;
130
- const stream = new ReadableStream ( {
131
- start ( controller ) {
132
- response . data . on ( "data" , ( chunk : Buffer ) => {
133
- controller . enqueue ( chunk ) ;
134
- } ) ;
135
-
136
- response . data . on ( "end" , ( ) => {
137
- controller . close ( ) ;
138
- } ) ;
139
-
140
- response . data . on ( "error" , ( err : Error ) => {
141
- controller . error ( err ) ;
142
- } ) ;
143
- } ,
144
-
145
- cancel ( ) {
146
- response . data . destroy ( ) ;
147
- return Promise . resolve ( ) ;
148
- } ,
149
- } ) ;
187
+ const getHeaderFromResponse = ( name : string ) => {
188
+ const value = response . headers [ name . toLowerCase ( ) ] ;
189
+ return value === undefined ? null : String ( value ) ;
190
+ }
191
+ const getReader = ( ) => getStreamFromResponse ( response ) . getReader ( )
192
+ const body = {
193
+ getReader,
194
+ } ;
195
+ const redirected = response . request . res . responseUrl !== urlStr ;
196
+ const headers = {
197
+ get : getHeaderFromResponse ,
198
+ } ;
150
199
151
200
return {
152
- body : {
153
- getReader : ( ) => stream . getReader ( ) ,
154
- } ,
201
+ body,
155
202
url : urlStr ,
156
203
status : response . status ,
157
- redirected : response . request . res . responseUrl !== urlStr ,
158
- headers : {
159
- get : ( name : string ) => {
160
- const value = response . headers [ name . toLowerCase ( ) ] ;
161
- return value === undefined ? null : String ( value ) ;
162
- } ,
163
- } ,
204
+ redirected,
205
+ headers,
164
206
} ;
165
207
} ;
166
208
}
0 commit comments