apply formatting

This commit is contained in:
Bryan MacFarlane 2020-04-10 09:50:06 -04:00
parent c715044f28
commit 7af5adfb99
12 changed files with 1573 additions and 1234 deletions

View File

@ -40,8 +40,8 @@ jobs:
- name: npm test - name: npm test
run: npm test run: npm test
# - name: Format - name: Format
# run: npm run format-check run: npm run format-check
- name: audit security - name: audit security
run: npm audit --audit-level=moderate run: npm audit --audit-level=moderate

View File

@ -1,56 +1,61 @@
import * as httpm from '../_out'; import * as httpm from '../_out'
import * as am from '../_out/auth'; import * as am from '../_out/auth'
describe('auth', () => { describe('auth', () => {
beforeEach(() => { beforeEach(() => {})
}) afterEach(() => {})
afterEach(() => {
}) it('does basic http get request with basic auth', async () => {
let bh: am.BasicCredentialHandler = new am.BasicCredentialHandler(
it('does basic http get request with basic auth', async() => { 'johndoe',
let bh: am.BasicCredentialHandler = new am.BasicCredentialHandler('johndoe', 'password'); 'password'
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [bh]); )
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get'); let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [bh])
expect(res.message.statusCode).toBe(200); let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
let body: string = await res.readBody(); expect(res.message.statusCode).toBe(200)
let obj:any = JSON.parse(body); let body: string = await res.readBody()
let auth: string = obj.headers.Authorization; let obj: any = JSON.parse(body)
let creds: string = Buffer.from(auth.substring('Basic '.length), 'base64').toString(); let auth: string = obj.headers.Authorization
expect(creds).toBe('johndoe:password'); let creds: string = Buffer.from(
expect(obj.url).toBe("http://httpbin.org/get"); auth.substring('Basic '.length),
}); 'base64'
).toString()
expect(creds).toBe('johndoe:password')
expect(obj.url).toBe('http://httpbin.org/get')
})
it('does basic http get request with pat token auth', async() => { it('does basic http get request with pat token auth', async () => {
let token: string = 'scbfb44vxzku5l4xgc3qfazn3lpk4awflfryc76esaiq7aypcbhs'; let token: string = 'scbfb44vxzku5l4xgc3qfazn3lpk4awflfryc76esaiq7aypcbhs'
let ph: am.PersonalAccessTokenCredentialHandler = let ph: am.PersonalAccessTokenCredentialHandler = new am.PersonalAccessTokenCredentialHandler(
new am.PersonalAccessTokenCredentialHandler(token); token
)
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [ph]); let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [ph])
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get'); let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
expect(res.message.statusCode).toBe(200); expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody(); let body: string = await res.readBody()
let obj:any = JSON.parse(body); let obj: any = JSON.parse(body)
let auth: string = obj.headers.Authorization; let auth: string = obj.headers.Authorization
let creds: string = Buffer.from(auth.substring('Basic '.length), 'base64').toString(); let creds: string = Buffer.from(
expect(creds).toBe('PAT:' + token); auth.substring('Basic '.length),
expect(obj.url).toBe("http://httpbin.org/get"); 'base64'
}); ).toString()
expect(creds).toBe('PAT:' + token)
it('does basic http get request with pat token auth', async() => { expect(obj.url).toBe('http://httpbin.org/get')
let token: string = 'scbfb44vxzku5l4xgc3qfazn3lpk4awflfryc76esaiq7aypcbhs'; })
let ph: am.BearerCredentialHandler =
new am.BearerCredentialHandler(token);
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [ph]); it('does basic http get request with pat token auth', async () => {
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get'); let token: string = 'scbfb44vxzku5l4xgc3qfazn3lpk4awflfryc76esaiq7aypcbhs'
expect(res.message.statusCode).toBe(200); let ph: am.BearerCredentialHandler = new am.BearerCredentialHandler(token)
let body: string = await res.readBody();
let obj:any = JSON.parse(body); let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [ph])
let auth: string = obj.headers.Authorization; let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
expect(auth).toBe('Bearer ' + token); expect(res.message.statusCode).toBe(200)
expect(obj.url).toBe("http://httpbin.org/get"); let body: string = await res.readBody()
}); let obj: any = JSON.parse(body)
let auth: string = obj.headers.Authorization
expect(auth).toBe('Bearer ' + token)
expect(obj.url).toBe('http://httpbin.org/get')
})
}) })

View File

