{"id":956,"date":"2013-08-14T17:51:25","date_gmt":"2013-08-14T22:51:25","guid":{"rendered":"http:\/\/osric.com\/chris\/accidental-developer\/?p=956"},"modified":"2013-08-14T17:51:25","modified_gmt":"2013-08-14T22:51:25","slug":"using-a-lightweight-web-server-to-debug-requests","status":"publish","type":"post","link":"https:\/\/osric.com\/chris\/accidental-developer\/2013\/08\/using-a-lightweight-web-server-to-debug-requests\/","title":{"rendered":"Using a lightweight web server to debug requests"},"content":{"rendered":"<p>I&#8217;ve been working a lot with the <a href=\"https:\/\/canvas.instructure.com\/doc\/api\/\">Canvas API<\/a> lately. One task was to add <a href=\"https:\/\/canvas.instructure.com\/doc\/api\/communication_channels.html#method.communication_channels.create\">communication channels<\/a> (e-mail addresses) to user accounts. I was able to add them successfully following the documentation&#8217;s cURL example using the skip_confirmation flag:<\/p>\n<p><code>curl 'https:\/\/mycanvas.instructure.com\/api\/v1\/users\/[user id]\/communication_channels'<br \/>\n    -H \"Authorization: Bearer [...]\"<br \/>\n    -d 'communication_channel[address]=chris@osric.com'<br \/>\n    -d 'communication_channel[type]=email'<br \/>\n    -d 'skip_confirmation=1'<\/code><\/p>\n<p>However, when I ran the ColdFusion script I wrote, the user received notification of the addition even though the skip_confirmation flag was set:<\/p>\n<p><code>&lt;cfhttp url=\"https:\/\/mycanvas.instructure.com\/api\/v1\/users\/[user id]\/communication_channels\" method=\"post\"&gt;<br \/>\n    &lt;cfhttpparam type=\"header\" name=\"Authorization\" value=\"Bearer [...]\" \/&gt;<br \/>\n    &lt;cfhttpparam type=\"formfield\" name=\"communication_channel[address]\" value=\"chris@osric.com\" \/&gt;<br \/>\n    &lt;cfhttpparam type=\"formfield\" name=\"communication_channel[type]\" value=\"email\" \/&gt;<br \/>\n    &lt;cfhttpparam type=\"formfield\" name=\"skip_confirmation\" value=\"1\" \/&gt;<br \/>\n&lt;\/cfhttp&gt;<\/code><\/p>\n<p>Why didn&#8217;t the latter work as expected?<\/p>\n<p>I needed to be able to tell what was different about the 2 requests, but it would be difficult to capture that outbound requests. Tools like <a href=\"http:\/\/fiddler2.com\/\">Fiddler<\/a> and <a href=\"http:\/\/www.wireshark.org\/\">WireShark<\/a> could help, but I was sending one request from my local machine and another from a remote web server.<\/p>\n<p>My idea for capturing the request data was to send the request to a server under my control. I grabbed a <a href=\"http:\/\/ilab.cs.byu.edu\/python\/socket\/echoserver.html\">Python echo server<\/a> and modified it slightly to print the data received. Then, instead of sending the requests to the Canvas API I sent them to the echo server. Here are the results of the 2 requests:<\/p>\n<p><strong>cURL<\/strong><br \/>\n<code>POST \/ HTTP\/1.1<br \/>\nUser-Agent: curl\/7.24.0 (i686-pc-cygwin) libcurl\/7.24.0 OpenSSL\/0.9.8t zlib\/1.2.5 libidn\/1.22 libssh2\/1.3.0<br \/>\nHost: osric.com:50000<br \/>\nAccept: *\/*<br \/>\nAuthorization: Bearer [...]<br \/>\nContent-Length: 100<br \/>\nContent-Type: application\/x-www-form-urlencoded<\/p>\n<p>communication_channel[address]=chris@osric.com&amp;communications_channel[type]=email&amp;skip_confirmation=1<\/code><\/p>\n<p><strong>ColdFusion<\/strong><br \/>\n<code>POST \/ HTTP\/1.1<br \/>\nUser-Agent: ColdFusion<br \/>\nContent-Type: application\/x-www-form-urlencoded<br \/>\nConnection: close<br \/>\nAuthorization: Bearer [...]<br \/>\nContent-Length: 118<br \/>\nHost: osric.com:50000<\/p>\n<p>communication%5Fchannel%5Baddress%5D=chris%40osric%2Ecom&amp;communications%5Fchannel%5Btype%5D=email&amp;skip%5Fconfirmation=1<\/code><\/p>\n<p>I noted the different content lengths for the same data, and upon closer inspection, ColdFusion was URL-encoding characters. I added the <em>encoded<\/em> attribute to the cfhttpparam tags with a value of &#8220;no&#8221;, and then the request bodies were identical:<\/p>\n<p><code>&lt;cfhttp url=\"https:\/\/mycanvas.instructure.com\/api\/v1\/users\/[user id]\/communication_channels\" method=\"post\"&gt;<br \/>\n    &lt;cfhttpparam type=\"header\" name=\"Authorization\" value=\"Bearer [...]\" \/&gt;<br \/>\n    &lt;cfhttpparam type=\"formfield\" encoded=\"no\" name=\"communication_channel[address]\" value=\"chris@osric.com\" \/&gt;<br \/>\n    &lt;cfhttpparam type=\"formfield\" encoded=\"no\" name=\"communication_channel[type]\" value=\"email\" \/&gt;<br \/>\n    &lt;cfhttpparam type=\"formfield\" encoded=\"no\" name=\"skip_confirmation\" value=\"1\" \/&gt;<br \/>\n&lt;\/cfhttp&gt;<\/code><\/p>\n<p>Not surprisingly that solved the problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been working a lot with the Canvas API lately. One task was to add communication channels (e-mail addresses) to user accounts. I was able to add them successfully following the documentation&#8217;s cURL example using the skip_confirmation flag: curl &#8216;https:\/\/mycanvas.instructure.com\/api\/v1\/users\/[user id]\/communication_channels&#8217; -H &#8220;Authorization: Bearer [&#8230;]&#8221; -d &#8216;communication_channel[address]=chris@osric.com&#8217; -d &#8216;communication_channel[type]=email&#8217; -d &#8216;skip_confirmation=1&#8217; However, when I ran &hellip; <a href=\"https:\/\/osric.com\/chris\/accidental-developer\/2013\/08\/using-a-lightweight-web-server-to-debug-requests\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Using a lightweight web server to debug requests<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,18],"tags":[308,309,299,300,349,215,310,358,311,307],"class_list":["post-956","post","type-post","status-publish","format-standard","hentry","category-coldfusion","category-debugging","tag-canvas","tag-canvas-api","tag-cfhttp","tag-cfhttpparam","tag-coldfusion","tag-curl","tag-echo-server","tag-python","tag-request-debugging","tag-url-encoding"],"_links":{"self":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/comments?post=956"}],"version-history":[{"count":4,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/956\/revisions"}],"predecessor-version":[{"id":961,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/956\/revisions\/961"}],"wp:attachment":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/media?parent=956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/categories?post=956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/tags?post=956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}