Archive for March, 2013

iCurlHTTP – Curl for iOS

Friday, March 15th, 2013

iCurlHTTP

HTTP Server Response Diagnostic Tool

I love curl.  Systems engineers, developers, administrators, QA engineers and web operations specialist everywhere have used the curl tool to help troubleshoot web server responses.  It gives a quick view into exactly what is being sent from a web server to a browser.

Several weeks back on a commute home from work I started to think how handy it would be if the small computer I was holding, my iPhone, had a simple to use app like curl to do the same troubleshooting.  I always wanted to write my on iPhone app so I started researching how I could do that.

My Xcode Adventure

I’ve never used Xcode so I fired up the Xcode on my Snow Leopard equipped MacBook Pro.  I found a few great iOS development books on SafariOnline and started learning Objective-C.  After a few chapters I started going off the page and adding views and controllers.  I wanted to deploy my test apps to my iPhone so that required that I sign up as an Apple Developer (and $100!).  I soon discovered that my Xcode version was too out of date to work with my iOS 6.1 devices so I attempted to upgrade, only to discover that I needed to upgrade my OS.   Now on to Xcode 4.6 and suddenly my projects were running on my iPhone and iPad.

My libcurl Adventure

I discovered the NSURL class and started trying to get raw responses from web servers to display to the textview.  It was too digested and would require a lot of effort to simulate a raw curl session.  I started looking at the NSStream class when a friend suggested that I investigate precompiled version of libcurl for the ARM processor.  Instead, I found a great post by Nick Zitzmann where he shows how he compiled libcurl and even provides a binary: http://seiryu.home.comcast.net/~seiryu/libcurl-ios.html

I managed to get the latest version of libcurl to compile and also included the Apple SecureTransport library (–with-darwinsll in libcurl config):

#!/bin/bash
cd curl-7.29.0
export IPHONEOS_DEPLOYMENT_TARGET="4.3"
export CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2"
export CFLAGS="-arch armv7 -arch armv7s -pipe -Os -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk"
export LDFLAGS="-arch armv7 -arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk"
./configure --disable-shared --enable-static --with-darwinssl --disable-dependency-tracking --host="armv7-apple-darwin" --prefix=~/Code/curl/device
make -j `sysctl -n hw.logicalcpu_max`
make install

I added the libcurl.a library to my Xcode project and started using the easy interface API (e.g. CURLcode curl_easy_perform(CURL * handle )).  The realtime feel of iCurlHTTP comes from the use of the CURLOPT_WRITEFUNCTION option to push realtime code into a view controller method that renders to the textview object.  It required  periodically having the thread give up time to the mainRunLoop (via message to NSRunLoop) in order to allow the display to render and respond to user events.

iCurlHTTP Born

iCurlHTTP is a simple, easy to use iOS app that allows you to run cURL like tests, simulating different web browsers to retrive the raw HTTP headers and HTML response from the web servers.

OpenSSL Anyone?

The SecureTransport library works great but provided less details on SSL connections that I was accustomed to seeing with curl.  I wanted more x509 decoded information, specifcially SSL certificate details about expiration date.  The OpenSSL library would allow for this so I began another search to get an cross-compiled OpenSSL library for ARM7.   To get what I wanted, I needed to cross-compile both OpenSSL and libcurl together.

HTTP Timing added to iCurlHTTP v1.2

Curl has the ability to provide timing data for DNS lookup, TCP Connect, SSL Handshake, First Byte and Total time.  For example…

curl -k -s -o /dev/null -w '%{time_namelookup} %{time_connect} %{time_appconnect} %{time_pretransfer} %{time_redirect} %{time_starttransfer} %{time_total}n' https://jasonacox.com

I wanted to add this to iCurlHTTP to give a mobile perspective on these numbers.  In v1.2, I added this in the detail response view and as timing data points listed along the bottom of the UI.

The v1.2 version also includes the iOS 7 SDK updates and formatting for the new iOS.