@ -1,256 +1,329 @@
import * as httpm from '../_out'; import * as httpm from '../_out'
import * as ifm from '../_out/interfaces' import * as ifm from '../_out/interfaces'
import * as path from 'path'; import * as path from 'path'
import * as fs from 'fs'; import * as fs from 'fs'
let sampleFilePath: string = path.join(__dirname, 'testoutput.txt'); let sampleFilePath: string = path.join(__dirname, 'testoutput.txt')
interface HttpBinData { interface HttpBinData {
url: string; url: string
data: any; data: any
json: any; json: any
headers: any; headers: any
args?: any args?: any
} }
describe('basics', () => { describe('basics', () => {
let _http: httpm.HttpClient; let _http: httpm.HttpClient
beforeEach(() => { beforeEach(() => {
_http = new httpm.HttpClient('http-client-tests'); _http = new httpm.HttpClient('http-client-tests')
})
afterEach(() => {})
it('constructs', () => {
let http: httpm.HttpClient = new httpm.HttpClient('thttp-client-tests')
expect(http).toBeDefined()
})
// responses from httpbin return something like:
// {
// "args": {},
// "headers": {
// "Connection": "close",
// "Host": "httpbin.org",
// "User-Agent": "typed-test-client-tests"
// },
// "origin": "173.95.152.44",
// "url": "https://httpbin.org/get"
// }
it('does basic http get request', async done => {
let res: httpm.HttpClientResponse = await _http.get(
'http://httpbin.org/get'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.headers['User-Agent']).toBeTruthy()
done()
})
it('does basic http get request with no user agent', async done => {
let http: httpm.HttpClient = new httpm.HttpClient()
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(obj.headers['User-Agent']).toBeFalsy()
done()
})
it('does basic https get request', async done => {
let res: httpm.HttpClientResponse = await _http.get(
'https://httpbin.org/get'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
done()
})
it('does basic http get request with default headers', async done => {
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [], {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
}) })
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
afterEach(() => { expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.headers.Accept).toBe('application/json')
expect(obj.headers['Content-Type']).toBe('application/json')
expect(obj.url).toBe('http://httpbin.org/get')
done()
})
it('does basic http get request with merged headers', async done => {
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [], {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
}) })
let res: httpm.HttpClientResponse = await http.get(
it('constructs', () => { 'http://httpbin.org/get',
let http: httpm.HttpClient = new httpm.HttpClient('thttp-client-tests'); {
expect(http).toBeDefined(); 'content-type': 'application/x-www-form-urlencoded'
}); }
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.headers.Accept).toBe('application/json')
expect(obj.headers['Content-Type']).toBe(
'application/x-www-form-urlencoded'
)
expect(obj.url).toBe('http://httpbin.org/get')
done()
})
// responses from httpbin return something like: it('pipes a get request', () => {
// { return new Promise<string>(async (resolve, reject) => {
// "args": {}, let file: NodeJS.WritableStream = fs.createWriteStream(sampleFilePath)
// "headers": { ;(await _http.get('https://httpbin.org/get')).message
// "Connection": "close", .pipe(file)
// "Host": "httpbin.org", .on('close', () => {
// "User-Agent": "typed-test-client-tests" let body: string = fs.readFileSync(sampleFilePath).toString()
// }, let obj: any = JSON.parse(body)
// "origin": "173.95.152.44", expect(obj.url).toBe('https://httpbin.org/get')
// "url": "https://httpbin.org/get" resolve()
// } })
})
})
it('does basic http get request', async(done) => { it('does basic get request with redirects', async done => {
let res: httpm.HttpClientResponse = await _http.get('http://httpbin.org/get'); let res: httpm.HttpClientResponse = await _http.get(
expect(res.message.statusCode).toBe(200); 'https://httpbin.org/redirect-to?url=' +
let body: string = await res.readBody(); encodeURIComponent('https://httpbin.org/get')
let obj: any = JSON.parse(body); )
expect(obj.url).toBe("http://httpbin.org/get"); expect(res.message.statusCode).toBe(200)
expect(obj.headers["User-Agent"]).toBeTruthy(); let body: string = await res.readBody()
done(); let obj: any = JSON.parse(body)
}); expect(obj.url).toBe('https://httpbin.org/get')
done()
it('does basic http get request with no user agent', async(done) => { })
let http: httpm.HttpClient = new httpm.HttpClient();
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get');
expect(res.message.statusCode).toBe(200);
let body: string = await res.readBody();
let obj: any = JSON.parse(body);
expect(obj.url).toBe("http://httpbin.org/get");
expect(obj.headers["User-Agent"]).toBeFalsy();
done();
});
it('does basic https get request', async(done) => { it('does basic get request with redirects (303)', async done => {
let res: httpm.HttpClientResponse = await _http.get('https://httpbin.org/get'); let res: httpm.HttpClientResponse = await _http.get(
expect(res.message.statusCode).toBe(200); 'https://httpbin.org/redirect-to?url=' +
let body: string = await res.readBody(); encodeURIComponent('https://httpbin.org/get') +
let obj: any = JSON.parse(body); '&status_code=303'
expect(obj.url).toBe("https://httpbin.org/get"); )
done(); expect(res.message.statusCode).toBe(200)
}); let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
done()
})
it('does basic http get request with default headers', async(done) => { it('returns 404 for not found get request on redirect', async done => {
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [], { let res: httpm.HttpClientResponse = await _http.get(
headers: { 'https://httpbin.org/redirect-to?url=' +
'Accept': 'application/json', encodeURIComponent('https://httpbin.org/status/404') +
'Content-Type': 'application/json' '&status_code=303'
} )
}); expect(res.message.statusCode).toBe(404)
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get'); let body: string = await res.readBody()
expect(res.message.statusCode).toBe(200); done()
let body: string = await res.readBody(); })
let obj:any = JSON.parse(body);
expect(obj.headers.Accept).toBe('application/json');
expect(obj.headers['Content-Type']).toBe('application/json');
expect(obj.url).toBe("http://httpbin.org/get");
done();
});
it('does basic http get request with merged headers', async(done) => { it('does not follow redirects if disabled', async done => {
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [], { let http: httpm.HttpClient = new httpm.HttpClient(
headers: { 'typed-test-client-tests',
'Accept': 'application/json', null,
'Content-Type': 'application/json' {allowRedirects: false}
} )
}); let res: httpm.HttpClientResponse = await http.get(
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get', { 'https://httpbin.org/redirect-to?url=' +
'content-type': 'application/x-www-form-urlencoded' encodeURIComponent('https://httpbin.org/get')
}); )
expect(res.message.statusCode).toBe(200); expect(res.message.statusCode).toBe(302)
let body: string = await res.readBody(); let body: string = await res.readBody()
let obj:any = JSON.parse(body); done()
expect(obj.headers.Accept).toBe('application/json'); })
expect(obj.headers['Content-Type']).toBe('application/x-www-form-urlencoded');
expect(obj.url).toBe("http://httpbin.org/get");
done();
});
it('pipes a get request', () => { it('does basic head request', async done => {
return new Promise<string>(async (resolve, reject) => { let res: httpm.HttpClientResponse = await _http.head(
let file: NodeJS.WritableStream = fs.createWriteStream(sampleFilePath); 'http://httpbin.org/get'
(await _http.get('https://httpbin.org/get')).message.pipe(file).on('close', () => { )
let body: string = fs.readFileSync(sampleFilePath).toString(); expect(res.message.statusCode).toBe(200)
let obj:any = JSON.parse(body); done()
expect(obj.url).toBe("https://httpbin.org/get"); })
resolve();
});
});
});
it('does basic get request with redirects', async(done) => {
let res: httpm.HttpClientResponse = await _http.get("https://httpbin.org/redirect-to?url=" + encodeURIComponent("https://httpbin.org/get"))
expect(res.message.statusCode).toBe(200);
let body: string = await res.readBody();
let obj:any = JSON.parse(body);
expect(obj.url).toBe("https://httpbin.org/get");
done();
});
it('does basic get request with redirects (303)', async(done) => { it('does basic http delete request', async done => {
let res: httpm.HttpClientResponse = await _http.get("https://httpbin.org/redirect-to?url=" + encodeURIComponent("https://httpbin.org/get") + '&status_code=303') let res: httpm.HttpClientResponse = await _http.del(
expect(res.message.statusCode).toBe(200); 'http://httpbin.org/delete'
let body: string = await res.readBody(); )
let obj:any = JSON.parse(body); expect(res.message.statusCode).toBe(200)
expect(obj.url).toBe("https://httpbin.org/get"); let body: string = await res.readBody()
done(); let obj: any = JSON.parse(body)
}); done()
})
it('returns 404 for not found get request on redirect', async(done) => { it('does basic http post request', async done => {
let res: httpm.HttpClientResponse = await _http.get("https://httpbin.org/redirect-to?url=" + encodeURIComponent("https://httpbin.org/status/404") + '&status_code=303') let b: string = 'Hello World!'
expect(res.message.statusCode).toBe(404); let res: httpm.HttpClientResponse = await _http.post(
let body: string = await res.readBody(); 'http://httpbin.org/post',
done(); b
}); )
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/post')
done()
})
it('does not follow redirects if disabled', async(done) => { it('does basic http patch request', async done => {
let http: httpm.HttpClient = new httpm.HttpClient('typed-test-client-tests', null, { allowRedirects: false }); let b: string = 'Hello World!'
let res: httpm.HttpClientResponse = await http.get("https://httpbin.org/redirect-to?url=" + encodeURIComponent("https://httpbin.org/get")) let res: httpm.HttpClientResponse = await _http.patch(
expect(res.message.statusCode).toBe(302); 'http://httpbin.org/patch',
let body: string = await res.readBody(); b
done(); )
}); expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/patch')
done()
})
it('does basic head request', async(done) => { it('does basic http options request', async done => {
let res: httpm.HttpClientResponse = await _http.head('http://httpbin.org/get'); let res: httpm.HttpClientResponse = await _http.options(
expect(res.message.statusCode).toBe(200); 'http://httpbin.org'
done(); )
}); expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
done()
})
it('does basic http delete request', async(done) => { it('returns 404 for not found get request', async done => {
let res: httpm.HttpClientResponse = await _http.del('http://httpbin.org/delete'); let res: httpm.HttpClientResponse = await _http.get(
expect(res.message.statusCode).toBe(200); 'http://httpbin.org/status/404'
let body: string = await res.readBody(); )
let obj:any = JSON.parse(body); expect(res.message.statusCode).toBe(404)
done(); let body: string = await res.readBody()
}); done()
})
it('does basic http post request', async(done) => { it('gets a json object', async () => {
let b: string = 'Hello World!'; let jsonObj: ifm.ITypedResponse<HttpBinData> = await _http.getJson<
let res: httpm.HttpClientResponse = await _http.post('http://httpbin.org/post', b); HttpBinData
expect(res.message.statusCode).toBe(200); >('https://httpbin.org/get')
let body: string = await res.readBody(); expect(jsonObj.statusCode).toBe(200)
let obj:any = JSON.parse(body); expect(jsonObj.result).toBeDefined()
expect(obj.data).toBe(b); expect(jsonObj.result.url).toBe('https://httpbin.org/get')
expect(obj.url).toBe("http://httpbin.org/post"); expect(jsonObj.result.headers['Accept']).toBe(
done(); httpm.MediaTypes.ApplicationJson
}); )
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
})
it('does basic http patch request', async(done) => { it('getting a non existent json object returns null', async () => {
let b: string = 'Hello World!'; let jsonObj: ifm.ITypedResponse<HttpBinData> = await _http.getJson<
let res: httpm.HttpClientResponse = await _http.patch('http://httpbin.org/patch', b); HttpBinData
expect(res.message.statusCode).toBe(200); >('https://httpbin.org/status/404')
let body: string = await res.readBody(); expect(jsonObj.statusCode).toBe(404)
let obj:any = JSON.parse(body); expect(jsonObj.result).toBeNull()
expect(obj.data).toBe(b); })
expect(obj.url).toBe("http://httpbin.org/patch");
done();
});
it('does basic http options request', async(done) => {
let res: httpm.HttpClientResponse = await _http.options('http://httpbin.org');
expect(res.message.statusCode).toBe(200);
let body: string = await res.readBody();
done();
});
it('returns 404 for not found get request', async(done) => {
let res: httpm.HttpClientResponse = await _http.get('http://httpbin.org/status/404');
expect(res.message.statusCode).toBe(404);
let body: string = await res.readBody();
done();
});
it('gets a json object', async() => {
let jsonObj: ifm.ITypedResponse<HttpBinData> = await _http.getJson<HttpBinData>('https://httpbin.org/get');
expect(jsonObj.statusCode).toBe(200);
expect(jsonObj.result).toBeDefined();
expect(jsonObj.result.url).toBe('https://httpbin.org/get');
expect(jsonObj.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson);
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson);
});
it('getting a non existent json object returns null', async() => {
let jsonObj: ifm.ITypedResponse<HttpBinData> = await _http.getJson<HttpBinData>('https://httpbin.org/status/404');
expect(jsonObj.statusCode).toBe(404);
expect(jsonObj.result).toBeNull();
});
it('posts a json object', async() => { it('posts a json object', async () => {
let res: any = { name: 'foo' }; let res: any = {name: 'foo'}
let restRes: ifm.ITypedResponse<HttpBinData> = await _http.postJson<HttpBinData>('https://httpbin.org/post', res); let restRes: ifm.ITypedResponse<HttpBinData> = await _http.postJson<
expect(restRes.statusCode).toBe(200); HttpBinData
expect(restRes.result).toBeDefined(); >('https://httpbin.org/post', res)
expect(restRes.result.url).toBe('https://httpbin.org/post'); expect(restRes.statusCode).toBe(200)
expect(restRes.result.json.name).toBe('foo'); expect(restRes.result).toBeDefined()
expect(restRes.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); expect(restRes.result.url).toBe('https://httpbin.org/post')
expect(restRes.result.headers["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson); expect(restRes.result.json.name).toBe('foo')
expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); expect(restRes.result.headers['Accept']).toBe(
}); httpm.MediaTypes.ApplicationJson
)
expect(restRes.result.headers['Content-Type']).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
})
it('puts a json object', async() => { it('puts a json object', async () => {
let res: any = { name: 'foo' }; let res: any = {name: 'foo'}
let restRes: ifm.ITypedResponse<HttpBinData> = await _http.putJson<HttpBinData>('https://httpbin.org/put', res); let restRes: ifm.ITypedResponse<HttpBinData> = await _http.putJson<
expect(restRes.statusCode).toBe(200); HttpBinData
expect(restRes.result).toBeDefined(); >('https://httpbin.org/put', res)
expect(restRes.result.url).toBe('https://httpbin.org/put'); expect(restRes.statusCode).toBe(200)
expect(restRes.result.json.name).toBe('foo'); expect(restRes.result).toBeDefined()
expect(restRes.result.url).toBe('https://httpbin.org/put')
expect(restRes.result.json.name).toBe('foo')
expect(restRes.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); expect(restRes.result.headers['Accept']).toBe(
expect(restRes.result.headers["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson); httpm.MediaTypes.ApplicationJson
expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); )
}); expect(restRes.result.headers['Content-Type']).toBe(
httpm.MediaTypes.ApplicationJson
it('patch a json object', async() => { )
let res: any = { name: 'foo' }; expect(restRes.headers[httpm.Headers.ContentType]).toBe(
let restRes: ifm.ITypedResponse<HttpBinData> = await _http.patchJson<HttpBinData>('https://httpbin.org/patch', res); httpm.MediaTypes.ApplicationJson
expect(restRes.statusCode).toBe(200); )
expect(restRes.result).toBeDefined(); })
expect(restRes.result.url).toBe('https://httpbin.org/patch');
expect(restRes.result.json.name).toBe('foo'); it('patch a json object', async () => {
expect(restRes.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); let res: any = {name: 'foo'}
expect(restRes.result.headers["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson); let restRes: ifm.ITypedResponse<HttpBinData> = await _http.patchJson<
expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); HttpBinData
}); >('https://httpbin.org/patch', res)
}); expect(restRes.statusCode).toBe(200)
expect(restRes.result).toBeDefined()
expect(restRes.result.url).toBe('https://httpbin.org/patch')
expect(restRes.result.json.name).toBe('foo')
expect(restRes.result.headers['Accept']).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.result.headers['Content-Type']).toBe(
httpm.MediaTypes.ApplicationJson
)
expect(restRes.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
})
})

