1- import { AxiosInstance } from "axios" ;
1+ import { AxiosInstance , AxiosResponse } from "axios" ;
22import { spawn } from "child_process" ;
33import { Api } from "coder/site/src/api/api" ;
44import {
@@ -19,47 +19,104 @@ import { expandPath } from "./util";
1919
2020export const coderSessionTokenHeader = "Coder-Session-Token" ;
2121
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+
2288/**
2389 * Return whether the API will need a token for authorization.
2490 * If mTLS is in use (as specified by the cert or key files being set) then
2591 * token authorization is disabled. Otherwise, it is enabled.
2692 */
2793export 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 ( ) ;
3495}
3596
3697/**
3798 * Create a new agent based off the current settings.
3899 */
39100export 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" ) ;
48106
49107 return new ProxyAgent ( {
50108 // Called each time a request is made.
51109 getProxyForUrl : ( url : string ) => {
52- const cfg = vscode . workspace . getConfiguration ( ) ;
53110 return getProxyForUrl (
54111 url ,
55- cfg . get ( "http.proxy" ) ,
56- cfg . get ( "coder.proxyBypass" ) ,
112+ config ( "http.proxy" ) ,
113+ config ( "coder.proxyBypass" ) ,
57114 ) ;
58115 } ,
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 ) ,
63120 // rejectUnauthorized defaults to true, so we need to explicitly set it to
64121 // false if we want to allow self-signed certificates.
65122 rejectUnauthorized : ! insecure ,
@@ -127,40 +184,25 @@ export function createStreamingFetchAdapter(axiosInstance: AxiosInstance) {
127184 responseType : "stream" ,
128185 validateStatus : ( ) => true , // Don't throw on any status code
129186 } ) ;
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+ } ;
150199
151200 return {
152- body : {
153- getReader : ( ) => stream . getReader ( ) ,
154- } ,
201+ body,
155202 url : urlStr ,
156203 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,
164206 } ;
165207 } ;
166208}
0 commit comments