insomnia/packages/insomnia-app/app/__mocks__/node-libcurl.ts
Dimitri Mitropoulos 2dc4299e39
fix node-libcurl imports (#3384)
* 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
2021-05-17 09:59:43 -04:00

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),
};