View File

@ -1,79 +1,115 @@
import * as httpm from '../_out'; import * as httpm from '../_out'
import * as ifm from '../_out/interfaces' import * as ifm from '../_out/interfaces'
describe('headers', () => { describe('headers', () => {
let _http: httpm.HttpClient; let _http: httpm.HttpClient
beforeEach(() => { beforeEach(() => {
_http = new httpm.HttpClient('http-client-tests'); _http = new httpm.HttpClient('http-client-tests')
}); })
it('preserves existing headers on getJson', async() => { it('preserves existing headers on getJson', async () => {
let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; let additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj: ifm.ITypedResponse<any> = await _http.getJson<any>('https://httpbin.org/get', additionalHeaders); let jsonObj: ifm.ITypedResponse<any> = await _http.getJson<any>(
expect(jsonObj.result.headers["Accept"]).toBe("foo"); 'https://httpbin.org/get',
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
let httpWithHeaders = new httpm.HttpClient(); let httpWithHeaders = new httpm.HttpClient()
httpWithHeaders.requestOptions = { httpWithHeaders.requestOptions = {
headers: { headers: {
[httpm.Headers.Accept]: "baz" [httpm.Headers.Accept]: 'baz'
} }
}; }
jsonObj = await httpWithHeaders.getJson<any>('https://httpbin.org/get'); jsonObj = await httpWithHeaders.getJson<any>('https://httpbin.org/get')
expect(jsonObj.result.headers["Accept"]).toBe("baz"); expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
}); httpm.MediaTypes.ApplicationJson
)
})
it('preserves existing headers on postJson', async() => { it('preserves existing headers on postJson', async () => {
let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; let additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj: ifm.ITypedResponse<any> = await _http.postJson<any>('https://httpbin.org/post', {}, additionalHeaders); let jsonObj: ifm.ITypedResponse<any> = await _http.postJson<any>(
expect(jsonObj.result.headers["Accept"]).toBe("foo"); 'https://httpbin.org/post',
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); {},
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
let httpWithHeaders = new httpm.HttpClient(); let httpWithHeaders = new httpm.HttpClient()
httpWithHeaders.requestOptions = { httpWithHeaders.requestOptions = {
headers: { headers: {
[httpm.Headers.Accept]: "baz" [httpm.Headers.Accept]: 'baz'
} }
}; }
jsonObj = await httpWithHeaders.postJson<any>('https://httpbin.org/post', {}); jsonObj = await httpWithHeaders.postJson<any>(
expect(jsonObj.result.headers["Accept"]).toBe("baz"); 'https://httpbin.org/post',
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); {}
}); )
expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
})
it('preserves existing headers on putJson', async() => { it('preserves existing headers on putJson', async () => {
let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; let additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj: ifm.ITypedResponse<any> = await _http.putJson<any>('https://httpbin.org/put', {}, additionalHeaders); let jsonObj: ifm.ITypedResponse<any> = await _http.putJson<any>(
expect(jsonObj.result.headers["Accept"]).toBe("foo"); 'https://httpbin.org/put',
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); {},
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
let httpWithHeaders = new httpm.HttpClient(); let httpWithHeaders = new httpm.HttpClient()
httpWithHeaders.requestOptions = { httpWithHeaders.requestOptions = {
headers: { headers: {
[httpm.Headers.Accept]: "baz" [httpm.Headers.Accept]: 'baz'
} }
}; }
jsonObj = await httpWithHeaders.putJson<any>('https://httpbin.org/put', {}); jsonObj = await httpWithHeaders.putJson<any>('https://httpbin.org/put', {})
expect(jsonObj.result.headers["Accept"]).toBe("baz"); expect(jsonObj.result.headers['Accept']).toBe('baz')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
}); httpm.MediaTypes.ApplicationJson
)
})
it('preserves existing headers on patchJson', async() => { it('preserves existing headers on patchJson', async () => {
let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; let additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
let jsonObj: ifm.ITypedResponse<any> = await _http.patchJson<any>('https://httpbin.org/patch', {}, additionalHeaders); let jsonObj: ifm.ITypedResponse<any> = await _http.patchJson<any>(
expect(jsonObj.result.headers["Accept"]).toBe("foo"); 'https://httpbin.org/patch',
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); {},
additionalHeaders
)
expect(jsonObj.result.headers['Accept']).toBe('foo')
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
let httpWithHeaders = new httpm.HttpClient(); let httpWithHeaders = new httpm.HttpClient()
httpWithHeaders.requestOptions = { httpWithHeaders.requestOptions = {
headers: { headers: {
[httpm.Headers.Accept]: "baz" [httpm.Headers.Accept]: 'baz'
} }
}; }
jsonObj = await httpWithHeaders.patchJson<any>('https://httpbin.org/patch', {}); jsonObj = await httpWithHeaders.patchJson<any>(
expect(jsonObj.result.headers["Accept"]).toBe("baz"); 'https://httpbin.org/patch',
expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); {}
}); )
expect(jsonObj.result.headers['Accept']).toBe('baz')
}); expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(
httpm.MediaTypes.ApplicationJson
)
})
})

