@vercel/ruby 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +149 -69
- package/package.json +5 -3
- package/vc_init.rb +1 -1
package/dist/index.js
CHANGED
|
@@ -174,8 +174,8 @@ var require_isexe = __commonJS({
|
|
|
174
174
|
// ../../node_modules/.pnpm/which@1.3.1/node_modules/which/which.js
|
|
175
175
|
var require_which = __commonJS({
|
|
176
176
|
"../../node_modules/.pnpm/which@1.3.1/node_modules/which/which.js"(exports, module2) {
|
|
177
|
-
module2.exports =
|
|
178
|
-
|
|
177
|
+
module2.exports = which2;
|
|
178
|
+
which2.sync = whichSync;
|
|
179
179
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
180
180
|
var path = require("path");
|
|
181
181
|
var COLON = isWindows ? ";" : ":";
|
|
@@ -206,7 +206,7 @@ var require_which = __commonJS({
|
|
|
206
206
|
extExe: pathExtExe
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
|
-
function
|
|
209
|
+
function which2(cmd, opt, cb) {
|
|
210
210
|
if (typeof opt === "function") {
|
|
211
211
|
cb = opt;
|
|
212
212
|
opt = {};
|
|
@@ -307,7 +307,7 @@ var require_resolveCommand = __commonJS({
|
|
|
307
307
|
"../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module2) {
|
|
308
308
|
"use strict";
|
|
309
309
|
var path = require("path");
|
|
310
|
-
var
|
|
310
|
+
var which2 = require_which();
|
|
311
311
|
var pathKey = require_path_key()();
|
|
312
312
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
313
313
|
const cwd = process.cwd();
|
|
@@ -320,7 +320,7 @@ var require_resolveCommand = __commonJS({
|
|
|
320
320
|
}
|
|
321
321
|
let resolved;
|
|
322
322
|
try {
|
|
323
|
-
resolved =
|
|
323
|
+
resolved = which2.sync(parsed.command, {
|
|
324
324
|
path: (parsed.options.env || process.env)[pathKey],
|
|
325
325
|
pathExt: withoutPathExt ? path.delimiter : void 0
|
|
326
326
|
});
|
|
@@ -5165,11 +5165,11 @@ var require_symlink = __commonJS({
|
|
|
5165
5165
|
return callback(err);
|
|
5166
5166
|
if (destinationExists)
|
|
5167
5167
|
return callback(null);
|
|
5168
|
-
symlinkPaths(srcpath, dstpath, (err2,
|
|
5168
|
+
symlinkPaths(srcpath, dstpath, (err2, relative) => {
|
|
5169
5169
|
if (err2)
|
|
5170
5170
|
return callback(err2);
|
|
5171
|
-
srcpath =
|
|
5172
|
-
symlinkType(
|
|
5171
|
+
srcpath = relative.toDst;
|
|
5172
|
+
symlinkType(relative.toCwd, type, (err3, type2) => {
|
|
5173
5173
|
if (err3)
|
|
5174
5174
|
return callback(err3);
|
|
5175
5175
|
const dir = path.dirname(dstpath);
|
|
@@ -5192,9 +5192,9 @@ var require_symlink = __commonJS({
|
|
|
5192
5192
|
const destinationExists = fs.existsSync(dstpath);
|
|
5193
5193
|
if (destinationExists)
|
|
5194
5194
|
return void 0;
|
|
5195
|
-
const
|
|
5196
|
-
srcpath =
|
|
5197
|
-
type = symlinkTypeSync(
|
|
5195
|
+
const relative = symlinkPathsSync(srcpath, dstpath);
|
|
5196
|
+
srcpath = relative.toDst;
|
|
5197
|
+
type = symlinkTypeSync(relative.toCwd, type);
|
|
5198
5198
|
const dir = path.dirname(dstpath);
|
|
5199
5199
|
const exists = fs.existsSync(dir);
|
|
5200
5200
|
if (exists)
|
|
@@ -6502,6 +6502,94 @@ var require_lib = __commonJS({
|
|
|
6502
6502
|
}
|
|
6503
6503
|
});
|
|
6504
6504
|
|
|
6505
|
+
// ../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js
|
|
6506
|
+
var require_lib2 = __commonJS({
|
|
6507
|
+
"../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
|
|
6508
|
+
var isexe = require_isexe();
|
|
6509
|
+
var { join: join3, delimiter, sep, posix } = require("path");
|
|
6510
|
+
var isWindows = process.platform === "win32";
|
|
6511
|
+
var rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1"));
|
|
6512
|
+
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
6513
|
+
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
6514
|
+
var getPathInfo = (cmd, {
|
|
6515
|
+
path: optPath = process.env.PATH,
|
|
6516
|
+
pathExt: optPathExt = process.env.PATHEXT,
|
|
6517
|
+
delimiter: optDelimiter = delimiter
|
|
6518
|
+
}) => {
|
|
6519
|
+
const pathEnv = cmd.match(rSlash) ? [""] : [
|
|
6520
|
+
// windows always checks the cwd first
|
|
6521
|
+
...isWindows ? [process.cwd()] : [],
|
|
6522
|
+
...(optPath || /* istanbul ignore next: very unusual */
|
|
6523
|
+
"").split(optDelimiter)
|
|
6524
|
+
];
|
|
6525
|
+
if (isWindows) {
|
|
6526
|
+
const pathExtExe = optPathExt || [".EXE", ".CMD", ".BAT", ".COM"].join(optDelimiter);
|
|
6527
|
+
const pathExt = pathExtExe.split(optDelimiter);
|
|
6528
|
+
if (cmd.includes(".") && pathExt[0] !== "") {
|
|
6529
|
+
pathExt.unshift("");
|
|
6530
|
+
}
|
|
6531
|
+
return { pathEnv, pathExt, pathExtExe };
|
|
6532
|
+
}
|
|
6533
|
+
return { pathEnv, pathExt: [""] };
|
|
6534
|
+
};
|
|
6535
|
+
var getPathPart = (raw, cmd) => {
|
|
6536
|
+
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
6537
|
+
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
6538
|
+
return prefix + join3(pathPart, cmd);
|
|
6539
|
+
};
|
|
6540
|
+
var which2 = async (cmd, opt = {}) => {
|
|
6541
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
6542
|
+
const found = [];
|
|
6543
|
+
for (const envPart of pathEnv) {
|
|
6544
|
+
const p = getPathPart(envPart, cmd);
|
|
6545
|
+
for (const ext of pathExt) {
|
|
6546
|
+
const withExt = p + ext;
|
|
6547
|
+
const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true });
|
|
6548
|
+
if (is) {
|
|
6549
|
+
if (!opt.all) {
|
|
6550
|
+
return withExt;
|
|
6551
|
+
}
|
|
6552
|
+
found.push(withExt);
|
|
6553
|
+
}
|
|
6554
|
+
}
|
|
6555
|
+
}
|
|
6556
|
+
if (opt.all && found.length) {
|
|
6557
|
+
return found;
|
|
6558
|
+
}
|
|
6559
|
+
if (opt.nothrow) {
|
|
6560
|
+
return null;
|
|
6561
|
+
}
|
|
6562
|
+
throw getNotFoundError(cmd);
|
|
6563
|
+
};
|
|
6564
|
+
var whichSync = (cmd, opt = {}) => {
|
|
6565
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
6566
|
+
const found = [];
|
|
6567
|
+
for (const pathEnvPart of pathEnv) {
|
|
6568
|
+
const p = getPathPart(pathEnvPart, cmd);
|
|
6569
|
+
for (const ext of pathExt) {
|
|
6570
|
+
const withExt = p + ext;
|
|
6571
|
+
const is = isexe.sync(withExt, { pathExt: pathExtExe, ignoreErrors: true });
|
|
6572
|
+
if (is) {
|
|
6573
|
+
if (!opt.all) {
|
|
6574
|
+
return withExt;
|
|
6575
|
+
}
|
|
6576
|
+
found.push(withExt);
|
|
6577
|
+
}
|
|
6578
|
+
}
|
|
6579
|
+
}
|
|
6580
|
+
if (opt.all && found.length) {
|
|
6581
|
+
return found;
|
|
6582
|
+
}
|
|
6583
|
+
if (opt.nothrow) {
|
|
6584
|
+
return null;
|
|
6585
|
+
}
|
|
6586
|
+
throw getNotFoundError(cmd);
|
|
6587
|
+
};
|
|
6588
|
+
module2.exports = which2;
|
|
6589
|
+
which2.sync = whichSync;
|
|
6590
|
+
}
|
|
6591
|
+
});
|
|
6592
|
+
|
|
6505
6593
|
// ../../node_modules/.pnpm/semver@6.3.1/node_modules/semver/semver.js
|
|
6506
6594
|
var require_semver2 = __commonJS({
|
|
6507
6595
|
"../../node_modules/.pnpm/semver@6.3.1/node_modules/semver/semver.js"(exports, module2) {
|
|
@@ -7666,32 +7754,39 @@ var import_fs_extra = __toESM(require_lib());
|
|
|
7666
7754
|
var import_build_utils2 = require("@vercel/build-utils");
|
|
7667
7755
|
|
|
7668
7756
|
// src/install-ruby.ts
|
|
7757
|
+
var import_execa = __toESM(require_execa());
|
|
7758
|
+
var import_which = __toESM(require_lib2());
|
|
7669
7759
|
var import_path = require("path");
|
|
7670
7760
|
var import_semver = __toESM(require_semver2());
|
|
7671
|
-
var import_execa = __toESM(require_execa());
|
|
7672
7761
|
var import_build_utils = require("@vercel/build-utils");
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
return options;
|
|
7692
|
-
}
|
|
7762
|
+
var allOptions = [
|
|
7763
|
+
{ major: 3, minor: 3, range: "3.3.x", runtime: "ruby3.3" },
|
|
7764
|
+
{ major: 3, minor: 2, range: "3.2.x", runtime: "ruby3.2" },
|
|
7765
|
+
{
|
|
7766
|
+
major: 2,
|
|
7767
|
+
minor: 7,
|
|
7768
|
+
range: "2.7.x",
|
|
7769
|
+
runtime: "ruby2.7",
|
|
7770
|
+
discontinueDate: /* @__PURE__ */ new Date("2023-12-07")
|
|
7771
|
+
},
|
|
7772
|
+
{
|
|
7773
|
+
major: 2,
|
|
7774
|
+
minor: 5,
|
|
7775
|
+
range: "2.5.x",
|
|
7776
|
+
runtime: "ruby2.5",
|
|
7777
|
+
discontinueDate: /* @__PURE__ */ new Date("2021-11-30")
|
|
7778
|
+
}
|
|
7779
|
+
];
|
|
7693
7780
|
function getLatestRubyVersion() {
|
|
7694
|
-
|
|
7781
|
+
const selection = allOptions.find(isInstalled);
|
|
7782
|
+
if (!selection) {
|
|
7783
|
+
throw new import_build_utils.NowBuildError({
|
|
7784
|
+
code: "RUBY_INVALID_VERSION",
|
|
7785
|
+
link: "http://vercel.link/ruby-version",
|
|
7786
|
+
message: `Unable to find any supported Ruby versions.`
|
|
7787
|
+
});
|
|
7788
|
+
}
|
|
7789
|
+
return selection;
|
|
7695
7790
|
}
|
|
7696
7791
|
function isDiscontinued({ discontinueDate }) {
|
|
7697
7792
|
const today = Date.now();
|
|
@@ -7707,7 +7802,7 @@ function getRubyPath(meta, gemfileContents) {
|
|
|
7707
7802
|
const line = gemfileContents.split("\n").find((line2) => line2.startsWith("ruby"));
|
|
7708
7803
|
if (line) {
|
|
7709
7804
|
const strVersion = line.slice(4).trim().slice(1, -1).replace("~>", "");
|
|
7710
|
-
const found =
|
|
7805
|
+
const found = allOptions.some((o) => {
|
|
7711
7806
|
selection = o;
|
|
7712
7807
|
return (0, import_semver.intersects)(o.range, strVersion);
|
|
7713
7808
|
});
|
|
@@ -7718,12 +7813,13 @@ function getRubyPath(meta, gemfileContents) {
|
|
|
7718
7813
|
link: "http://vercel.link/ruby-version"
|
|
7719
7814
|
});
|
|
7720
7815
|
}
|
|
7721
|
-
|
|
7816
|
+
const discontinued = isDiscontinued(selection);
|
|
7817
|
+
if (discontinued || !isInstalled(selection)) {
|
|
7722
7818
|
const latest = getLatestRubyVersion();
|
|
7723
|
-
const intro = `Found \`Gemfile\` with discontinued Ruby version: \`${line}.\``;
|
|
7819
|
+
const intro = `Found \`Gemfile\` with ${discontinued ? "discontinued" : "invalid"} Ruby version: \`${line}.\``;
|
|
7724
7820
|
const hint = `Please set \`ruby "~> ${latest.range}"\` in your \`Gemfile\` to use Ruby ${latest.range}.`;
|
|
7725
7821
|
throw new import_build_utils.NowBuildError({
|
|
7726
|
-
code: "RUBY_DISCONTINUED_VERSION",
|
|
7822
|
+
code: discontinued ? "RUBY_DISCONTINUED_VERSION" : "RUBY_INVALID_VERSION",
|
|
7727
7823
|
link: "http://vercel.link/ruby-version",
|
|
7728
7824
|
message: `${intro} ${hint}`
|
|
7729
7825
|
});
|
|
@@ -7733,6 +7829,7 @@ function getRubyPath(meta, gemfileContents) {
|
|
|
7733
7829
|
const { major, minor, runtime } = selection;
|
|
7734
7830
|
const gemHome = "/ruby" + major + minor;
|
|
7735
7831
|
const result = {
|
|
7832
|
+
major,
|
|
7736
7833
|
gemHome,
|
|
7737
7834
|
runtime,
|
|
7738
7835
|
rubyPath: (0, import_path.join)(gemHome, "bin", "ruby"),
|
|
@@ -7743,23 +7840,7 @@ function getRubyPath(meta, gemfileContents) {
|
|
|
7743
7840
|
return result;
|
|
7744
7841
|
}
|
|
7745
7842
|
async function installBundler(meta, gemfileContents) {
|
|
7746
|
-
const { gemHome, rubyPath, gemPath, vendorPath, runtime } = getRubyPath(
|
|
7747
|
-
meta,
|
|
7748
|
-
gemfileContents
|
|
7749
|
-
);
|
|
7750
|
-
if (meta.avoidTopLevelInstall) {
|
|
7751
|
-
(0, import_build_utils.debug)(
|
|
7752
|
-
`Skipping bundler installation, already installed by Install Command`
|
|
7753
|
-
);
|
|
7754
|
-
return {
|
|
7755
|
-
gemHome,
|
|
7756
|
-
rubyPath,
|
|
7757
|
-
gemPath,
|
|
7758
|
-
vendorPath,
|
|
7759
|
-
runtime,
|
|
7760
|
-
bundlerPath: (0, import_path.join)(gemHome, "bin", "bundler")
|
|
7761
|
-
};
|
|
7762
|
-
}
|
|
7843
|
+
const { gemHome, rubyPath, gemPath, vendorPath, runtime, major } = getRubyPath(meta, gemfileContents);
|
|
7763
7844
|
(0, import_build_utils.debug)("installing bundler...");
|
|
7764
7845
|
await (0, import_execa.default)(gemPath, ["install", "bundler", "--no-document"], {
|
|
7765
7846
|
stdio: "pipe",
|
|
@@ -7768,6 +7849,7 @@ async function installBundler(meta, gemfileContents) {
|
|
|
7768
7849
|
}
|
|
7769
7850
|
});
|
|
7770
7851
|
return {
|
|
7852
|
+
major,
|
|
7771
7853
|
gemHome,
|
|
7772
7854
|
rubyPath,
|
|
7773
7855
|
gemPath,
|
|
@@ -7776,6 +7858,10 @@ async function installBundler(meta, gemfileContents) {
|
|
|
7776
7858
|
bundlerPath: (0, import_path.join)(gemHome, "bin", "bundler")
|
|
7777
7859
|
};
|
|
7778
7860
|
}
|
|
7861
|
+
function isInstalled({ major, minor }) {
|
|
7862
|
+
const gemHome = "/ruby" + major + minor;
|
|
7863
|
+
return Boolean(import_which.default.sync((0, import_path.join)(gemHome, "bin/ruby"), { nothrow: true })) && Boolean(import_which.default.sync((0, import_path.join)(gemHome, "bin/gem"), { nothrow: true }));
|
|
7864
|
+
}
|
|
7779
7865
|
|
|
7780
7866
|
// src/index.ts
|
|
7781
7867
|
async function matchPaths(configPatterns, workPath) {
|
|
@@ -7791,7 +7877,7 @@ async function matchPaths(configPatterns, workPath) {
|
|
|
7791
7877
|
);
|
|
7792
7878
|
return patternPaths.reduce((a, b) => a.concat(b), []);
|
|
7793
7879
|
}
|
|
7794
|
-
async function bundleInstall(bundlePath, bundleDir, gemfilePath, rubyPath,
|
|
7880
|
+
async function bundleInstall(bundlePath, bundleDir, gemfilePath, rubyPath, major) {
|
|
7795
7881
|
(0, import_build_utils2.debug)(`running "bundle install --deployment"...`);
|
|
7796
7882
|
const bundleAppConfig = await (0, import_build_utils2.getWriteableDirectory)();
|
|
7797
7883
|
const gemfileContent = await (0, import_fs_extra.readFile)(gemfilePath, "utf8");
|
|
@@ -7805,6 +7891,11 @@ async function bundleInstall(bundlePath, bundleDir, gemfilePath, rubyPath, runti
|
|
|
7805
7891
|
gemfilePath,
|
|
7806
7892
|
gemfileContent.replace('ruby "~> 3.2.x"', 'ruby "~> 3.2.0"')
|
|
7807
7893
|
);
|
|
7894
|
+
} else if (gemfileContent.includes('ruby "~> 3.3.x"')) {
|
|
7895
|
+
await (0, import_fs_extra.writeFile)(
|
|
7896
|
+
gemfilePath,
|
|
7897
|
+
gemfileContent.replace('ruby "~> 3.3.x"', 'ruby "~> 3.3.0"')
|
|
7898
|
+
);
|
|
7808
7899
|
}
|
|
7809
7900
|
const bundlerEnv = (0, import_build_utils2.cloneEnv)(process.env, {
|
|
7810
7901
|
// Ensure the correct version of `ruby` is in front of the $PATH
|
|
@@ -7813,7 +7904,7 @@ async function bundleInstall(bundlePath, bundleDir, gemfilePath, rubyPath, runti
|
|
|
7813
7904
|
BUNDLE_APP_CONFIG: bundleAppConfig,
|
|
7814
7905
|
BUNDLE_JOBS: "4"
|
|
7815
7906
|
});
|
|
7816
|
-
if (
|
|
7907
|
+
if (major >= 3) {
|
|
7817
7908
|
const result2 = await (0, import_execa2.default)("bundler", ["add", "webrick"], {
|
|
7818
7909
|
cwd: (0, import_path2.dirname)(gemfilePath),
|
|
7819
7910
|
stdio: "pipe",
|
|
@@ -7862,7 +7953,7 @@ var build = async ({
|
|
|
7862
7953
|
await (0, import_fs_extra.writeFile)(gemfilePath, `source "https://rubygems.org"${import_os.EOL}`);
|
|
7863
7954
|
}
|
|
7864
7955
|
const gemfileContents = gemfilePath ? await (0, import_fs_extra.readFile)(gemfilePath, "utf8") : "";
|
|
7865
|
-
const { gemHome, bundlerPath, vendorPath, runtime, rubyPath } = await installBundler(meta, gemfileContents);
|
|
7956
|
+
const { gemHome, bundlerPath, vendorPath, runtime, rubyPath, major } = await installBundler(meta, gemfileContents);
|
|
7866
7957
|
process.env.GEM_HOME = gemHome;
|
|
7867
7958
|
(0, import_build_utils2.debug)(`Checking existing vendor directory at "${vendorPath}"`);
|
|
7868
7959
|
const vendorDir = (0, import_path2.join)(workPath, vendorPath);
|
|
@@ -7889,18 +7980,7 @@ var build = async ({
|
|
|
7889
7980
|
(0, import_build_utils2.debug)(
|
|
7890
7981
|
"did not find a vendor directory but found a Gemfile, bundling gems..."
|
|
7891
7982
|
);
|
|
7892
|
-
|
|
7893
|
-
if (meta.avoidTopLevelInstall && fileAtRoot) {
|
|
7894
|
-
(0, import_build_utils2.debug)("Skipping `bundle install` \u2014 already handled by Install Command");
|
|
7895
|
-
} else {
|
|
7896
|
-
await bundleInstall(
|
|
7897
|
-
bundlerPath,
|
|
7898
|
-
bundleDir,
|
|
7899
|
-
gemfilePath,
|
|
7900
|
-
rubyPath,
|
|
7901
|
-
runtime
|
|
7902
|
-
);
|
|
7903
|
-
}
|
|
7983
|
+
await bundleInstall(bundlerPath, bundleDir, gemfilePath, rubyPath, major);
|
|
7904
7984
|
}
|
|
7905
7985
|
} else {
|
|
7906
7986
|
(0, import_build_utils2.debug)('found vendor directory, skipping "bundle install"...');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/ruby",
|
|
3
3
|
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
|
4
|
-
"version": "2.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./dist/index",
|
|
7
7
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/fs-extra": "8.0.0",
|
|
19
19
|
"@types/semver": "6.0.0",
|
|
20
|
-
"@
|
|
20
|
+
"@types/which": "3.0.0",
|
|
21
|
+
"@vercel/build-utils": "8.0.0",
|
|
21
22
|
"execa": "2.0.4",
|
|
22
23
|
"fs-extra": "^7.0.1",
|
|
23
24
|
"jest-junit": "16.0.0",
|
|
24
|
-
"semver": "6.3.1"
|
|
25
|
+
"semver": "6.3.1",
|
|
26
|
+
"which": "3.0.0"
|
|
25
27
|
},
|
|
26
28
|
"scripts": {
|
|
27
29
|
"build": "node ../../utils/build-builder.mjs",
|
package/vc_init.rb
CHANGED
|
@@ -60,7 +60,7 @@ def webrick_handler(httpMethod, path, body, headers)
|
|
|
60
60
|
server.shutdown
|
|
61
61
|
Thread.kill(th)
|
|
62
62
|
|
|
63
|
-
# Net::HTTP
|
|
63
|
+
# Net::HTTP doesn't read the set the encoding so we must set manually.
|
|
64
64
|
# Bug: https://bugs.ruby-lang.org/issues/15517
|
|
65
65
|
# More: https://yehudakatz.com/2010/05/17/encodings-unabridged/
|
|
66
66
|
res_headers = res.each_capitalized.to_h
|