How can I route a url to a CGI script in Rack? - rack

I have an app that has a htdocs folder with static files and a couple of CGI scripts on the httpd/cgi-bin folder. How can I use Rack with config.ru to serve this application?
My current config.ru:
map "/check" do
What here ("httpd/cgi-bin/check_wrapper.sh")
end
run Rack::Directory.new("htdocs")

You can use the backticks to run the command and grab the output.
map "/check" do
run Proc.new { |env| [200, {"Content-Type" => "text/html"}, [`./httpd/cgi-bin/check_wrapper.sh`] ] }
end
run Rack::Directory.new("htdocs")

Related

PHP script works from browser but not from Windows Server Task Scheduler or from CMD/PS

I have this simple script called webcam.php to acquire some screenshot from webcams
<?php
$d=date('YmdHis');
$url = 'http://xxx:40801/snap.jpeg?'.$d;
$img = 'camera_east.jpg';
echo file_put_contents($img, file_get_contents($url));
$url = 'http://xxx:40802/snap.jpeg?'.$d;
$img = 'camera_west.jpg';
echo file_put_contents($img, file_get_contents($url));
echo $d;
?>
and if I call http://xxx/webcam.php from browser, everything's OK:
I find the two pictures in the folder, and the script returns the length of the files and the timestamp as echoes.
I tried to make this script to be executed by the windows scheduler, but although it returns 0x0 the pictures are not updated.
(I tried also unlinking the images, and also using curl but nothing changes)
Then I tried to run the PHP script from command line (also from PowerShell):
something like:
C:\Program Files\PHP\v7.2\php.exe -f C:\\webcam.php
but again, although it seems working, since it returns the length of the two files and the timestamp, the pictures are not updated and if I add unlink command, files are not cancelled:
Clearly folder has all permissions...
I've not big experience in PHP... :-(
what can be wrong?
Thanks!
obviously from cmd/ps/scheduler requires the full path,
while from browser can accept relative path

Run script in relative path via System.cmd in elixir

I have a project with a executive file in it: ./bin/dcolors
So, I want to run this file via System.cmd/3. How can I do that?
My attempts
First: run just ./bin/dcolors.
System.cwd # => project path
System.cmd("./bin/dcolors", []) # => :enoent
The documentation for System#cmd/3 states:
command is expected to be an executable available in PATH unless an absolute path is given.
Since ./bin is assumingly not on the path, one might use the absolute path, retrieved via System#cwd/0 and joined with the relative one using Path#join/2:
System.cwd
|> Path.join("bin/dcolors")
|> System.cmd([])

Execute perl script using mason template

I have installed Mason module from cpan. Now i am executing my first program using mason template.
first_mason.mc
% my $name = "Mason";
Hello world! Welcome to <% $name %>.
first_mason.pl
#!/usr/local/bin/perl
use Mason;
my $mason = Mason->new(comp_root => '...');
print $mason->run('first_mason.mc')->output;
This throws an error as follows
first_mason.mc is not an absolute path at C:/Perl/site/lib/Mason/Request.pm line 256**
Note
I am placing both files in the path where mason is installed(to find an installation path ,i used perldoc -l Mason) and executed a program using perl first_mason.pl
There is no need to put your files in the directory where Mason is installed:
Perl should know where to find Mason when you import it with use (assuming your perl installation is correct).
Mason will know where to find the .mc file via the comp_root argument.
The component name needs to be specified as a path relative to comp_root, always beginning with /.
You need to leave out the .mc from the component name.
So, if you place the 2 files in your home directory, then the script should look like this:
#!/usr/local/bin/perl
use Mason;
my $mason = Mason->new(comp_root => $HOME_DIR); # where $HOME_DIR is `C:\User\your_name`
print $mason->run('/first_mason')->output;
From the documentation:
The component root and component paths
When you use Mason, you specify a component root that all component
files live under. Thereafter, any component will be referred to by its
virtual path relative to the root, rather than its full filename.
For example, if the component root is '/opt/web/comps', then the
component path '/foo/bar.mc' refers to the file
'/opt/web/comps/foo/bar.mc'.
#stevenl fully answers your question. Simply don't blindly copy the Synopsis from the Mason docs, need read the docs too. :) E.g. in the example code:
#!/usr/local/bin/perl
use Mason;
my $mason = Mason->new(comp_root => '...');
print $mason->run('/foo')->output;
you need replace
and the shebang line #!/usr/local/bin/perl with the real path to your perl interpreter
the '...' with the real path in the filesystem, where your component are, e.g.
comp_root => '/some/real/path/here/where/my/component/root/is'
However, I wrote this answer mainly with a reason: if you want use the Mason for the web-app development, check the Poet module too. It GREATLY simplifies the whole process, and you will not need care about many-many things. E.g. after installing the Poet you can simply:
poet new MyApp
myapp/bin/run.pl
and you will immediately get (without any configuration) an WORKING web-app, and you could access it in your browser at http://localhost:5000. Your component_root will be inside of the myapp directory as myapp/comps.

FInding relative path in Perl

I have the following code in a perl module,
package Foo;
our $pathToScript = "/home/Lucas/project841/python_script.py";
It is frequently called by other modules in the same file directory through
$output = `$Foo::pathToScript`;
# etc
I would like to remove the hard coding of the actual path and use relative path, Eg. ./python_script.py to call the script from other modules.
What would be the ideal way?
You said your Perl script is "frequently" called from the same directory where the Python script resides, not "always". If you remove the absolute path, you'll need to change that "frequently" to "always", and just change $pathToScript to the Python script name (no path).
You could also consider setting the environment PATH (in the Perl script) so that the Python script (without the full path in $pathToScript) is always found, regardless of where the user is running from or where the Perl script is located.

What is $ENV{DOCUMENT_ROOT} equivalent in perl CGI on Windows IIS (2003)

I'm migrating a perl cgi script from linux to windows IIS server 2003 and see that there is no DOCUMENT_ROOT environment variable.
Some googling suggests I can hack it by stripping stuff off the end of $0 or cwd, but getting the site root should be a common task. Is there a better or standard way of doing this?
IIS doesn't really have the notion of a document root in the same way with IIS, as each application is more or less self-contained and independent. For any request, PATH_TRANSLATED is usually a good base on which to build, it is set to the physical path name for the handling component set in PATH_INFO, and from that you can usually get to the file system locations using a little File::Spec navigation.
There's also a SCRIPT_TRANSLATED and SCRIPT_NAME, which may be closer to what you need. SCRIPT_NAME is essentially the host absolute URL (minus the scheme, host, and port) for script, and SCRIPT_TRANSLATED is the corresponding physical file. I use the URI and URI::file classes, and methods to manipulate them, for some of these tasks.
These will only be useful if your request is handled by the same application that serves files, but they do allow you do derive URLs which work. If you need the file system for the root application, the one mapped to "/", and your script is not in the same root application, you will likely have to do some accesses to the IIS metabase (essentially the equivalent to httpd.conf and friends, but queryable) to find this out.
You can print out all ENV variables with a simple CGI script, like this:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
foreach $key (keys %ENV) {
print "$key --> $ENV{$key}<br>";
}
From that output, it should be semi-obvious what the variable you're looking for is.