mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 23:00:30 +00:00
2dc4299e39
* fix node-libcurl imports * removes unnecessary function wrapper and anyway, `number` is not the correct type (which is what motivated this change in the first place), `CurlFeature` is. * updates type for setOpt see https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgOIBs4GcvIN4BQyxyWwAXhAFzIDkWAtnOurcgD50MQAmwArgzadamKAHMItANwEAvgQKhIsRCgDCAe00BrYCkIlkYAJ4AHanSz9xcKMLoIAFpoSbMkdU+BmZ8xQD0AcjK0PBIyJoAbtDomnA8WErgYWrIAIIIYMCaIPhEJBBwYACMABSaZtm5NLQAssDoOrQANMjimDg0GNhYAJQ0UZrAPLJGRaUVVTkgtVq6+lityG4LlvN6EAPIQyOyCgRuIFhgyIjVsxlZM8gAvPnjxeWVF208xXB9+MhByGZQmgARugIAwaKYLCFcCBNKdQDBoFBeGcQDxkABJZBOOAxZAw5AAdzgJmMmmM5hQwFOsKc0AJwCwEAKRmIRyw7ggADo4uIyrRzjNORMSss8JFprk3h9kHI+syZf5DrkTshhQB1KBwMwWKA0TIXADatGFtAAundkFNXsh3mBPncAHzfX7-IEgsHkyEMvGwkIgBFQJFouCojFYnEofFEklgMkQynUsC0qD0xnytkc7maXnGp6i8XW21wGV9MaFJ4arU6q0zKV20uKgi-JHifhiZAwfgga65SIxKBxBJJTvdi6q4oAJhrNToDSayw6vW6nX6g2GowII57eQmU5eMzm2k2Szaq02NA2+m2uw3W7Hu+nIDr9rFLoBwNB4IpUJ9cP9iOREM0UxbFcSjYlSU9BNIiTOkGRQMpvQAAxDEwkOMWlIhAdASX3XIAH5iHSZAuxuBkQFoU43EDCAslVKlk05OUjAzEEsxzFs2zsDsu23fM8KfG1pVlRU2VOXdK21aAvwsTQYHHMAJwtR9ny+W4nVfYJXQ-D14x-GE-wDIMUWA8MwLJaNIL0qkYOTVMmRY5VMx5Pld2QSSdVoBtHkUlShPrfZAmCWDGUJTQoB0NpsFVAAPCwsl4KgmyCFLUrS9KMsyrKUoIAVciFJ4+TnZo2jFMhKFqRhmFYEtZHVTUpKgIrGhK75yssegmBYNhZTqydmvnUrSAoDqqu62qCAkhrq3qFr83ayqupq3rFDykACsmWhLwgE9vnjWpnFcdxiggLwfB6uV6qraA+W23axX2xwXDcDxTu8XwS0m-qtqPRZ80e2hDpek6zo+kSpuupqfrWe6oIO57js8d6LqCjCdpQAAqHgyQMjGwoiqLcAgOLaMgHgkuyymqepoJkuQAABMAsAAWmJ+KwFZwNwuQQEEg7YAoBVOxW24cBcu3DbymhzZ-opeGjte0GUd+RmWbZ0nOYBKAeb5mABaFiRBAgMWrsa27fqkIaAaBxG3vOz6VaZ1mSayTXud5tE9cF05haNk3vu22WLHl4GkftkTHbVl2OcRd3df1n3DdFsAvsUjybul-Qg46m3FeRz66dV532bd7WPdIWjcmDJPjZTtbJfNmHs5D23meccO5Uj4uNdjsu+cZI5q5F2vU5KdOobu5unoVk62-ziPgiL9XXd7nW0QHquzhr-3fMznap8BhHXrnjvC6d5eY65vv18r0NfeT1OJ3HxvjwP3PZ-bsG5SAA to see why `any` is required, for now (at least) * updates the getBodyBuffer parse calls now that the types are working * return to prior approach, this time with a warning
204 lines
5.4 KiB
TypeScript
204 lines
5.4 KiB
TypeScript
import { EventEmitter } from 'events';
|
|
import fs from 'fs';
|
|
|
|
// Note: we cannot import these from `node-libcurl` like normal because they come from the native library and it's not possible to load it while testing because it was built to run with Electron.
|
|
// That applies to these Enum type imports, but also applies to the members of the class below.
|
|
import { CurlAuth } from 'node-libcurl/dist/enum/CurlAuth';
|
|
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 {
|
|
_options = {};
|
|
_meta = {};
|
|
_features = {};
|
|
|
|
static info = {
|
|
COOKIELIST: 'COOKIELIST',
|
|
EFFECTIVE_URL: 'EFFECTIVE_URL',
|
|
SIZE_DOWNLOAD: 'SIZE_DOWNLOAD',
|
|
TOTAL_TIME: 'TOTAL_TIME',
|
|
}
|
|
|
|
static option = {
|
|
ACCEPT_ENCODING: 'ACCEPT_ENCODING',
|
|
CAINFO: 'CAINFO',
|
|
COOKIEFILE: 'COOKIEFILE',
|
|
COOKIELIST: 'COOKIELIST',
|
|
CUSTOMREQUEST: 'CUSTOMREQUEST',
|
|
DEBUGFUNCTION: 'DEBUGFUNCTION',
|
|
FOLLOWLOCATION: 'FOLLOWLOCATION',
|
|
HTTPAUTH: 'HTTPAUTH',
|
|
HTTPGET: 'HTTPGET',
|
|
HTTPHEADER: 'HTTPHEADER',
|
|
HTTPPOST: 'HTTPPOST',
|
|
HTTP_VERSION: 'HTTP_VERSION',
|
|
INFILESIZE_LARGE: 'INFILESIZE_LARGE',
|
|
KEYPASSWD: 'KEYPASSWD',
|
|
MAXREDIRS: 'MAXREDIRS',
|
|
NETRC: 'NETRC',
|
|
NOBODY: 'NOBODY',
|
|
NOPROGRESS: 'NOPROGRESS',
|
|
NOPROXY: 'NOPROXY',
|
|
PASSWORD: 'PASSWORD',
|
|
POST: 'POST',
|
|
POSTFIELDS: 'POSTFIELDS',
|
|
PROXY: 'PROXY',
|
|
PROXYAUTH: 'PROXYAUTH',
|
|
READDATA: 'READDATA',
|
|
READFUNCTION: 'READFUNCTION',
|
|
SSLCERT: 'SSLCERT',
|
|
SSLCERTTYPE: 'SSLCERTTYPE',
|
|
SSLKEY: 'SSLKEY',
|
|
SSL_VERIFYHOST: 'SSL_VERIFYHOST',
|
|
SSL_VERIFYPEER: 'SSL_VERIFYPEER',
|
|
TIMEOUT_MS: 'TIMEOUT_MS',
|
|
UNIX_SOCKET_PATH: 'UNIX_SOCKET_PATH',
|
|
UPLOAD: 'UPLOAD',
|
|
URL: 'URL',
|
|
USERAGENT: 'USERAGENT',
|
|
USERNAME: 'USERNAME',
|
|
VERBOSE: 'VERBOSE',
|
|
WRITEFUNCTION: 'WRITEFUNCTION',
|
|
XFERINFOFUNCTION: 'XFERINFOFUNCTION',
|
|
}
|
|
|
|
static getVersion() {
|
|
return 'libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0';
|
|
}
|
|
|
|
enable(name) {
|
|
this._features[name] = true;
|
|
}
|
|
|
|
setOpt(name, value) {
|
|
if (!name) {
|
|
throw new Error(`Invalid option ${name} ${value}`);
|
|
}
|
|
|
|
if (name === Curl.option.CAINFO) {
|
|
// Just ignore this because it's platform-specific
|
|
return;
|
|
}
|
|
|
|
if (name === Curl.option.READFUNCTION) {
|
|
let body = '';
|
|
|
|
// Only limiting this to prevent infinite loops
|
|
for (let i = 0; i < 1000; i++) {
|
|
const buffer = Buffer.alloc(23);
|
|
const bytes = value(buffer);
|
|
|
|
if (bytes === 0) {
|
|
break;
|
|
}
|
|
|
|
body += buffer.slice(0, bytes);
|
|
}
|
|
|
|
this._meta[`${name}_VALUE`] = body;
|
|
}
|
|
|
|
if (name === Curl.option.COOKIELIST) {
|
|
// This can be set multiple times
|
|
this._options[name] = this._options[name] || [];
|
|
|
|
this._options[name].push(value);
|
|
} else if (name === Curl.option.READDATA) {
|
|
const { size } = fs.fstatSync(value);
|
|
const buffer = Buffer.alloc(size);
|
|
fs.readSync(value, buffer, 0, size, 0);
|
|
this._options[name] = buffer.toString();
|
|
} else {
|
|
this._options[name] = value;
|
|
}
|
|
}
|
|
|
|
getInfo(name) {
|
|
switch (name) {
|
|
case Curl.info.COOKIELIST:
|
|
return [`#HttpOnly_.insomnia.rest\tTRUE\t/url/path\tTRUE\t${Date.now() / 1000}\tfoo\tbar`];
|
|
|
|
case Curl.info.EFFECTIVE_URL:
|
|
return this._options[Curl.option.URL];
|
|
|
|
case Curl.info.TOTAL_TIME:
|
|
return 700;
|
|
|
|
case Curl.info.SIZE_DOWNLOAD:
|
|
return 800;
|
|
|
|
default:
|
|
throw new Error(`Invalid info ${name}`);
|
|
}
|
|
}
|
|
|
|
perform() {
|
|
process.nextTick(() => {
|
|
const data = Buffer.from(
|
|
JSON.stringify({
|
|
options: this._options,
|
|
meta: this._meta,
|
|
features: this._features,
|
|
}),
|
|
);
|
|
this.emit('data', data);
|
|
|
|
// @ts-expect-error -- TSCONVERSION
|
|
this._options.WRITEFUNCTION(data);
|
|
|
|
process.nextTick(() => {
|
|
this.emit(
|
|
'end',
|
|
'NOT_USED',
|
|
'NOT_USED',
|
|
[
|
|
'HTTP/1.1 200 OK',
|
|
`Content-Length: ${data.length}`,
|
|
'Content-Type: application/json',
|
|
'',
|
|
].join('\n'),
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
close() {}
|
|
}
|
|
|
|
/**
|
|
* This is just to make it easier to test
|
|
* node-libcurl Enum exports (CurlAuth, CurlCode, etc) are TypeScript enums, which are converted to an object with format:
|
|
* ```ts
|
|
* const myEnum = {
|
|
* EnumKey: 0,
|
|
* 0: EnumKey,
|
|
* }
|
|
* ```
|
|
* We only want the named members (non-number ones)
|
|
*/
|
|
const getTsEnumOnlyWithNamedMembers = enumObj => {
|
|
let obj = {};
|
|
|
|
for (const member in enumObj) {
|
|
if (typeof enumObj[member] === 'number') {
|
|
obj = { ...obj, [member]: member };
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
};
|
|
|
|
// WARNING: changing this to `export default` will break the mock and be incredibly hard to debug. Ask me how I know.
|
|
module.exports = {
|
|
Curl,
|
|
CurlAuth: getTsEnumOnlyWithNamedMembers(CurlAuth),
|
|
CurlCode: getTsEnumOnlyWithNamedMembers(CurlCode),
|
|
CurlInfoDebug: getTsEnumOnlyWithNamedMembers(CurlInfoDebug),
|
|
CurlFeature: getTsEnumOnlyWithNamedMembers(CurlFeature),
|
|
CurlNetrc: getTsEnumOnlyWithNamedMembers(CurlNetrc),
|
|
CurlHttpVersion: getTsEnumOnlyWithNamedMembers(CurlHttpVersion),
|
|
};
|