View File

@ -1,65 +1,79 @@
import * as httpm from '../_out'; import * as httpm from '../_out'
describe('basics', () => { describe('basics', () => {
let _http: httpm.HttpClient; let _http: httpm.HttpClient
beforeEach(() => { beforeEach(() => {
_http = new httpm.HttpClient('http-client-tests', [], { keepAlive: true }); _http = new httpm.HttpClient('http-client-tests', [], {keepAlive: true})
}) })
afterEach(() => {
_http.dispose();
})
it('does basic http get request with keepAlive true', async(done) => {
let res: httpm.HttpClientResponse = await _http.get('http://httpbin.org/get');
expect(res.message.statusCode).toBe(200);
let body: string = await res.readBody();
let obj:any = JSON.parse(body);
expect(obj.url).toBe("http://httpbin.org/get");
done();
});
it('does basic head request with keepAlive true', async(done) => { afterEach(() => {
let res: httpm.HttpClientResponse = await _http.head('http://httpbin.org/get'); _http.dispose()
expect(res.message.statusCode).toBe(200); })
done();
});
it('does basic http delete request with keepAlive true', async(done) => { it('does basic http get request with keepAlive true', async done => {
let res: httpm.HttpClientResponse = await _http.del('http://httpbin.org/delete'); let res: httpm.HttpClientResponse = await _http.get(
expect(res.message.statusCode).toBe(200); 'http://httpbin.org/get'
let body: string = await res.readBody(); )
let obj:any = JSON.parse(body); expect(res.message.statusCode).toBe(200)
done(); let body: string = await res.readBody()
}); let obj: any = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
it('does basic http post request with keepAlive true', async(done) => { done()
let b: string = 'Hello World!'; })
let res: httpm.HttpClientResponse = await _http.post('http://httpbin.org/post', b);
expect(res.message.statusCode).toBe(200); it('does basic head request with keepAlive true', async done => {
let body: string = await res.readBody(); let res: httpm.HttpClientResponse = await _http.head(
let obj:any = JSON.parse(body); 'http://httpbin.org/get'
expect(obj.data).toBe(b); )
expect(obj.url).toBe("http://httpbin.org/post"); expect(res.message.statusCode).toBe(200)
done(); done()
}); })
it('does basic http patch request with keepAlive true', async(done) => { it('does basic http delete request with keepAlive true', async done => {
let b: string = 'Hello World!'; let res: httpm.HttpClientResponse = await _http.del(
let res: httpm.HttpClientResponse = await _http.patch('http://httpbin.org/patch', b); 'http://httpbin.org/delete'
expect(res.message.statusCode).toBe(200); )
let body: string = await res.readBody(); expect(res.message.statusCode).toBe(200)
let obj:any = JSON.parse(body); let body: string = await res.readBody()
expect(obj.data).toBe(b); let obj: any = JSON.parse(body)
expect(obj.url).toBe("http://httpbin.org/patch"); done()
done(); })
});
it('does basic http post request with keepAlive true', async done => {
it('does basic http options request with keepAlive true', async(done) => { let b: string = 'Hello World!'
let res: httpm.HttpClientResponse = await _http.options('http://httpbin.org'); let res: httpm.HttpClientResponse = await _http.post(
expect(res.message.statusCode).toBe(200); 'http://httpbin.org/post',
let body: string = await res.readBody(); b
done(); )
}); expect(res.message.statusCode).toBe(200)
}); let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/post')
done()
})
it('does basic http patch request with keepAlive true', async done => {
let b: string = 'Hello World!'
let res: httpm.HttpClientResponse = await _http.patch(
'http://httpbin.org/patch',
b
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.data).toBe(b)
expect(obj.url).toBe('http://httpbin.org/patch')
done()
})
it('does basic http options request with keepAlive true', async done => {
let res: httpm.HttpClientResponse = await _http.options(
'http://httpbin.org'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
done()
})
})

View File

@ -1,201 +1,208 @@
import * as http from 'http' import * as http from 'http'
import * as httpm from '../_out'; import * as httpm from '../_out'
import * as pm from '../_out/proxy'; import * as pm from '../_out/proxy'
import * as proxy from 'proxy' import * as proxy from 'proxy'
import * as url from 'url'; import * as url from 'url'
let _proxyConnects: string[] let _proxyConnects: string[]
let _proxyServer: http.Server let _proxyServer: http.Server
let _proxyUrl = 'http://127.0.0.1:8080' let _proxyUrl = 'http://127.0.0.1:8080'
describe('proxy', () => { describe('proxy', () => {
beforeAll(async () => { beforeAll(async () => {
// Start proxy server // Start proxy server
_proxyServer = proxy() _proxyServer = proxy()
await new Promise((resolve) => { await new Promise(resolve => {
const port = Number(_proxyUrl.split(':')[2]) const port = Number(_proxyUrl.split(':')[2])
_proxyServer.listen(port, () => resolve()) _proxyServer.listen(port, () => resolve())
})
_proxyServer.on('connect', (req) => {
_proxyConnects.push(req.url)
});
}) })
_proxyServer.on('connect', req => {
_proxyConnects.push(req.url)
})
})
beforeEach(() => { beforeEach(() => {
_proxyConnects = [] _proxyConnects = []
_clearVars() _clearVars()
}) })
afterEach(() => {
})
afterAll(async() => { afterEach(() => {})
_clearVars()
// Stop proxy server afterAll(async () => {
await new Promise((resolve) => { _clearVars()
_proxyServer.once('close', () => resolve())
_proxyServer.close()
})
})
it('getProxyUrl does not return proxyUrl if variables not set', () => { // Stop proxy server
let proxyUrl = pm.getProxyUrl(url.parse('https://github.com')); await new Promise(resolve => {
expect(proxyUrl).toBeUndefined(); _proxyServer.once('close', () => resolve())
_proxyServer.close()
}) })
})
it('getProxyUrl returns proxyUrl if https_proxy set for https url', () => { it('getProxyUrl does not return proxyUrl if variables not set', () => {
process.env["https_proxy"] = "https://myproxysvr"; let proxyUrl = pm.getProxyUrl(url.parse('https://github.com'))
let proxyUrl = pm.getProxyUrl(url.parse('https://github.com')); expect(proxyUrl).toBeUndefined()
expect(proxyUrl).toBeDefined(); })
})
it('getProxyUrl does not return proxyUrl if http_proxy set for https url', () => { it('getProxyUrl returns proxyUrl if https_proxy set for https url', () => {
process.env["http_proxy"] = "https://myproxysvr"; process.env['https_proxy'] = 'https://myproxysvr'
let proxyUrl = pm.getProxyUrl(url.parse('https://github.com')); let proxyUrl = pm.getProxyUrl(url.parse('https://github.com'))
expect(proxyUrl).toBeUndefined(); expect(proxyUrl).toBeDefined()
}) })
it('getProxyUrl returns proxyUrl if http_proxy set for http url', () => {
process.env["http_proxy"] = "http://myproxysvr";
let proxyUrl = pm.getProxyUrl(url.parse('http://github.com'));
expect(proxyUrl).toBeDefined();
})
it('getProxyUrl does not return proxyUrl if https_proxy set and in no_proxy list', () => { it('getProxyUrl does not return proxyUrl if http_proxy set for https url', () => {
process.env["https_proxy"] = "https://myproxysvr"; process.env['http_proxy'] = 'https://myproxysvr'
process.env["no_proxy"] = "otherserver,myserver,anotherserver:8080" let proxyUrl = pm.getProxyUrl(url.parse('https://github.com'))
let proxyUrl = pm.getProxyUrl(url.parse('https://myserver')); expect(proxyUrl).toBeUndefined()
expect(proxyUrl).toBeUndefined(); })
})
it('getProxyUrl returns proxyUrl if https_proxy set and not in no_proxy list', () => { it('getProxyUrl returns proxyUrl if http_proxy set for http url', () => {
process.env["https_proxy"] = "https://myproxysvr"; process.env['http_proxy'] = 'http://myproxysvr'
process.env["no_proxy"] = "otherserver,myserver,anotherserver:8080" let proxyUrl = pm.getProxyUrl(url.parse('http://github.com'))
let proxyUrl = pm.getProxyUrl(url.parse('https://github.com')); expect(proxyUrl).toBeDefined()
expect(proxyUrl).toBeDefined(); })
})
it('getProxyUrl does not return proxyUrl if http_proxy set and in no_proxy list', () => { it('getProxyUrl does not return proxyUrl if https_proxy set and in no_proxy list', () => {
process.env["http_proxy"] = "http://myproxysvr"; process.env['https_proxy'] = 'https://myproxysvr'
process.env["no_proxy"] = "otherserver,myserver,anotherserver:8080" process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(url.parse('http://myserver')); let proxyUrl = pm.getProxyUrl(url.parse('https://myserver'))
expect(proxyUrl).toBeUndefined(); expect(proxyUrl).toBeUndefined()
}) })
it('getProxyUrl returns proxyUrl if http_proxy set and not in no_proxy list', () => { it('getProxyUrl returns proxyUrl if https_proxy set and not in no_proxy list', () => {
process.env["http_proxy"] = "http://myproxysvr"; process.env['https_proxy'] = 'https://myproxysvr'
process.env["no_proxy"] = "otherserver,myserver,anotherserver:8080" process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(url.parse('http://github.com')); let proxyUrl = pm.getProxyUrl(url.parse('https://github.com'))
expect(proxyUrl).toBeDefined(); expect(proxyUrl).toBeDefined()
}) })
it('checkBypass returns true if host as no_proxy list', () => { it('getProxyUrl does not return proxyUrl if http_proxy set and in no_proxy list', () => {
process.env["no_proxy"] = "myserver" process.env['http_proxy'] = 'http://myproxysvr'
let bypass = pm.checkBypass(url.parse('https://myserver')); process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
expect(bypass).toBeTruthy(); let proxyUrl = pm.getProxyUrl(url.parse('http://myserver'))
}) expect(proxyUrl).toBeUndefined()
})
it('checkBypass returns true if host in no_proxy list', () => { it('getProxyUrl returns proxyUrl if http_proxy set and not in no_proxy list', () => {
process.env["no_proxy"] = "otherserver,myserver,anotherserver:8080" process.env['http_proxy'] = 'http://myproxysvr'
let bypass = pm.checkBypass(url.parse('https://myserver')); process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
expect(bypass).toBeTruthy(); let proxyUrl = pm.getProxyUrl(url.parse('http://github.com'))
}) expect(proxyUrl).toBeDefined()
})
it('checkBypass returns true if host in no_proxy list with spaces', () => {
process.env["no_proxy"] = "otherserver, myserver ,anotherserver:8080"
let bypass = pm.checkBypass(url.parse('https://myserver'));
expect(bypass).toBeTruthy();
})
it('checkBypass returns true if host in no_proxy list with port', () => {
process.env["no_proxy"] = "otherserver, myserver:8080 ,anotherserver"
let bypass = pm.checkBypass(url.parse('https://myserver:8080'));
expect(bypass).toBeTruthy();
})
it('checkBypass returns true if host with port in no_proxy list without port', () => { it('checkBypass returns true if host as no_proxy list', () => {
process.env["no_proxy"] = "otherserver, myserver ,anotherserver" process.env['no_proxy'] = 'myserver'
let bypass = pm.checkBypass(url.parse('https://myserver:8080')); let bypass = pm.checkBypass(url.parse('https://myserver'))
expect(bypass).toBeTruthy(); expect(bypass).toBeTruthy()
}) })
it('checkBypass returns true if host in no_proxy list with default https port', () => { it('checkBypass returns true if host in no_proxy list', () => {
process.env["no_proxy"] = "otherserver, myserver:443 ,anotherserver" process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let bypass = pm.checkBypass(url.parse('https://myserver')); let bypass = pm.checkBypass(url.parse('https://myserver'))
expect(bypass).toBeTruthy(); expect(bypass).toBeTruthy()
}) })
it('checkBypass returns true if host in no_proxy list with default http port', () => { it('checkBypass returns true if host in no_proxy list with spaces', () => {
process.env["no_proxy"] = "otherserver, myserver:80 ,anotherserver" process.env['no_proxy'] = 'otherserver, myserver ,anotherserver:8080'
let bypass = pm.checkBypass(url.parse('http://myserver')); let bypass = pm.checkBypass(url.parse('https://myserver'))
expect(bypass).toBeTruthy(); expect(bypass).toBeTruthy()
}) })
it('checkBypass returns false if host not in no_proxy list', () => { it('checkBypass returns true if host in no_proxy list with port', () => {
process.env["no_proxy"] = "otherserver, myserver ,anotherserver:8080" process.env['no_proxy'] = 'otherserver, myserver:8080 ,anotherserver'
let bypass = pm.checkBypass(url.parse('https://github.com')); let bypass = pm.checkBypass(url.parse('https://myserver:8080'))
expect(bypass).toBeFalsy(); expect(bypass).toBeTruthy()
}) })
it('checkBypass returns false if empty no_proxy', () => {
process.env["no_proxy"] = ""
let bypass = pm.checkBypass(url.parse('https://github.com'));
expect(bypass).toBeFalsy();
})
it('HttpClient does basic http get request through proxy', async () => { it('checkBypass returns true if host with port in no_proxy list without port', () => {
process.env['http_proxy'] = _proxyUrl process.env['no_proxy'] = 'otherserver, myserver ,anotherserver'
const httpClient = new httpm.HttpClient(); let bypass = pm.checkBypass(url.parse('https://myserver:8080'))
let res: httpm.HttpClientResponse = await httpClient.get('http://httpbin.org/get'); expect(bypass).toBeTruthy()
expect(res.message.statusCode).toBe(200); })
let body: string = await res.readBody();
let obj: any = JSON.parse(body);
expect(obj.url).toBe("http://httpbin.org/get");
expect(_proxyConnects).toEqual(['httpbin.org:80'])
})
it('HttoClient does basic http get request when bypass proxy', async () => { it('checkBypass returns true if host in no_proxy list with default https port', () => {
process.env['http_proxy'] = _proxyUrl process.env['no_proxy'] = 'otherserver, myserver:443 ,anotherserver'
process.env['no_proxy'] = 'httpbin.org' let bypass = pm.checkBypass(url.parse('https://myserver'))
const httpClient = new httpm.HttpClient(); expect(bypass).toBeTruthy()
let res: httpm.HttpClientResponse = await httpClient.get('http://httpbin.org/get'); })
expect(res.message.statusCode).toBe(200);
let body: string = await res.readBody();
let obj: any = JSON.parse(body);
expect(obj.url).toBe("http://httpbin.org/get");
expect(_proxyConnects).toHaveLength(0)
})
it('HttpClient does basic https get request through proxy', async () => { it('checkBypass returns true if host in no_proxy list with default http port', () => {
process.env['https_proxy'] = _proxyUrl process.env['no_proxy'] = 'otherserver, myserver:80 ,anotherserver'
const httpClient = new httpm.HttpClient(); let bypass = pm.checkBypass(url.parse('http://myserver'))
let res: httpm.HttpClientResponse = await httpClient.get('https://httpbin.org/get'); expect(bypass).toBeTruthy()
expect(res.message.statusCode).toBe(200); })
let body: string = await res.readBody();
let obj: any = JSON.parse(body);
expect(obj.url).toBe("https://httpbin.org/get");
expect(_proxyConnects).toEqual(['httpbin.org:443'])
})
it('HttpClient does basic https get request when bypass proxy', async () => { it('checkBypass returns false if host not in no_proxy list', () => {
process.env['https_proxy'] = _proxyUrl process.env['no_proxy'] = 'otherserver, myserver ,anotherserver:8080'
process.env['no_proxy'] = 'httpbin.org' let bypass = pm.checkBypass(url.parse('https://github.com'))
const httpClient = new httpm.HttpClient(); expect(bypass).toBeFalsy()
let res: httpm.HttpClientResponse = await httpClient.get('https://httpbin.org/get'); })
expect(res.message.statusCode).toBe(200);
let body: string = await res.readBody(); it('checkBypass returns false if empty no_proxy', () => {
let obj: any = JSON.parse(body); process.env['no_proxy'] = ''
expect(obj.url).toBe("https://httpbin.org/get"); let bypass = pm.checkBypass(url.parse('https://github.com'))
expect(_proxyConnects).toHaveLength(0) expect(bypass).toBeFalsy()
}) })
it('HttpClient does basic http get request through proxy', async () => {
process.env['http_proxy'] = _proxyUrl
const httpClient = new httpm.HttpClient()
let res: httpm.HttpClientResponse = await httpClient.get(
'http://httpbin.org/get'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(_proxyConnects).toEqual(['httpbin.org:80'])
})
it('HttoClient does basic http get request when bypass proxy', async () => {
process.env['http_proxy'] = _proxyUrl
process.env['no_proxy'] = 'httpbin.org'
const httpClient = new httpm.HttpClient()
let res: httpm.HttpClientResponse = await httpClient.get(
'http://httpbin.org/get'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('http://httpbin.org/get')
expect(_proxyConnects).toHaveLength(0)
})
it('HttpClient does basic https get request through proxy', async () => {
process.env['https_proxy'] = _proxyUrl
const httpClient = new httpm.HttpClient()
let res: httpm.HttpClientResponse = await httpClient.get(
'https://httpbin.org/get'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(_proxyConnects).toEqual(['httpbin.org:443'])
})
it('HttpClient does basic https get request when bypass proxy', async () => {
process.env['https_proxy'] = _proxyUrl
process.env['no_proxy'] = 'httpbin.org'
const httpClient = new httpm.HttpClient()
let res: httpm.HttpClientResponse = await httpClient.get(
'https://httpbin.org/get'
)
expect(res.message.statusCode).toBe(200)
let body: string = await res.readBody()
let obj: any = JSON.parse(body)
expect(obj.url).toBe('https://httpbin.org/get')
expect(_proxyConnects).toHaveLength(0)
})
}) })
function _clearVars() { function _clearVars() {
delete process.env.http_proxy; delete process.env.http_proxy
delete process.env.HTTP_PROXY; delete process.env.HTTP_PROXY
delete process.env.https_proxy; delete process.env.https_proxy
delete process.env.HTTPS_PROXY; delete process.env.HTTPS_PROXY
delete process.env.no_proxy; delete process.env.no_proxy
delete process.env.NO_PROXY; delete process.env.NO_PROXY
} }

117
auth.ts
View File

@ -1,71 +1,86 @@
import ifm = require('./interfaces')
import ifm = require('./interfaces');
export class BasicCredentialHandler implements ifm.IRequestHandler { export class BasicCredentialHandler implements ifm.IRequestHandler {
username: string; username: string
password: string; password: string
constructor(username: string, password: string) { constructor(username: string, password: string) {
this.username = username; this.username = username
this.password = password; this.password = password
} }
prepareRequest(options:any): void { prepareRequest(options: any): void {
options.headers['Authorization'] = 'Basic ' + Buffer.from(this.username + ':' + this.password).toString('base64'); options.headers['Authorization'] =
} 'Basic ' +
Buffer.from(this.username + ':' + this.password).toString('base64')
}
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response: ifm.IHttpClientResponse): boolean { canHandleAuthentication(response: ifm.IHttpClientResponse): boolean {
return false; return false
} }
handleAuthentication(httpClient: ifm.IHttpClient, requestInfo: ifm.IRequestInfo, objs): Promise<ifm.IHttpClientResponse> { handleAuthentication(
return null; httpClient: ifm.IHttpClient,
} requestInfo: ifm.IRequestInfo,
objs
): Promise<ifm.IHttpClientResponse> {
return null
}
} }
export class BearerCredentialHandler implements ifm.IRequestHandler { export class BearerCredentialHandler implements ifm.IRequestHandler {
token: string; token: string
constructor(token: string) { constructor(token: string) {
this.token = token; this.token = token
} }
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options:any): void { prepareRequest(options: any): void {
options.headers['Authorization'] = 'Bearer ' + this.token; options.headers['Authorization'] = 'Bearer ' + this.token
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response: ifm.IHttpClientResponse): boolean { canHandleAuthentication(response: ifm.IHttpClientResponse): boolean {
return false; return false
} }
handleAuthentication(httpClient: ifm.IHttpClient, requestInfo: ifm.IRequestInfo, objs): Promise<ifm.IHttpClientResponse> { handleAuthentication(
return null; httpClient: ifm.IHttpClient,
} requestInfo: ifm.IRequestInfo,
objs
): Promise<ifm.IHttpClientResponse> {
return null
}
} }
export class PersonalAccessTokenCredentialHandler implements ifm.IRequestHandler { export class PersonalAccessTokenCredentialHandler
token: string; implements ifm.IRequestHandler {
token: string
constructor(token: string) { constructor(token: string) {
this.token = token; this.token = token
} }
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options:any): void { prepareRequest(options: any): void {
options.headers['Authorization'] = 'Basic ' + Buffer.from('PAT:' + this.token).toString('base64'); options.headers['Authorization'] =
} 'Basic ' + Buffer.from('PAT:' + this.token).toString('base64')
}
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response: ifm.IHttpClientResponse): boolean { canHandleAuthentication(response: ifm.IHttpClientResponse): boolean {
return false; return false
} }
handleAuthentication(httpClient: ifm.IHttpClient, requestInfo: ifm.IRequestInfo, objs): Promise<ifm.IHttpClientResponse> { handleAuthentication(
return null; httpClient: ifm.IHttpClient,
} requestInfo: ifm.IRequestInfo,
objs
): Promise<ifm.IHttpClientResponse> {
return null
}
} }

