Default to sending Accept and Content-Type headers for json

This commit is contained in:
David Kale 2020-02-04 14:19:46 -05:00
parent f545df6c21
commit e91a39a86b
6 changed files with 131 additions and 12 deletions

View File

@ -1,10 +1,13 @@
## Releases
## 1.0.1 to 1.0.3
Adds proxy support.
## 1.0.6
Automatically sends Content-Type and Accept application/json headers for \<verb>Json() helper methods if not set in the client or parameters.
## 1.0.5
Adds \<verb>Json() helper methods for json over http scenarios.
## 1.0.4
Started to add \<verb>Json() helper methods. Do not use this release for that. Use >= 1.0.5 since there was an issue with types.
## 1.0.5
Adds \<verb>Json() helper methods for json over http scenarios.
## 1.0.1 to 1.0.3
Adds proxy support.

View File

@ -9,6 +9,7 @@ interface HttpBinData {
url: string;
data: any;
json: any;
headers: any;
args?: any
}
@ -206,6 +207,8 @@ describe('basics', () => {
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() => {
@ -221,6 +224,9 @@ describe('basics', () => {
expect(restRes.result).toBeDefined();
expect(restRes.result.url).toBe('https://httpbin.org/post');
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);
});
it('puts a json object', async() => {
@ -230,6 +236,10 @@ describe('basics', () => {
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["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson);
expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson);
});
it('patch a json object', async() => {
@ -239,5 +249,8 @@ describe('basics', () => {
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);
});
});

79
__tests__/headers.test.ts Normal file
View File

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

View File

@ -35,6 +35,15 @@ export enum HttpCodes {
GatewayTimeout = 504,
}
export enum Headers {
Accept = "accept",
ContentType = "content-type"
}
export enum MediaTypes {
ApplicationJson = "application/json"
}
/**
* Returns the proxy URL, depending upon the supplied url and proxy environment variables.
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
@ -166,25 +175,32 @@ export class HttpClient {
* Gets a typed object from an endpoint
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
*/
public async getJson<T>(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>> {
public async getJson<T>(requestUrl: string, additionalHeaders: ifm.IHeaders = {}): Promise<ifm.ITypedResponse<T>> {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson)
let res: ifm.IHttpClientResponse = await this.get(requestUrl, additionalHeaders);
return this._processResponse<T>(res, this.requestOptions);
}
public async postJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>> {
public async postJson<T>(requestUrl: string, obj: any, additionalHeaders: ifm.IHeaders = {}): Promise<ifm.ITypedResponse<T>> {
let data: string = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson)
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
let res: ifm.IHttpClientResponse = await this.post(requestUrl, data, additionalHeaders);
return this._processResponse<T>(res, this.requestOptions);
}
public async putJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>> {
public async putJson<T>(requestUrl: string, obj: any, additionalHeaders: ifm.IHeaders = {}): Promise<ifm.ITypedResponse<T>> {
let data: string = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson)
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
let res: ifm.IHttpClientResponse = await this.put(requestUrl, data, additionalHeaders);
return this._processResponse<T>(res, this.requestOptions);
}
public async patchJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>> {
public async patchJson<T>(requestUrl: string, obj: any, additionalHeaders: ifm.IHeaders = {}): Promise<ifm.ITypedResponse<T>> {
let data: string = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson)
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
let res: ifm.IHttpClientResponse = await this.patch(requestUrl, data, additionalHeaders);
return this._processResponse<T>(res, this.requestOptions);
}
@ -416,6 +432,14 @@ export class HttpClient {
return lowercaseKeys(headers || {});
}
private _getExistingOrDefaultHeader(additionalHeaders: ifm.IHeaders, header: string, _default: string) {
let clientHeader: string;
if(this.requestOptions && this.requestOptions.headers) {
clientHeader = this.requestOptions.headers[header];
}
return additionalHeaders[header] || clientHeader || _default;
}
private _getAgent(parsedUrl: url.Url): http.Agent {
let agent;
let proxyUrl: url.Url = pm.getProxyUrl(parsedUrl);

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "@actions/http-client",
"version": "1.0.5",
"version": "1.0.6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "@actions/http-client",
"version": "1.0.5",
"version": "1.0.6",
"description": "Actions Http Client",
"main": "index.js",
"scripts": {