Sign In

cgi-core

Package Overview
Dependencies
Maintainers
1
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cgi-core - npm Package Compare versions

Comparing version
1.4.3
to
1.4.4
+14
-13
cgi-core.js

@@ -94,3 +94,3 @@ "use strict";

const execPath = getExecPath(filePath, config.extensions);
let env;
let env, cgiProcess, ac, timeoutId;

@@ -114,2 +114,13 @@ try {

});
const result = spawnProcess({
execPath,
fullFilePath,
env,
config,
req,
res,
useShell: execPath ? !absolutePaths[execPath] : false,
});
({ cgiProcess, ac, timeoutId } = result);
} catch (err) {

@@ -120,3 +131,3 @@ if (err.code === "ENOENT") {

}
if (err.code === "EACCES") {
if (err.code === "EACCES" || err.code === "EFTYPE") {
const message = `${fullFilePath} is not executable.`;

@@ -130,12 +141,2 @@ errorHandler.apply({ req, res, config }, [message]);

const { cgiProcess, ac, timeoutId } = spawnProcess({
execPath,
fullFilePath,
env,
config,
req,
res,
useShell: execPath ? !absolutePaths[execPath] : false,
});
await streamRequestPayload(cgiProcess, req, res, config);

@@ -145,3 +146,3 @@ streamResponsePayload(cgiProcess, req, res, config);

res.on("close", () => {
ac.abort();
ac?.abort();
req.destroy();

@@ -148,0 +149,0 @@ clearTimeout(timeoutId);

@@ -142,54 +142,117 @@ # Sample CGI/Perl Scripts

use warnings;
use CGI qw(:standard);
use CGI qw(escapeHTML);
use File::Spec;
use File::Basename;
use URI::Escape;
use File::Basename qw(dirname);
use URI::Escape qw(uri_escape);
# Use SCRIPT_FILENAME environment variable to get script directory
# 1. Graceful Error Handling Function
sub show_error {
my ($message, $status) = @_;
$status ||= '500 Internal Server Error';
print "Status: $status\r\n";
print "Content-Type: text/html; charset=UTF-8\r\n\r\n";
print <<"HTML";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Error</title>
</head>
<body>
<h1>Error</h1>
<p>@{[ escapeHTML($message) ]}</p>
</body>
</html>
HTML
exit;
}
# 2. Get and validate script path
my $script_path = $ENV{'SCRIPT_FILENAME'}
or die "SCRIPT_FILENAME environment variable is not set.";
or show_error("SCRIPT_FILENAME environment variable is not set.", '500 Server Misconfiguration');
my $script_dir = dirname($script_path);
my $web_base_url = "/cgi-bin";
# Get the current script's URL path
my $script_url_path = $ENV{'SCRIPT_NAME'};
$script_url_path =~ s/[^\/]+$//; # Remove script filename, keep path prefix
# prepend "/cgi-bin/" to the path
$script_url_path = $web_base_url . $script_url_path;
# 3. Cleanly resolve script URL prefix without duplicate slashes
my $web_base_url = "/cgi-bin";
my $raw_script_name = $ENV{'SCRIPT_NAME'} // '';
(my $script_url_path = $raw_script_name) =~ s{[^/]+$}{}; # Remove script file name
print header(-type => 'text/html; charset=UTF-8');
print start_html("Directory Listing");
print h1("Files and Folders in $script_dir");
# Combine base paths cleanly
my $base_href = File::Spec::Unix->catdir($web_base_url, $script_url_path);
$base_href =~ s{/{2,}}{/}g;
$base_href .= '/' unless $base_href =~ m{/$};
opendir(my $dh, $script_dir) or die "Cannot open directory $script_dir: $!";
my @items = grep { $_ ne '.' && $_ ne '..' } readdir($dh);
# 4. Open and read directory safely
opendir(my $dh, $script_dir)
or show_error("Cannot read directory: $!", '500 Internal Server Error');
my @raw_items = grep { $_ ne '.' && $_ ne '..' } readdir($dh);
closedir($dh);
# Case-insensitive natural sort (directories first, then files)
my @items = sort {
my $path_a = File::Spec->catfile($script_dir, $a);
my $path_b = File::Spec->catfile($script_dir, $b);
(-d $path_b <=> -d $path_a) || (lc($a) cmp lc($b))
} @raw_items;
# 5. Output HTTP Header & Page Content
print "Content-Type: text/html; charset=UTF-8\r\n\r\n";
print <<"HTML";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Directory Listing</title>
<style>
body { font-family: system-ui, -apple-system, sans-serif; margin: 2rem; background: #fafafa; color: #333; }
h1 { font-size: 1.5rem; word-break: break-all; }
ul { list-style-type: none; padding-left: 0; }
li { margin: 0.4rem 0; }
a { text-decoration: none; color: #0066cc; }
a:hover { text-decoration: underline; }
.dir { font-weight: bold; color: #1a0dab; }
.tag { font-size: 0.8em; color: #666; font-weight: normal; margin-left: 0.3rem; }
</style>
</head>
<body>
<h1>Files and Folders in @{[ escapeHTML($script_dir) ]}</h1>
HTML
if (@items) {
print ul(
map {
my $full_path = File::Spec->catfile($script_dir, $_);
my $encoded = uri_escape($_);
my $label = $_;
my $is_dir = -d $full_path;
print " <ul>\n";
for my $item (@items) {
my $full_path = File::Spec->catfile($script_dir, $item);
my $is_dir = -d $full_path;
# Preserve slashes in URI encoding if item contains them
my $encoded = uri_escape($item);
my $label = escapeHTML($item);
my $href = $base_href . $encoded . ($is_dir ? '/' : '');
# Create the correct URL pointing to the file or folder
my $href = $script_url_path . $encoded;
$href .= '/' if $is_dir;
my $dir_class = $is_dir ? ' class="dir"' : '';
my $dir_tag = $is_dir ? ' <span class="tag">[DIR]</span>' : '';
my $target = $is_dir ? '' : ' target="_blank" rel="noopener"';
li(
a({ href => $href, target => '_blank' }, $label)
. ($is_dir ? " [DIR]" : "")
);
} sort @items
);
print qq{ <li><a href="$href"$dir_class$target>$label</a>$dir_tag</li>\n};
}
print " </ul>\n";
} else {
print p("No files or directories found.");
print " <p>No files or directories found.</p>\n";
}
print end_html;
print <<"HTML";
</body>
</html>
HTML
1;
```
Feel free to modify and test these scripts in your CGI environment!
{
"name": "cgi-core",
"description": "Lightweight, zero-dependency middleware for hosting CGI scripts with HTTP/1.1 support",
"version": "1.4.3",
"version": "1.4.4",
"homepage": "https://lfortin.github.io/cgi-core",

@@ -6,0 +6,0 @@ "repository": {