HTTPS Post of XML data using Perl and curl and (optional) basic authentication

So, you need to post some data securely to one of them new-fangled web apps.

Here is my howto recipe:

#!/usr/bin/perl

use URI::Escape;
use IPC::Open2;

# note: your curl must be compiled with ssl support to use https URLs
my $post_url = "https://www.domain.com/cgi-bin/AcceptXML";

my $curl = "/usr/local/bin/curl";

# We should probably tell curl to override the content-type
# header to indicate that we are posting XML and not
# the standard application/x-www-form-urlencoded -- or maybe
# the app you're posting to actually expects you to post in
# that content type (if so, comment out the next line) eg
# in a param=value construct like: xml=[url-encoded xml]
#
my $curl_opt = "-H 'Content-Type: text/xml'";

# set $basic_auth = "" if the app does not require basic authentication
my $basic_auth = "username:password";

$post_url =~ s|://|://$basic_auth\@| if $basic_auth;

# curl -d can be followed by a string of post data
# OR a @file or in this case @- which means to
# read the data from stdin.  This is the best
# way to go if you are posting sensitive data and
# would like to avoid writing the data to a temp file.
#
# 2>/dev/null just suppresses output to STDERR.
# curl is very gabby with stderr for some reason.
#
open2(*README, *WRITEME, "$curl $curl_opt -d \@- $post_url 2>/dev/null");

# side note:
# Don't care about the response?  Use open with a pipe...
#
#   open(WRITEME,"|$curl $curl_opt -d \@- $post_url 2>/dev/null");
#
# ...and you won't have to deal with the Open2 library.

# sample post data... I like qq[] syntax for quoting multi-line
# strings but I suppose most people would use <<EOS here.
my $xml_out = qq[<?xml version="1.0" encoding="UTF-8"?>
<SomeXml>
 <SomeData>1234</SomeData>
 <SomeOtherData>x=25%</SomeOtherData>
 <MoreData id="445A">Pink Elephants</MoreData>
</SomeXml>
];

# pick one from A/B/C

# (A) web app expects urlencoded xml document
print WRITEME &uri_escape($xml_out);
# (B) web app expects application/x-www-form-urlencoded
# print WRITEME "xml=".&uri_escape($xml_out);
# (C) web app expects raw xml (no urlencoding)
# print WRITEME $xml_out;

close WRITEME;

my @answer = <README>;
close README;

my $answer = join('',@answer);

&processResponse($answer);

exit 0;

All Articles:
  • Java meets Flash (server/client)
  • Freedom of Position (dhtml)
  • Freedom of Position II: Date Picker (dhtml)
  • Video Poker Obsession (optimization)
  • Tag, You're It! Chunk, the All-Purpose Template Engine (java)
  • Look, Ma! Real Scroll Bars! (flash 5)
  • Perl, curl, and HTTPS Post for XML