Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83c13c81ba | |||
| bccbba401a | |||
| 3a191eecf6 | |||
| 97f5a6f0dc | |||
| 48a7cdbf9c | |||
| 3f1933edf9 | |||
| 2215c8e5aa | |||
| af6de2cb95 | |||
| 1dc58e3080 | |||
| 20596c1d96 | |||
| 557f80fd03 | |||
| 32c52bb78a | |||
| 6d9a3fe547 | |||
| 4e1c194b34 | |||
| 09cb71a033 | |||
| 2506e78e82 |
@@ -21,7 +21,10 @@ describe('basics', () => {
|
||||
_http = new httpm.HttpClient('http-client-tests')
|
||||
})
|
||||
|
||||
afterEach(() => {})
|
||||
afterEach(() => {
|
||||
// Clean up environment variable to prevent test pollution
|
||||
delete process.env['ACTIONS_ORCHESTRATION_ID']
|
||||
})
|
||||
|
||||
it('constructs', () => {
|
||||
const http: httpm.HttpClient = new httpm.HttpClient('thttp-client-tests')
|
||||
@@ -60,7 +63,7 @@ describe('basics', () => {
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(obj.headers['user-agent']).toBeFalsy()
|
||||
expect(obj.headers['user-agent']).toBe('actions/http-client')
|
||||
})
|
||||
|
||||
/* TODO write a mock rather then relying on a third party
|
||||
@@ -374,4 +377,66 @@ describe('basics', () => {
|
||||
httpm.MediaTypes.ApplicationJson
|
||||
)
|
||||
})
|
||||
|
||||
it('appends orchestration ID to user-agent when ACTIONS_ORCHESTRATION_ID is set', async () => {
|
||||
const orchId = 'test-orch-id-12345'
|
||||
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
|
||||
|
||||
const http: httpm.HttpClient = new httpm.HttpClient('http-client-tests')
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.headers['user-agent']).toBe(
|
||||
`http-client-tests actions_orchestration_id/${orchId}`
|
||||
)
|
||||
})
|
||||
|
||||
it('sanitizes invalid characters in orchestration ID', async () => {
|
||||
const orchId = 'test (with) special/chars'
|
||||
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
|
||||
|
||||
const http: httpm.HttpClient = new httpm.HttpClient('http-client-tests')
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
// Spaces, parentheses, and slashes should be replaced with underscores
|
||||
expect(obj.headers['user-agent']).toBe(
|
||||
'http-client-tests actions_orchestration_id/test__with__special_chars'
|
||||
)
|
||||
})
|
||||
|
||||
it('does not modify user-agent when ACTIONS_ORCHESTRATION_ID is not set', async () => {
|
||||
delete process.env['ACTIONS_ORCHESTRATION_ID']
|
||||
|
||||
const http: httpm.HttpClient = new httpm.HttpClient('http-client-tests')
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.headers['user-agent']).toBe('http-client-tests')
|
||||
})
|
||||
|
||||
it('uses default user-agent with orchestration ID when no custom user-agent provided', async () => {
|
||||
const orchId = 'test-default-id-12345'
|
||||
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
|
||||
|
||||
const http: httpm.HttpClient = new httpm.HttpClient()
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.headers['user-agent']).toBe(
|
||||
`actions/http-client actions_orchestration_id/${orchId}`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -147,7 +147,7 @@ export class HttpClient {
|
||||
handlers?: ifm.RequestHandler[],
|
||||
requestOptions?: ifm.RequestOptions
|
||||
) {
|
||||
this.userAgent = userAgent
|
||||
this.userAgent = this._getUserAgentWithOrchestrationId(userAgent)
|
||||
this.handlers = handlers || []
|
||||
this.requestOptions = requestOptions
|
||||
if (requestOptions) {
|
||||
@@ -816,6 +816,18 @@ export class HttpClient {
|
||||
return proxyAgent
|
||||
}
|
||||
|
||||
private _getUserAgentWithOrchestrationId(userAgent?: string): string {
|
||||
const baseUserAgent = userAgent || 'actions/http-client'
|
||||
const orchId = process.env['ACTIONS_ORCHESTRATION_ID']
|
||||
if (orchId) {
|
||||
// Sanitize the orchestration ID to ensure it contains only valid characters
|
||||
// Valid characters: 0-9, a-z, _, -, .
|
||||
const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_')
|
||||
return `${baseUserAgent} actions_orchestration_id/${sanitizedId}`
|
||||
}
|
||||
return baseUserAgent
|
||||
}
|
||||
|
||||
private async _performExponentialBackoff(retryNumber: number): Promise<void> {
|
||||
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber)
|
||||
const ms: number = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber)
|
||||
|
||||
Reference in New Issue
Block a user