#! / usr / bin / perl use strict; use warnings; use LWP :: UserAgent; # This is the file that will be sent my $ file = './files/some_file.bin'; # This is the URI to send the request to. my $ uri = 'http://somedomain.com/form/action/script'; # Request object my $ request = HTTP :: Request-> new ('POST', $ uri); # Create a separator, because if we do not specify it forcibly, then with $ ua-> request ($ request) it will not be included in the main title # though, you can simply make $ request-> as_string after forming the header object, then it will be substituted by default, but we will not risk my $ boundary = 'X'; my @rand = ('a' .. 'z', 'A' .. 'Z'); for (0..14) {$ boundary. = $ rand [rand (@rand)];} # Create a title: $ request-> header ('Content-Type' => 'multipart / form-data; boundary ='. $ boundary); $ request-> header ('User-Agent' => '<i> Mozilla Firefox 5.0: -) </ i>'); $ request-> header ('Referer' => '<i> http://somedomain.com/form </ i>'); $ request-> protocol ('HTTP / 1.0'); # Although it will make LWP :: UserAgent, but better immediately # Formation of ordinary, textual form parameters my $ field = HTTP :: Message-> new ( [ 'Content-Disposition' => 'form-data; name = "<i> fieldname </ i>" ', 'Content-Type' => 'text / plain; charset = utf-8 ', ]); # The HTTP header :: Headers is substituted during the creation of the HTTP :: Message object $ field-> add_content_utf8 ('<i> somevalue </ i>'); # As you can see, somevalue should be in UTF-8 $ request-> add_part ($ field); # ... And so on, for each text field ... # Formation of binary form parameters open (my $ fh, '<', $ file); # And you can first make a header, and then apply to HTTP :: Message my $ size = (stat $ file) [7]; my $ header = HTTP :: Headers-> new; $ header-> header ('Content-Disposition' => 'form-data; name = "<i> file </ i>"; filename = "<i> somefile.bin </ i>'); # Although filename can be calculated from the file name $ header-> header ('Content-Type' => '<i> application / octet-stream </ i>'); # Or appropriate file type my $ file_content = HTTP :: Message-> new ($ header); $ file_content-> add_content ($ _) while <$ fh>; $ request-> add_part ($ file_content); close $ fh; # ... And so on, for each file ... my $ response = $ ua-> request ($ request); if ($ response-> is_success) { print $ response-> content } else { die $ response-> status_line }
#! / usr / bin / perl use strict; use warnings; use HTTP :: Headers; use HTTP :: Message; use HTTP :: Request; use HTTP :: Response; use IO :: Socket :: INET; # This is the file that will be sent my $ file = './files/some_file.bin'; # This is the URI to send the request to. my $ uri = 'http://somedomain.com/form/action/script'; # Since we will use a socket, we need a domain, port and path separately my ($ domain, $ port, $ path) = $ uri = ~ m / ^ (?: https? \: \ / \ /)? ([^ \ / \:] +) (?: \: (\ d + ))? (. +) $ /; $ port || = 80; # Default # A bicycle is, of course, good, but you can easily form headers and non-binary request body using a ready-made module my $ header = HTTP :: Headers-> new; $ header-> header ('Content-Type' => 'multipart / form-data'); my $ request = HTTP :: Request-> new ('POST', $ uri, $ header); # Instead of $ path we have $ uri, so it should be ;-) $ request-> protocol ('HTTP / 1.0'); # It is strange that the default protocol does not set the HTTP :: Request protocol, therefore we set ourselves # For small amounts of data, such as text fields, the bike will also be superfluous # (SFCI) Conditions are the same as in the previous code (1) my $ field = HTTP :: Message-> new ( [ 'Content-Disposition' => 'form-data; name = "<i> fieldname </ i>" ', 'Content-Type' => 'text / plain; charset = utf-8 ', ]); $ field-> add_content_utf8 ('<i> somevalue </ i>'); # And here, too, utf8 $ request-> add_part ($ field); # ... And so on, for each text field ... Further, our request, but without the files we divide into the main title and the first part of the content # We divide the regular expression for $ request-> headers-> as_string does not return the first line of the request, namely, the POST command, # and collect the string yourself, you can of course, but laziness. my ($ head, $ content) = $ request-> as_string = ~ m / ^ (. +?) \ n \ n (. +) $ / s; Content is not finished here, so we cut off - [LF] [EOF] $ content = substr ($ content, 0, -4); # as well as the boundary $ content = ~ s / (\ - \ - [^ \ n] +) $ // s; my $ boundary = $ 1; # We consider the preliminary length of the request my $ length = length $ content; # Now our files: my $ files = []; my $ size = (stat $ file) [7]; my $ f_header = HTTP :: Headers-> new; $ f_header-> header ('Content-Disposition' => 'form-data; name = "<i> file </ i>"; filename = "<i> somefile.bin </ i>'); $ f_header-> header ('Content-Type' => '<i> application / octet-stream </ i>'); $ f_header = $ boundary. "\ n". $ f_header-> as_string. "\ n"; # We arrive at the length of the request $ length + = length $ f_header; $ length + = $ size; # Actually, the procedure below is only for cases when there are many files. # Then, we first need to calculate the length of the content, because it (the length) will be indicated in the main title push @ {$ files}, {header => $ f_header, file => $ file}; # ... And so on, for each file ... # So we have everything ready $ length + = length $ boundary .'-- '; # The end line is also considered # Open the socket my $ socket = IO :: Socket :: INET-> new ($ domain. ':'. $ port) || die $ !; # To the main title is long $ head. = "\ nContent-Length:". $ length; # Send the header and the first (text) part of the content to the socket print $ socket $ head; print $ socket "\ n \ n"; print $ socket $ content; foreach my $ file (@ {$ files}) { print $ socket $ file -> {header}; open (my $ fh, '<', $ file -> {file}); print $ socket $ _ while <$ fh>; print $ socket "\ n"; close $ fh; } # Send socket end of file print $ socket $ boundary .'-- '; # Send socket end of file shutdown ($ socket, 1); # Get the answer from the socket and parse it my $ response = HTTP :: Response-> parse (join ('', <$ socket>)); if ($ response-> is_success) { print $ response-> content } else { die $ response-> status_line }Well done (SFCI) I want to note that everything in the code in italics should be replaced with the corresponding values ​​of the problem condition. Note: SFCI - Special for copipaster's idiots. No comments.
Source: https://habr.com/ru/post/63432/
All Articles