1178
index.ts

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +1,99 @@
import http = require("http"); import http = require('http')
import url = require("url"); import url = require('url')
export interface IHeaders { [key: string]: any }; export interface IHeaders {
[key: string]: any
}
export interface IHttpClient { export interface IHttpClient {
options(requestUrl: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; options(
get(requestUrl: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; requestUrl: string,
del(requestUrl: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; additionalHeaders?: IHeaders
post(requestUrl: string, data: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; ): Promise<IHttpClientResponse>
patch(requestUrl: string, data: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; get(
put(requestUrl: string, data: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; requestUrl: string,
sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; additionalHeaders?: IHeaders
request(verb: string, requestUrl: string, data: string | NodeJS.ReadableStream, headers: IHeaders): Promise<IHttpClientResponse>; ): Promise<IHttpClientResponse>
requestRaw(info: IRequestInfo, data: string | NodeJS.ReadableStream): Promise<IHttpClientResponse>; del(
requestRawWithCallback(info: IRequestInfo, data: string | NodeJS.ReadableStream, onResult: (err: any, res: IHttpClientResponse) => void): void; requestUrl: string,
additionalHeaders?: IHeaders
): Promise<IHttpClientResponse>
post(
requestUrl: string,
data: string,
additionalHeaders?: IHeaders
): Promise<IHttpClientResponse>
patch(
requestUrl: string,
data: string,
additionalHeaders?: IHeaders
): Promise<IHttpClientResponse>
put(
requestUrl: string,
data: string,
additionalHeaders?: IHeaders
): Promise<IHttpClientResponse>
sendStream(
verb: string,
requestUrl: string,
stream: NodeJS.ReadableStream,
additionalHeaders?: IHeaders
): Promise<IHttpClientResponse>
request(
verb: string,
requestUrl: string,
data: string | NodeJS.ReadableStream,
headers: IHeaders
): Promise<IHttpClientResponse>
requestRaw(
info: IRequestInfo,
data: string | NodeJS.ReadableStream
): Promise<IHttpClientResponse>
requestRawWithCallback(
info: IRequestInfo,
data: string | NodeJS.ReadableStream,
onResult: (err: any, res: IHttpClientResponse) => void
): void
} }
export interface IRequestHandler { export interface IRequestHandler {
prepareRequest(options: http.RequestOptions): void; prepareRequest(options: http.RequestOptions): void
canHandleAuthentication(response: IHttpClientResponse): boolean; canHandleAuthentication(response: IHttpClientResponse): boolean
handleAuthentication(httpClient: IHttpClient, requestInfo: IRequestInfo, objs): Promise<IHttpClientResponse>; handleAuthentication(
httpClient: IHttpClient,
requestInfo: IRequestInfo,
objs
): Promise<IHttpClientResponse>
} }
export interface IHttpClientResponse { export interface IHttpClientResponse {
message: http.IncomingMessage; message: http.IncomingMessage
readBody(): Promise<string>; readBody(): Promise<string>
} }
export interface IRequestInfo { export interface IRequestInfo {
options: http.RequestOptions; options: http.RequestOptions
parsedUrl: url.Url; parsedUrl: url.Url
httpModule: any; httpModule: any
} }
export interface IRequestOptions { export interface IRequestOptions {
headers?: IHeaders; headers?: IHeaders
socketTimeout?: number; socketTimeout?: number
ignoreSslError?: boolean; ignoreSslError?: boolean
allowRedirects?: boolean; allowRedirects?: boolean
allowRedirectDowngrade?: boolean; allowRedirectDowngrade?: boolean
maxRedirects?: number; maxRedirects?: number
maxSockets?: number; maxSockets?: number
keepAlive?: boolean; keepAlive?: boolean
deserializeDates?: boolean; deserializeDates?: boolean
// Allows retries only on Read operations (since writes may not be idempotent) // Allows retries only on Read operations (since writes may not be idempotent)
allowRetries?: boolean; allowRetries?: boolean
maxRetries?: number; maxRetries?: number
} }
export interface ITypedResponse<T> { export interface ITypedResponse<T> {
statusCode: number, statusCode: number
result: T | null, result: T | null
headers: Object headers: Object
} }

2
package-lock.json generated
View File

@ -3416,7 +3416,7 @@
"prettier": { "prettier": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz",
"integrity": "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==", "integrity": "sha1-LRuuFz41WZbuNV7Jgwp6HuBUV+8=",
"dev": true "dev": true
}, },
"pretty-format": { "pretty-format": {

View File

@ -6,8 +6,8 @@
"scripts": { "scripts": {
"build": "rm -Rf ./_out && tsc && cp package*.json ./_out && cp *.md ./_out && cp LICENSE ./_out && cp actions.png ./_out", "build": "rm -Rf ./_out && tsc && cp package*.json ./_out && cp *.md ./_out && cp LICENSE ./_out && cp actions.png ./_out",
"test": "jest", "test": "jest",
"format": "prettier --write packages/**/*.ts", "format": "prettier --write *.ts && prettier --write **/*.ts",
"format-check": "prettier --check packages/**/*.ts", "format-check": "prettier --check *.ts && prettier --check **/*.ts",
"audit-check": "npm audit --audit-level=moderate" "audit-check": "npm audit --audit-level=moderate"
}, },
"repository": { "repository": {

107
proxy.ts
View File

@ -1,65 +1,62 @@
import * as url from 'url'; import * as url from 'url'
export function getProxyUrl(reqUrl: url.Url): url.Url | undefined { export function getProxyUrl(reqUrl: url.Url): url.Url | undefined {
let usingSsl = reqUrl.protocol === 'https:'; let usingSsl = reqUrl.protocol === 'https:'
let proxyUrl: url.Url; let proxyUrl: url.Url
if (checkBypass(reqUrl)) { if (checkBypass(reqUrl)) {
return proxyUrl; return proxyUrl
} }
let proxyVar: string; let proxyVar: string
if (usingSsl) { if (usingSsl) {
proxyVar = process.env["https_proxy"] || proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY']
process.env["HTTPS_PROXY"]; } else {
proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY']
} else { }
proxyVar = process.env["http_proxy"] ||
process.env["HTTP_PROXY"];
}
if (proxyVar) { if (proxyVar) {
proxyUrl = url.parse(proxyVar); proxyUrl = url.parse(proxyVar)
} }
return proxyUrl; return proxyUrl
} }
export function checkBypass(reqUrl: url.Url): boolean { export function checkBypass(reqUrl: url.Url): boolean {
if (!reqUrl.hostname) { if (!reqUrl.hostname) {
return false
}
let noProxy = process.env["no_proxy"] || process.env["NO_PROXY"] || '';
if (!noProxy) {
return false
}
// Determine the request port
let reqPort: number
if (reqUrl.port) {
reqPort = Number(reqUrl.port)
}
else if (reqUrl.protocol === 'http:') {
reqPort = 80
}
else if (reqUrl.protocol === 'https:') {
reqPort = 443
}
// Format the request hostname and hostname with port
let upperReqHosts = [reqUrl.hostname.toUpperCase()]
if (typeof reqPort === 'number') {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`)
}
// Compare request host against noproxy
for (let upperNoProxyItem of noProxy.split(',').map(x => x.trim().toUpperCase()).filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
return true
}
}
return false return false
} }
let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''
if (!noProxy) {
return false
}
// Determine the request port
let reqPort: number
if (reqUrl.port) {
reqPort = Number(reqUrl.port)
} else if (reqUrl.protocol === 'http:') {
reqPort = 80
} else if (reqUrl.protocol === 'https:') {
reqPort = 443
}
// Format the request hostname and hostname with port
let upperReqHosts = [reqUrl.hostname.toUpperCase()]
if (typeof reqPort === 'number') {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`)
}
// Compare request host against noproxy
for (let upperNoProxyItem of noProxy
.split(',')
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
return true
}
}
return false
}