# 2006-09-16 Atom Revisited

I went back to look at <span class="site">Atom</span><span class="separator">:</span><span class="page">:XML</span> and even wrote a mail to the maintainers, BenjaminTrott and Tatsuhiko Miyagawa, reporting on missing man pages and questions I had regarding the mode attribute of content elements.

But the most important piece I needed to know in order to write an Atom server inside Perl’s CGI.pm was knowing how to read the rest of the data from a POST request. The XML doesn’t come as part of the form!

I had to actually read the CGI.pm sources to figure it out. And the solution is very simple, except that it’s not documented in the man page:

  my $data =$q->param('POSTDATA');
my $entry = XML::Atom::Entry->new(\$data);

Yes, an undocumented parameter. Argh!!

The system already knows how to handle POST (for new pages), GET (to read existing pages), there’s an Atom feed (but not yet as flexible as the existing RSS 2.0 feed). So, there’s PUT to implement for updating pages, and testing to do. I’m testing my extension using the XML::Atom::Client library. Having this kind of unit test really helps! Once you have the infrastructure set up, haha. I can’t believe it took me so long to figure out the POSTDATA thing. And looking back it seems incomprehensible to try and develop for Flock directly without the XML::Atom::Client library to write unit tests.

Update: Hah. Time passes. Little Alex wants to write the code that accepts PUT requests. And finds that no data is being read. How’s that? Correct, the stupid POSTDATA hack only works when looking at a POST request. D’oh!

So now I’m using the following:

 sub AtomEntry { my $data =$q->param('POSTDATA'); if (not $data) { # CGI provides POSTDATA for POST requests, not for PUT requests local$/; # slurp $data = <STDIN>; } my$entry = XML::Atom::Entry->new(\$data); return$entry; } 

Well, actually, since I was being paranoid, I looked at the CGI.pm source code again and rewrote it as follows:

 sub AtomEntry { my $data =$q->param('POSTDATA'); if (not $data) { # CGI provides POSTDATA for POST requests, not for PUT requests. # The following code is based on the CGI->init code. my$content_length = defined($ENV{'CONTENT_LENGTH'}) ?$ENV{'CONTENT_LENGTH'} : 0; if ($content_length > 0 and$content_length < $MaxPost) {$q->read_from_client(\$data,$content_length, 0); } } my $entry = XML::Atom::Entry->new(\$data); return \$entry; } 

Tags: