mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
Add ability to specify HTTP version (#2276)
* Add ability to specify HTTP version (Closes #2245) * Fix default HTTP version * Format w/ Prettier
This commit is contained in:
parent
ec81568d43
commit
53c21fba37
@ -6,6 +6,7 @@ import { CurlCode } from 'node-libcurl/dist/enum/CurlCode';
|
||||
import { CurlInfoDebug } from 'node-libcurl/dist/enum/CurlInfoDebug';
|
||||
import { CurlFeature } from 'node-libcurl/dist/enum/CurlFeature';
|
||||
import { CurlNetrc } from 'node-libcurl/dist/enum/CurlNetrc';
|
||||
import { CurlHttpVersion } from 'node-libcurl/dist/enum/CurlHttpVersion';
|
||||
|
||||
class Curl extends EventEmitter {
|
||||
constructor() {
|
||||
@ -130,6 +131,7 @@ Curl.option = {
|
||||
HTTPGET: 'HTTPGET',
|
||||
HTTPHEADER: 'HTTPHEADER',
|
||||
HTTPPOST: 'HTTPPOST',
|
||||
HTTP_VERSION: 'HTTP_VERSION',
|
||||
INFILESIZE_LARGE: 'INFILESIZE_LARGE',
|
||||
KEYPASSWD: 'KEYPASSWD',
|
||||
MAXREDIRS: 'MAXREDIRS',
|
||||
@ -185,4 +187,5 @@ module.exports = {
|
||||
CurlInfoDebug: getTsEnumOnlyWithNamedMembers(CurlInfoDebug),
|
||||
CurlFeature: getTsEnumOnlyWithNamedMembers(CurlFeature),
|
||||
CurlNetrc: getTsEnumOnlyWithNamedMembers(CurlNetrc),
|
||||
CurlHttpVersion: getTsEnumOnlyWithNamedMembers(CurlHttpVersion),
|
||||
};
|
||||
|
@ -227,6 +227,17 @@ export const HAWK_ALGORITHM_SHA1 = 'sha1';
|
||||
export const JSON_ORDER_PREFIX = '&';
|
||||
export const JSON_ORDER_SEPARATOR = '~|';
|
||||
|
||||
// HTTP version codes
|
||||
export const HttpVersions = {
|
||||
V1_0: 'V1_0',
|
||||
V1_1: 'V1_1',
|
||||
V2_0: 'V2_0',
|
||||
v3: 'v3',
|
||||
default: 'default',
|
||||
};
|
||||
|
||||
export type HttpVersion = $Keys<typeof HttpVersions>;
|
||||
|
||||
const authTypesMap = {
|
||||
[AUTH_BASIC]: ['Basic', 'Basic Auth'],
|
||||
[AUTH_DIGEST]: ['Digest', 'Digest Auth'],
|
||||
|
@ -1,8 +1,9 @@
|
||||
// @flow
|
||||
import type { BaseModel } from './index';
|
||||
import * as db from '../common/database';
|
||||
import { getAppDefaultTheme, UPDATE_CHANNEL_STABLE } from '../common/constants';
|
||||
import { getAppDefaultTheme, HttpVersions, UPDATE_CHANNEL_STABLE } from '../common/constants';
|
||||
import * as hotkeys from '../common/hotkeys';
|
||||
import type { HttpVersion } from '../common/constants';
|
||||
|
||||
export type PluginConfig = {
|
||||
disabled: boolean,
|
||||
@ -17,8 +18,8 @@ type BaseSettings = {
|
||||
autocompleteDelay: number,
|
||||
deviceId: string | null,
|
||||
disableHtmlPreviewJs: boolean,
|
||||
disableUpdateNotification: boolean,
|
||||
disableResponsePreviewLinks: boolean,
|
||||
disableUpdateNotification: boolean,
|
||||
editorFontSize: number,
|
||||
editorIndentSize: number,
|
||||
editorIndentWithTabs: boolean,
|
||||
@ -26,6 +27,7 @@ type BaseSettings = {
|
||||
editorLineWrapping: boolean,
|
||||
enableAnalytics: boolean,
|
||||
environmentHighlightColorStyle: string,
|
||||
filterResponsesByEnv: boolean,
|
||||
followRedirects: boolean,
|
||||
fontInterface: string | null,
|
||||
fontMonospace: string | null,
|
||||
@ -40,9 +42,10 @@ type BaseSettings = {
|
||||
maxTimelineDataSizeKB: number,
|
||||
noProxy: string,
|
||||
nunjucksPowerUserMode: boolean,
|
||||
pluginConfig: PluginConfigMap,
|
||||
pluginPath: string,
|
||||
preferredHttpVersion: HttpVersion,
|
||||
proxyEnabled: boolean,
|
||||
filterResponsesByEnv: boolean,
|
||||
showPasswords: boolean,
|
||||
theme: string,
|
||||
timeout: number,
|
||||
@ -51,7 +54,6 @@ type BaseSettings = {
|
||||
useBulkHeaderEditor: boolean,
|
||||
useBulkParametersEditor: boolean,
|
||||
validateSSL: boolean,
|
||||
pluginConfig: PluginConfigMap,
|
||||
|
||||
// Feature flags
|
||||
enableSyncBeta: boolean,
|
||||
@ -80,6 +82,7 @@ export function init(): BaseSettings {
|
||||
editorLineWrapping: true,
|
||||
enableAnalytics: false,
|
||||
environmentHighlightColorStyle: 'sidebar-indicator',
|
||||
filterResponsesByEnv: false,
|
||||
followRedirects: true,
|
||||
fontInterface: null,
|
||||
fontMonospace: null,
|
||||
@ -96,8 +99,8 @@ export function init(): BaseSettings {
|
||||
nunjucksPowerUserMode: false,
|
||||
pluginConfig: {},
|
||||
pluginPath: '',
|
||||
preferredHttpVersion: HttpVersions.default,
|
||||
proxyEnabled: false,
|
||||
filterResponsesByEnv: false,
|
||||
showPasswords: false,
|
||||
theme: getAppDefaultTheme(),
|
||||
timeout: 0,
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
CONTENT_TYPE_FORM_DATA,
|
||||
CONTENT_TYPE_FORM_URLENCODED,
|
||||
getAppVersion,
|
||||
HttpVersions,
|
||||
} from '../../common/constants';
|
||||
import { filterHeaders } from '../../common/misc';
|
||||
import { globalBeforeEach } from '../../__jest__/before-each';
|
||||
@ -571,6 +572,50 @@ describe('actuallySend()', () => {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('sets HTTP version', async () => {
|
||||
const workspace = await models.workspace.create();
|
||||
const settings = await models.settings.create();
|
||||
|
||||
const request = Object.assign(models.request.init(), {
|
||||
_id: 'req_123',
|
||||
parentId: workspace._id,
|
||||
});
|
||||
|
||||
const renderedRequest = await getRenderedRequest(request);
|
||||
const responseV1 = await networkUtils._actuallySend(renderedRequest, CONTEXT, workspace, {
|
||||
...settings,
|
||||
preferredHttpVersion: HttpVersions.V1_0,
|
||||
});
|
||||
const responseV11 = await networkUtils._actuallySend(renderedRequest, CONTEXT, workspace, {
|
||||
...settings,
|
||||
preferredHttpVersion: HttpVersions.V1_1,
|
||||
});
|
||||
const responseV2 = await networkUtils._actuallySend(renderedRequest, CONTEXT, workspace, {
|
||||
...settings,
|
||||
preferredHttpVersion: HttpVersions.V2_0,
|
||||
});
|
||||
const responseV3 = await networkUtils._actuallySend(renderedRequest, CONTEXT, workspace, {
|
||||
...settings,
|
||||
preferredHttpVersion: HttpVersions.v3,
|
||||
});
|
||||
const responseDefault = await networkUtils._actuallySend(renderedRequest, CONTEXT, workspace, {
|
||||
...settings,
|
||||
preferredHttpVersion: HttpVersions.default,
|
||||
});
|
||||
const responseInvalid = await networkUtils._actuallySend(renderedRequest, CONTEXT, workspace, {
|
||||
...settings,
|
||||
preferredHttpVersion: 'blah',
|
||||
});
|
||||
|
||||
const r = models.response;
|
||||
expect(JSON.parse(r.getBodyBuffer(responseV1)).options.HTTP_VERSION).toBe('V1_0');
|
||||
expect(JSON.parse(r.getBodyBuffer(responseV11)).options.HTTP_VERSION).toBe('V1_1');
|
||||
expect(JSON.parse(r.getBodyBuffer(responseV2)).options.HTTP_VERSION).toBe('V2_0');
|
||||
expect(JSON.parse(r.getBodyBuffer(responseV3)).options.HTTP_VERSION).toBe('v3');
|
||||
expect(JSON.parse(r.getBodyBuffer(responseDefault)).options.HTTP_VERSION).toBe(undefined);
|
||||
expect(JSON.parse(r.getBodyBuffer(responseInvalid)).options.HTTP_VERSION).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getAwsAuthHeaders', () => {
|
||||
|
@ -13,7 +13,15 @@ import mkdirp from 'mkdirp';
|
||||
import crypto from 'crypto';
|
||||
import clone from 'clone';
|
||||
import { parse as urlParse, resolve as urlResolve } from 'url';
|
||||
import { Curl, CurlAuth, CurlCode, CurlInfoDebug, CurlFeature, CurlNetrc } from 'node-libcurl';
|
||||
import {
|
||||
Curl,
|
||||
CurlAuth,
|
||||
CurlCode,
|
||||
CurlInfoDebug,
|
||||
CurlFeature,
|
||||
CurlNetrc,
|
||||
CurlHttpVersion,
|
||||
} from 'node-libcurl';
|
||||
import { join as pathJoin } from 'path';
|
||||
import uuid from 'uuid';
|
||||
import * as models from '../models';
|
||||
@ -27,6 +35,7 @@ import {
|
||||
CONTENT_TYPE_FORM_URLENCODED,
|
||||
getAppVersion,
|
||||
getTempDir,
|
||||
HttpVersions,
|
||||
STATUS_CODE_PLUGIN_ERROR,
|
||||
} from '../common/constants';
|
||||
import {
|
||||
@ -338,8 +347,34 @@ export async function _actuallySend(
|
||||
setOpt(Curl.option.URL, finalUrl);
|
||||
}
|
||||
addTimelineText('Preparing request to ' + finalUrl);
|
||||
addTimelineText(`Using ${Curl.getVersion()}`);
|
||||
addTimelineText('Current time is ' + new Date().toISOString());
|
||||
addTimelineText(`Using ${Curl.getVersion()}`);
|
||||
|
||||
// Set HTTP version
|
||||
switch (settings.preferredHttpVersion) {
|
||||
case HttpVersions.V1_0:
|
||||
addTimelineText('Using HTTP 1.0');
|
||||
setOpt(Curl.option.HTTP_VERSION, CurlHttpVersion.V1_0);
|
||||
break;
|
||||
case HttpVersions.V1_1:
|
||||
addTimelineText('Using HTTP 1.1');
|
||||
setOpt(Curl.option.HTTP_VERSION, CurlHttpVersion.V1_1);
|
||||
break;
|
||||
case HttpVersions.V2_0:
|
||||
addTimelineText('Using HTTP/2');
|
||||
setOpt(Curl.option.HTTP_VERSION, CurlHttpVersion.V2_0);
|
||||
break;
|
||||
case HttpVersions.v3:
|
||||
addTimelineText('Using HTTP/3');
|
||||
setOpt(Curl.option.HTTP_VERSION, CurlHttpVersion.v3);
|
||||
break;
|
||||
case HttpVersions.default:
|
||||
addTimelineText('Using default HTTP version');
|
||||
break;
|
||||
default:
|
||||
addTimelineText(`Unknown HTTP version specified ${settings.preferredHttpVersion}`);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set timeout
|
||||
if (settings.timeout > 0) {
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
EDITOR_KEY_MAP_EMACS,
|
||||
EDITOR_KEY_MAP_SUBLIME,
|
||||
EDITOR_KEY_MAP_VIM,
|
||||
HttpVersions,
|
||||
isLinux,
|
||||
isMac,
|
||||
isWindows,
|
||||
@ -20,6 +21,7 @@ import { setFont } from '../../../plugins/misc';
|
||||
import * as session from '../../../account/session';
|
||||
import Tooltip from '../tooltip';
|
||||
import CheckForUpdatesButton from '../check-for-updates-button';
|
||||
import type { HttpVersion } from '../../../common/constants';
|
||||
|
||||
// Font family regex to match certain monospace fonts that don't get
|
||||
// recognized as monospace
|
||||
@ -81,11 +83,6 @@ class General extends React.PureComponent<Props, State> {
|
||||
return this.props.updateSetting(el.name, value);
|
||||
}
|
||||
|
||||
async _handleToggleMenuBar(e: SyntheticEvent<HTMLInputElement>) {
|
||||
const settings = await this._handleUpdateSetting(e);
|
||||
this.props.handleToggleMenuBar(settings.autoHideMenuBar);
|
||||
}
|
||||
|
||||
async _handleUpdateSettingAndRestart(e: SyntheticEvent<HTMLInputElement>) {
|
||||
await this._handleUpdateSetting(e);
|
||||
const { app } = electron.remote || electron;
|
||||
@ -93,11 +90,6 @@ class General extends React.PureComponent<Props, State> {
|
||||
app.exit();
|
||||
}
|
||||
|
||||
async _handleFontLigatureChange(el: SyntheticEvent<HTMLInputElement>) {
|
||||
const settings = await this._handleUpdateSetting(el);
|
||||
setFont(settings);
|
||||
}
|
||||
|
||||
async _handleFontSizeChange(el: SyntheticEvent<HTMLInputElement>) {
|
||||
const settings = await this._handleUpdateSetting(el);
|
||||
setFont(settings);
|
||||
@ -108,6 +100,32 @@ class General extends React.PureComponent<Props, State> {
|
||||
setFont(settings);
|
||||
}
|
||||
|
||||
renderEnumSetting(
|
||||
label: string,
|
||||
name: string,
|
||||
values: Array<{ name: string, value: any }>,
|
||||
help: string,
|
||||
forceRestart?: boolean,
|
||||
) {
|
||||
const { settings } = this.props;
|
||||
const onChange = forceRestart ? this._handleUpdateSettingAndRestart : this._handleUpdateSetting;
|
||||
return (
|
||||
<div className="form-control form-control--outlined pad-top-sm">
|
||||
<label>
|
||||
{label}
|
||||
{help && <HelpTooltip className="space-left">{help}</HelpTooltip>}
|
||||
<select value={settings[name] || '__NULL__'} name={name} onChange={onChange}>
|
||||
{values.map(({ name, value }) => (
|
||||
<option key={value} value={value}>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderBooleanSetting(label: string, name: string, help: string, forceRestart?: boolean) {
|
||||
const { settings } = this.props;
|
||||
|
||||
@ -330,6 +348,24 @@ class General extends React.PureComponent<Props, State> {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-row pad-top-sm">
|
||||
{this.renderEnumSetting(
|
||||
'Preferred HTTP version',
|
||||
'preferredHttpVersion',
|
||||
([
|
||||
{ name: 'Default', value: HttpVersions.default },
|
||||
{ name: 'HTTP 1.0', value: HttpVersions.V1_0 },
|
||||
{ name: 'HTTP 1.1', value: HttpVersions.V1_1 },
|
||||
{ name: 'HTTP/2', value: HttpVersions.V2_0 },
|
||||
|
||||
// Enable when our version of libcurl supports HTTP/3
|
||||
// { name: 'HTTP/3', value: HttpVersions.v3 },
|
||||
]: Array<{ name: string, value: HttpVersion }>),
|
||||
'Preferred HTTP version to use for requests which will fall back if it cannot be' +
|
||||
'negotiated',
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="form-row pad-top-sm">
|
||||
{this.renderNumberSetting('Maximum Redirects', 'maxRedirects', '-1 for infinite', {
|
||||
min: -1,
|
||||
|
@ -32,6 +32,15 @@ declare module 'node-libcurl' {
|
||||
CurlCode: {|
|
||||
CURLE_ABORTED_BY_CALLBACK: number,
|
||||
|};
|
||||
CurlHttpVersion: {|
|
||||
None: number,
|
||||
V1_0: number,
|
||||
V1_1: number,
|
||||
V2PriorKnowledge: number,
|
||||
V2Tls: number,
|
||||
V2_0: number,
|
||||
v3: number,
|
||||
|};
|
||||
CurlInfoDebug: {|
|
||||
Text: number,
|
||||
HeaderIn: number,
|
||||
|
Loading…
Reference in New Issue
Block a user