How to debug the server side of the script to download files from the client (twisting in this example)?

I am trying to write a Perl Mojolicious request from the CLI. I want to pass the file as a parameter to this request. Below are those things that I have tried so far, but to no avail.

Below is an example of what works great 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 an example in which I am stuck because below the perl script I take the file as 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 a great help if someone helps me 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> 
+7
perl mojolicious
source share
2 answers

I think you do not understand what post '/upload' and uploadtest.pl .

Your script is a small HTTP server that receives requests and executes responses. You can constantly start your server and execute requests using, for example, curl or make one request 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 POST requests make the requests permanent (first example) or onetime server (second) with empty content

If you run a curl with the -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 can even run tcpdump when 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 a file to your server, you use the -F Input_File=@d :/xml/test.xml option -F Input_File=@d :/xml/test.xml curl. You also expect to be able to execute the same onetime request, but with the following command:

 $perl ./uploadtest.pl get -v -M POST /upload?"Input_Type=XML&Input_File=d:/xml/test.xml" 

does not support such an 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 the help, you can send a short text message:

  ./uploadtest.pl get -M POST -H 'Content-Type: text/trololo' -c 'trololo' perl.org 

To upload files to the uploadtest.pl server, you can write your own bootloader. To do this, use Mojo :: UserAgent . 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 the same as:

 perl -Mojo -E 'p("http://localhost:3000" => form => {Input_Type => "XML", Input_File => {file => "d:/xml/test.xml"}})' 

UPD

To debug the server side of the script for downloading files, you should

 perl -d uploadtest.pl daemon Loading DB routines from perl5db.pl version 1.49_04 Editor support available. Enter h or 'hh' for help, or 'man perldebug' for more help. main::(tx.pl:6): get '/' => 'form'; DB<1> 

This will lead you to the 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 the source from 1 to 30 lines l 1-30 , set two breakpoints b 11 b 18 , again return the source l 1-30 to see that the breakpoints are in effect (note b next to the line), run the script from the current point (notification ==> sign near the line) to the next breakpoint by completing two steps with the n command and presenting the $ Token variable using the x $Token command.

Please note that after the c script is waiting for interaction. I do it with curl

 http://localhost:3000/status?Token=6d949625-2f07-1e7a-d57a-de0fa949035d 

NOTIFICATION. You must request '/ status' and' / upload ' NOT ' /updater.pl/status, just like you. It doesn't matter for the outer word what your server script is called. Only two things:

  • Where is your script listen: localhost: 3000
  • Which request can serve: '/ upload' and '/ status'
+4
source share

The Mojolicious get team does not support generating requests from files that I'm afraid of.

 perl -Mojo -E 'p("http://localhost:3000" => form => {Input_Type => "XML", Input_File => {file => "d:/xml/test.xml"}})' 

You need to use a single line ojo .

+3
source share

All Articles