Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Separation boundary in multipart/form-data POSTs

by aardvark (Pilgrim)
on Jul 31, 2002 at 20:18 UTC ( #186591=perlquestion: print w/ replies, xml ) Need Help??
aardvark has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I am trying to POST to a Java servlet that is expecting multipart/form-data that conforms to W3C RFC-1341 section 7.2 . I am using LWP::UserAgent to generate the request, but it is not generating the boundary value in the HTTP headers. I have not seen any mention of a boundary value in any of the LWP related modules. According to the spec there should be a boundary=boundary_value after the Content-Type in the HTTP headers. Something like this;

Content-Type: multipart/form-data; boundary=_OPERAB__xxx

Do any of you wise people know how I can get the boundary in there. Do any of you have the Fonz like powers to tap my code and make the elusive boundary appear?

Here is the code:
my $ua = LWP::UserAgent->new; my $req = HTTP::Request->new; $req->method('POST'); $req->uri($servlet); $req->content_type('multipart/form-data'); $req->content("xmlmsg=$xmlmsg"); $req->authorization_basic($uid, $pass); # make the request to server my $res = $ua->request($req); print "\nREQUEST\n" . $req->as_string; print "\nRESPONSE\n" . $res->as_string;
The results are printed below:
REQUEST POST http://myservername.com/LLS/GenPublishMessage Authorization: Basic Z2thaG46bWF4aW5lMTMxMw== User-Agent: libwww-perl/5.64 Content-Type: multipart/form-data xmlmsg=<?xml version="1.0" encoding="UTF-8" ?><message id="EA10" prior +ity="High" timezone="CET" user_type="I"><head><active><from>9-Jul-02 +11:20:00 </from><to>9-Jul-02 11:20:00 </to></active><author id="gkahn +"/><attribute type="CATEGORY" value="GEEVENT"/><attribute type="COUNT +RY" value="EUROAREA"/><entitlement_attribute type="PERIOD" value="Jul +"/><entitlement_attribute type="PREV2" value="3.32"/><entitlement_att +ribute type="PREV1" value="3.33"/><entitlement_attribute type="LATEST +" value="3.36"/><entitlement_attribute type="LBGE" value="3.33"/><ent +itlement_attribute type="MARKET" value="na"/></head><body><title>ECB +refinancing operation (average rate) </title><content>ECB </content>< +/body></message> RESPONSE HTTP/1.1 200 OK Connection: close Date: Wed, 31 Jul 2002 19:44:18 GMT Server: Netscape-Enterprise/4.1 Content-Type: text/xml Client-Date: Wed, 31 Jul 2002 19:44:18 GMT Client-Response-Num: 1 <?xml version="1.0"?> <LL_BULLETIN_BOARD_PUBLISHING STATUS="FAILED"> java.io.IOException: Separation boundary was not specified </LL_BULLETIN_BOARD_PUBLISHING>
Get Strong Together!!

Comment on Separation boundary in multipart/form-data POSTs
Select or Download Code
Re: Separation boundary in multipart/form-data POSTs
by Shendal (Hermit) on Jul 31, 2002 at 20:30 UTC
    See perldoc HTTP::Request::Common (it's online here). It specifically addresses multi-part form-data under the POST heading.

    Cheers,
    Shendal
      Thanks for the reply Shendal, but HTTP::Request::Common lacks some features that I need for this to work. Namely Authentication. It surprises me that HTTP::Request::Common would construct the headers in a diferent way than HTTP::Request.

      I tried it with HTTP::Request::Common and got the following results:
      Code: my $ua = LWP::UserAgent->new; my $res = $ua->request(POST 'http://myserver.com/LLS/GenPublishMessa +ge', Content_Type => 'multipart/form-data', [xmlmsg => $xmlmsg]); Response: HTTP/1.1 302 (Found) redirecting for authentication purposes Connection: close Date: Wed, 31 Jul 2002 21:23:53 GMT Location: http://myserver.com/securecontrol/ct_logon_int_qa.html?ct_or +ig_uri=%2FLLS%2FGenPublishMessage Server: Netscape-Enterprise/4.1 Client-Date: Wed, 31 Jul 2002 21:23:53 GMT Client-Response-Num: 1 P3P: CP="NON CURa ADMa DEVa TAIa IVAa OUR DELa SAMa LEG UNI PRE"
      Get Strong Together!!
        I think what you want is to pass to your content method an array reference, not a string. In your first example,  $req->content("xmlmsg=$xmlmsg"); should be $req->content([ xmlmsg => $xmlmsg ]);.

        The pertinent part of the man page I was referring to is:
        The POST method also supports the multipart/form-data content used for Form-based File Upload as specified in RFC 1867. You trigger this content format by specifying a content type of 'form-data' as one of the request headers. If one of the values in the $form_ref is an array reference, then it is treated as a file part specification with the following interpretation:
        [ $file, $filename, Header => Value... ]
        The first value in the array ($file) is the name of a file to open. This file will be read and its content placed in the request. The routine will croak if the file can't be opened. Use an undef as $file value if you want to specify the content directly. The $filename is the filename to report in the request. If this value is undefined, then the basename of the $file will be used. You can specify an empty string as $filename if you don't want any filename in the request.

        Note that I have not tested this code, but I hope it points you in the right direction.
        Cheers,
        Shendal
Re: Separation boundary in multipart/form-data POSTs
by hossman (Prior) on Jul 31, 2002 at 21:11 UTC
    Shendal is on the money ... but if it's not obvious, you should pay attention to the differences between what you are passing to the content method, and what is used in the examples for multipart POSTs
Re: Separation boundary in multipart/form-data POSTs
by aardvark (Pilgrim) on Aug 01, 2002 at 03:02 UTC
    Thanks for all your help. I got the boundary value to appear after much finagling with the Content portion.
    Authentication was driving me nuts, until, I came across a wonderful little post from tilly. This place is full of Fonzies!!

    Re (tilly) 2: HTTP::Headers, HTTP::Request, Authentication, LWP::Useragent

    The working code looks like this:
    my $ua = LWP::UserAgent->new; my $uri = "http://" . "$uid" . ":" . "$pass" . "@" . "myserver.com/LL +S/GenPublishMessage"; my $req = $ua->request(POST "$uri", Content_Type => 'multipart/form-data', Content => [ xmlmsg=>$xmlmsg ]);

    Get Strong Together!!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://186591]
Approved by tadman
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2014-10-02 05:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    What is your favourite meta-syntactic variable name?














    Results (49 votes), past polls