I'll never forget the feeling of enlightenment I received from the book Web Client Programming With Perl when I learned that I could simply telnet to a webserver and issue requests by hand. At the time, I was pleased simply because I felt this was a very neat thing to learn. It wasn't long, though, before I had occasion to use this knowledge in my job and in my education. (Tasked with writing a simple webserver for a class project, I went way out and wrote a server that supported CGI and exercised all sorts of things I was learning about UNIX at the time, including threading.) Today telnetting to webservers is not something I do every day, but it is something I need to do fairly frequently.
This week my assignment has involved writing Java code to interact with a (mostly standards-compliant) webservice. I've got documentation for zillions of supported parameters. Only a relatively small percentage of them are necessary, and those are all that I'm going to implement. I did need to compile a list of them, though. The best way to do that was to issue repeated requests to the webservice, taking note of the parameter it reports missing each time (it only reports one at a time; thanks, folks; I had the presence of mind to write a CGI program that reported all missing parameters rather than dying on the first one back in 1999 or so when I was 19 or 20), adding the missing parameter, and iterating.
Unfortunately, along with the "missing parameter" message which my browser happily displayed, the webservice also issued a 500 http error code. This in and of itself is not a problem, but under these circumstances, when you try to read the results of an http request in Java you get an exception rather than the text. Thanks, Sun. Brilliant design decision.
So Java was useless as a tool for this iterative process. The web browser would've been too clunky a tool for this process. Sadly, it didn't occur to me until just now that Perl could've been a good tool for this process, but even if it had, I had just spent far too long learning how to code this sort of thing in Java and was probably in no mood to face the learning curve for the same sort of thing in Perl, even though I'm sure it would've been far easier. So the best option available to me seemed to be telnetting to the webserver directly and debugging the process.
The catch: the webservice functions only under https. Good design decision. Bad for debugging. No, I don't have access to a development version of the service I could've run for myself over http. What to do?
Googling, of course, I quickly learned that I could use openssl to establish a session to an https server! It doesn't function totally like telnet: it spews some debugging information that I'd really rather not see and couldn't figure out how to turn off (at least in the amount of time allotted to me). But that wasn't too big a deal. As a nice bonus, since I was using HTTP/1.1, the session didn't terminate each time and I could very rapidly add parameters to my request (generated by a Perl program, of course :) ). In rapid-fire fashion, I completed the long list of needed parameters. When I left last night, I had completed the layer of code to talk to the webservice.
Here's the command:
openssl s_client -connect host.example.com:443
I suppose 443 could be replaced with some other port, of course, assuming it is possible to run https on another port and anyone is actually doing that. Don't ask me.
For the record, every place I saw this online had the parameters -state and -debug after the host:port part. I have no idea what those parameters do. Removing them doesn't seem to make any change whatsoever. Cargo cult code, I guess. It's not worth any effort on my part to find out. :)
For credit, here's one of the best-looking summaries of the command I saw, amongst the many pages I found which contained it. Like all the others, this guy uses -state and -debug:
I also saw reference to a telnet-ssl program which might've been great. I could only find this as part of Debian (and, by inheritance, Ubuntu). I did download the source, but it wouldn't compile for me, and I didn't want to invest the further effort to try the extra patch Debian had or to hunt down an origin for the source.