Finding a CGI Replacement
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.