I have used CGI since it was the new hot thing. I have been hesitant to move to the newer frameworks at work because reasons, including keeping a user-space server going, because I lack the ability to create another server on the machine where it’s running. So, while I may go that way for side projects, as they come to mind, I will continue to use CGI at work.

But, that doesn’t mean I will continue to use CGI.

Because I was loathe to spend too much time throwing stuff into production during the half-week before Thanksgiving, I spent time looking at some of the options. I have four styles of usage that I’d need to handle.

  • //hostname/?query_string=foo
  • //hostname/reading/path/info
  • <form method="POST" action="//hostname/">
  • curl -n -X POST //hostname/ -d '{"this":"is json"} #AJAX calls also work like this

The last looks like the second-to-last, but the behavior is different.

I am liking Plack::Request, mostly. It uses a lot of Hash::MultiValue. This is something I have to adjust to, because, going to the examples above, there is nothing stopping //hostname/?query_string=foo&query_string=bar&query_string=blee&query_string=quuz, and does that mean just the first value: $querystring="foo"? The alphabetically first: $querystring="bar"? The last: $querystring="quuz"? All: $querystring=["foo","bar","blee","quuz"]? It depends on what the rest of the system does.

A problem is that the regular tools I play with are that they don’t deal with Hash::MultiValue objects. Having written both the client and server sides, I have been careful to make the keys and values unique. So, I wrote a thing to make a regular hash from a H::MV object, where if there is just one value, it just does k->v, but when there are many, it makes an arrayref to shove them all into. When and if I convert all my stuff into the magical future, I may or may not use this technique, but I know how!

And, when you throw all the input into JSON, the unparsed data is in $req->content, and you can look for it with $req->content =~ /^\{/ && $req->content =~ /\}$/ to see if it’s parsable, and do my $params = JSON->decode($req->content) if it is.

And, I don’t do stuff with PATH_INFO often. The P::R method puts that into the call itself.

Because my code base was generated by several people over several decades, I’m not going to have a full switch-over any time soon. It isn’t a drop-in replacement. But I know I could make it work. So, that’s good.

If you have any questions or comments, I would be glad to hear it. Ask me on Twitter or make an issue on my blog repo.