I am trying to write a Perl Mojolicious request from CLI. I want to pass a file as a parameter to this request. Below are the things I have tried so far, but no avail.
Below Example is what working fine with me.
curl (working): curl -X POST "http://localhost:3000/uploadtest.pl/status?Token=6d949625-2f07-1e7a-d57a-de0fa949035d"
Mojolicious (working): perl ./uploadtest.pl get -v -M POST /status?"Token=3780e99a-fc2c-54e5-2c31-417f945c1792"
Below is the the example in which i am stuck, becouse below perl script take file as a input [file upload]:
curl (working): curl -X POST -F Input_File=@d:/xml/test.xml "http://localhost:3000/uploadtest.pl/upload?Input_Type=XML
Mojolicious (not working): perl ./uploadtest.pl get -v -M POST /upload?"Input_Type=XML&Input_File=d:/xml/test.xml"
It will be great help if someone helps me out with this.
#uploadtest.pl
use Mojolicious::Lite;
# Upload form in DATA section
get '/' => 'form';
# Check status
post '/status' => sub {
my $self = shift;
my $Token = $self->param('Token');
$self->render(text => "In process: $Token");
};
# Multipart upload handler
post '/upload' => sub {
my $self = shift;
# Process uploaded file
my $Input_File = $self->param('Input_File');
my $Input_Type = $self->param('Input_Type');
my $size = $Input_File->size;
my $name = $Input_File->filename;
my $upload = $self->req->upload('Input_File');
$upload->move_to("d:/xml/$name"); #move location
$self->render(text => "Thanks for uploading $size byte file $name.");
};
app->start;
__DATA__
@@ form.html.ep
<!DOCTYPE html>
<html>
<head><title>File Upload</title></head>
<body>
<form name="FileUpload" action="http://localhost:3000/uploadtest.pl/upload" enctype="multipart/form-data" method="post">
Input Type:</td><td><input type="text" name="Input_Type" />
Please specify a file:</td><td><input type="file" name="Input_File" size="40"></td></tr>
<input type="submit" value="Submit"/>
</form>
<br><br><br><hr><br><br><br>
<form name="Status" action="http://localhost:3000/uploadtest.pl/status" method="post">
Token ID: <input type="text" name="Token" />
<input type="submit" value="Check Status"/>
</form>
</body>
</html>
To post a file with Curl, use the -d or -F command-line options and start the data with the @ symbol followed by the file name. To send multiple files, repeat the -F option several times.
Transfer.sh is a simple, easy and fast service for file sharing from the command-line. It allows you to upload up to 10GB of data and files are stored for 14 days, for free. You can maximize amount of downloads and it also supports encryption for security.
The Mojolicious get command does not support generating requests from files i'm afraid.
perl -Mojo -E 'p("http://localhost:3000" => form => {Input_Type => "XML", Input_File => {file => "d:/xml/test.xml"}})'
You'd have to use an ojo
one-liner.
I think you are not understand what post '/upload'
does and uploadtest.pl
is.
Your script is a small HTTP server which receive requests and does responses.
You can run your server permanently and do requests with, for example, curl
or do one request to it and exit.
$ perl uploadtest.pl daemon
[Sat Jun 11 14:00:41 2016] [info] Listening at "http://*:3000"
Server available at http://127.0.0.1:3000
# in other shell
$ curl -X POST "http://localhost:3000/uploadtest.pl/status?Token=6d949625-2f07-1e7a-d57a-de0fa949035d"
Or both at once:
$perl ./uploadtest.pl get -v -M POST /status?"Token=3780e99a-fc2c-54e5-2c31-417f945c1792"
These POSTs make requests to permanent (first example) or onetime server (second one) with empty content
If you run your curl with -v
options:
$ curl -v -X POST "http://localhost:3000/status?Token=6d949625-2f07-1e7a-d57a-de0fa949035d"
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST /status?Token=6d949625-2f07-1e7a-d57a-de0fa949035d HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:3000
> Accept: */*
>
< HTTP/1.1 200 OK
* Server Mojolicious (Perl) is not blacklisted
< Server: Mojolicious (Perl)
< Date: Sat, 11 Jun 2016 11:42:24 GMT
< Content-Length: 48
< Content-Type: text/html;charset=UTF-8
<
* Connection #0 to host localhost left intact
In process: 6d949625-2f07-1e7a-d57a-de0fa949035d
You even may do tcpdump
while querying your server:
$ sudo tcpdump -x -X -i lo port 3000
14:41:51.665032 IP localhost.49063 > localhost.3000: Flags [P.], seq 1:129, ack 1, win 342, options [nop,nop,TS val 1097613 ecr 1097613], length 128
0x0000: 4500 00b4 38c4 4000 4006 037e 7f00 0001 E...8.@.@..~....
0x0010: 7f00 0001 bfa7 0bb8 3b17 8750 a281 4839 ........;..P..H9
0x0020: 8018 0156 fea8 0000 0101 080a 0010 bf8d ...V............
0x0030: 0010 bf8d 504f 5354 202f 7374 6174 7573 ....POST./status
0x0040: 3f54 6f6b 656e 3d36 6439 3439 3632 352d ?Token=6d949625-
0x0050: 3266 3037 2d31 6537 612d 6435 3761 2d64 2f07-1e7a-d57a-d
0x0060: 6530 6661 3934 3930 3335 6420 4854 5450 e0fa949035d.HTTP
0x0070: 2f31 2e31 0d0a 5573 6572 2d41 6765 6e74 /1.1..User-Agent
0x0080: 3a20 6375 726c 2f37 2e33 352e 300d 0a48 :.curl/7.35.0..H
0x0090: 6f73 743a 206c 6f63 616c 686f 7374 3a33 ost:.localhost:3
0x00a0: 3030 300d 0a41 6363 6570 743a 202a 2f2a 000..Accept:.*/*
0x00b0: 0d0a 0d0a ....
When you want to upload file to your server you use -F Input_File=@d:/xml/test.xml
curl option. You also expect you can do same onetime request, but next command:
$perl ./uploadtest.pl get -v -M POST /upload?"Input_Type=XML&Input_File=d:/xml/test.xml"
does not support such option.
$perl ./uploadtest.pl help get
Usage: APPLICATION get [OPTIONS] URL [SELECTOR|JSON-POINTER] [COMMANDS]
./myapp.pl get /
./myapp.pl get -H 'Accept: text/html' /hello.html 'head > title' text
./myapp.pl get //sri:secr3t@/secrets.json /1/content
mojo get mojolicious.org
mojo get -v -r google.com
mojo get -v -H 'Host: mojolicious.org' -H 'Accept: */*' mojolicious.org
mojo get -M POST -H 'Content-Type: text/trololo' -c 'trololo' perl.org
mojo get mojolicious.org 'head > title' text
mojo get mojolicious.org .footer all
mojo get mojolicious.org a attr href
mojo get mojolicious.org '*' attr id
mojo get mojolicious.org 'h1, h2, h3' 3 text
mojo get https://api.metacpan.org/v0/author/SRI /name
Options:
-C, --charset <charset> Charset of HTML/XML content, defaults to
auto-detection
-c, --content <content> Content to send with request
-H, --header <name:value> Additional HTTP header
-h, --help Show this summary of available options
--home <path> Path to home directory of your application,
defaults to the value of MOJO_HOME or
auto-detection
-M, --method <method> HTTP method to use, defaults to "GET"
-m, --mode <name> Operating mode for your application, defaults to
the value of MOJO_MODE/PLACK_ENV or
"development"
-r, --redirect Follow up to 10 redirects
-v, --verbose Print request and response headers to STDERR
As you can see from help, you can send short text message:
./uploadtest.pl get -M POST -H 'Content-Type: text/trololo' -c 'trololo' perl.org
To upload files into your uploadtest.pl
server you may write your own uploader. For this need you should use Mojo::UserAgent module. Example
use Mojo::UserAgent;
# Upload file via POST and "multipart/form-data"
my $ua = Mojo::UserAgent->new;
$ua->post("http://localhost:3000" => form => {Input_Type => "XML", Input_File => {file => "d:/xml/test.xml"}});
But this is same as:
perl -Mojo -E 'p("http://localhost:3000" => form => {Input_Type => "XML", Input_File => {file => "d:/xml/test.xml"}})'
UPD
To debug server side script for file uploading you should
perl -d uploadtest.pl daemon
Loading DB routines from perl5db.pl version 1.49_04
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(tx.pl:6): get '/' => 'form';
DB<1>
This will bring you into perl debugger (Tutorial)
DB<1> l 1-30
1 #uploadtest.pl
2
3: use Mojolicious::Lite;
4
5 # Upload form in DATA section
6==> get '/' => 'form';
7
8
9 # Check status
10 post '/status' => sub {
11: my $self = shift;
12: my $Token = $self->param('Token');
13: $self->render(text => "In process: $Token");
14: };
15
16 # Multipart upload handler
17 post '/upload' => sub {
18: my $self = shift;
19
20 # Process uploaded file
21: my $Input_File = $self->param('Input_File');
22: my $Input_Type = $self->param('Input_Type');
23: my $size = $Input_File->size;
24: my $name = $Input_File->filename;
25: my $upload = $self->req->upload('Input_File');
26: $upload->move_to("d:/xml/$name"); #move location
27: $self->render(text => "Thanks for uploading $size byte file $name.");
28: };
29
30: app->start;
DB<2> b 11
DB<3> b 18
DB<4> l 1-30
1 #uploadtest.pl
2
3: use Mojolicious::Lite;
4
5 # Upload form in DATA section
6==> get '/' => 'form';
7
8
9 # Check status
10 post '/status' => sub {
11:b my $self = shift;
12: my $Token = $self->param('Token');
13: $self->render(text => "In process: $Token");
14: };
15
16 # Multipart upload handler
17 post '/upload' => sub {
18:b my $self = shift;
19
20 # Process uploaded file
21: my $Input_File = $self->param('Input_File');
22: my $Input_Type = $self->param('Input_Type');
23: my $size = $Input_File->size;
24: my $name = $Input_File->filename;
25: my $upload = $self->req->upload('Input_File');
26: $upload->move_to("d:/xml/$name"); #move location
27: $self->render(text => "Thanks for uploading $size byte file $name.");
28: };
29
30: app->start;
DB<5> c
[Tue Jun 14 16:43:06 2016] [info] Listening at "http://*:3000"
Server available at http://127.0.0.1:3000
[Tue Jun 14 16:43:10 2016] [debug] POST "/status"
[Tue Jun 14 16:43:10 2016] [debug] Routing to a callback
main::CODE(0x23f7be0)(tx.pl:11): my $self = shift;
DB<5> n
main::CODE(0x23f7be0)(tx.pl:12): my $Token = $self->param('Token');
DB<5> n
main::CODE(0x23f7be0)(tx.pl:13): $self->render(text => "In process: $Token");
DB<5> x $Token
0 '6d949625-2f07-1e7a-d57a-de0fa949035d'
DB<6>
Here I list source from 1 to 30 line l 1-30
, set two breakpoints b 11
b 18
, list source again l 1-30
to see that breakpoints are in effect (Notice b near the line), run script from current point (Notice ==> sign near the line) until next break point, done two steps with n
command and view value of $Token variable with x $Token
command.
Notice, that after c
script wait interaction. I do that with curl
http://localhost:3000/status?Token=6d949625-2f07-1e7a-d57a-de0fa949035d
NOTICE: You should request '/status' and '/upload' NOT '/updater.pl/status' as you did. It has no matter for the outer word how your server script is named. Just only two things:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With