{"id":307,"date":"2006-01-31T07:07:00","date_gmt":"2006-01-31T07:07:00","guid":{"rendered":"http:\/\/jclark.org\/weblog\/Programming\/Perl\/wisdom-of-the-documentation.html"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T04:00:00","slug":"wisdom-of-the-documentation","status":"publish","type":"post","link":"https:\/\/jclark.org\/weblog\/2006\/01\/31\/wisdom-of-the-documentation\/","title":{"rendered":"Wisdom of the Documentation"},"content":{"rendered":"<p>Today, I spent some time staring at an old piece of code that I had written at least a year ago.  It&#8217;s been in testing several times, but never put into production (the project it is tied to has been bumped on several occaisions).  Today, it was back in testing.<\/p>\n<p>The code is a failry simple web service, written in Perl.  I like Perl.  I have no illusions that I&#8217;m a fantastic Perl hacker, but I know the language well, though both experience and reading.  I&#8217;ve read most of the O&#8217;Reilly Perl titles, including <a href=\"http:\/\/www.amazon.com\/exec\/obidos\/ASIN\/0596000278\/ref=nosim\/jclarkorg-20\">Programming Perl<\/a> (&#8220;The Camel&#8221;), which I&#8217;ve read cover to cover at least three times.  I still find myself looking things up, usually to refresh my memory about something I can remember reading, or some syntax detail I can&#8217;t get right (one of the perils of working in multiple languages).  At least I generally know where to look.<\/p>\n<p>So this web service has been tested before.  It works in a browser, and it works when called by my test client.  It&#8217;s been tested with a third-party bit of code.  Today, it was tested by <a href=\"http:\/\/soulkerfuffle.blogspot.com\">Dave<\/a>, using some custom client code he had written in C#.  And it worked&#8230; <em>if<\/em> he told his http library to ignore HTTP protocol errors.  If he didn&#8217;t, his library complained.<\/p>\n<p>And so I stared at the code for a while.  By coincidence, I&#8217;d been reading <a href=\"http:\/\/www.faqs.org\/rfcs\/rfc2616.html\">the HTTP Spec<\/a> over the weekend (yes, I&#8217;m a geek), and was pretty sure my response was good-  a bare-minumum response, along the lines of:<\/p>\n<pre><code>HTTP\/1.1 200 OK\nContent-Type: text\/plain; charset=utf-8\n\nSingle Line Response<\/code><\/pre>\n<p>I double checked the spec anyway, and kept staring at the code.  I was about to start grasping at straws and adding additional entity headers to the response (such as Content-Length), when I finally stared at the code long enough.  I saw something like this:<\/p>\n<pre><code>print &quot;HTTP\/1.1 $status\\n&quot;\nprint &quot;Content-Type: text\/plain; charset=utf-8\\n&quot;<\/code><\/pre>\n<p>Then it hit me-  <code>&quot;\\n&quot;<\/code> in perl is a &#8220;magic newline&#8221;-  it conforms to the newline convention on the system in question.  HTTP, on the other hand, requires ASCII CR+LF (Cariage Return + Line Feed, or <code>&quot;\\r\\n&quot;<\/code> in C) as a line terminator.  Apparently all of the code thrown at the service before today was a bit forgiving.  I changed the strings to send CRLF using octal escape sequences (<code>&quot;\\015\\012&quot;<\/code>), and everything was fine.  I was a bit ticked about the mistake&#8230; I new both the HTTP requirement for CRLF and the Perl treatment of <code>&quot;\\n&quot;<\/code> when I originally wrote the code; it was a dumb mistake.  Also aggravating that it took so long to spot.<\/p>\n<p>And there my tale should end.  But this evening, I started wondering if the octal sequence was the most Perlish way to send a CRLF.  I knew that <code>&quot;\\r&quot;<\/code> is fine for the CR, but you can&#8217;t use <code>&quot;\\n&quot;<\/code> for the LF &#8211; it&#8217;s magic in perl, and behaves differently on different platforms.  I began to wonder if Perl has a backslash-escape for LF that is <em>always<\/em> LF.  Eventually, I had to check for myself, so I referred to the <a href=\"http:\/\/perldoc.perl.org\/perlop.html#Quote-and-Quote-like-Operators\">Quote and Quote-like Operators<\/a> section of the perlop man page. (Sadly, I knew right where to look, right down to the name of the section.  Geek, remember?)<\/p>\n<p>Turns out the manpage specifically recommends the octal form for networking applications (at least I got that right), but then it twists the knife:<\/p>\n<blockquote>\n<p>If you get in the habit of using <code>&quot;\\n&quot;<\/code>  for networking, you may be burned some day.<\/p>\n<\/blockquote>\n<p>D&#8217;oh.<\/p>","protected":false},"excerpt":{"rendered":"<p>Today, I spent some time staring at an old piece of code that I had written at least a year ago. It&#8217;s been in testing several times, but never put into production (the project it is tied to has been bumped on several occaisions). Today, it was back in testing. The code is a failry [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-307","post","type-post","status-publish","format-standard","hentry","category-perl"],"_links":{"self":[{"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/posts\/307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/comments?post=307"}],"version-history":[{"count":0,"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/posts\/307\/revisions"}],"wp:attachment":[{"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/media?parent=307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/categories?post=307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jclark.org\/weblog\/wp-json\/wp\/v2\/tags?post=307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}