A Note on WP_Http and HTTP Requests in WordPress

We all know and love the How To Make HTTP Requests with WordPress article by @Ozh written back in 2009, and I had quite an interesting discussion in the WordPress IRC channel today, mainly about WP_Http and how the 302 and 301 redirects are handled through different transports. The initial question was about grabbing the final URL to which request was redirected to, turns out there is no good way of grabbing that.

But an interesting thing came up by @sivel (modified and formatted):

In general we recommend not interacting with the class directly but using the wrappers, but in any case, there is no way to grab the final efective URL. And the reason behind that is the class is lazy loaded, so that we are not consuming additional memory when we don’t need the class. We only include the functions and then lazy load the class if needed. … I would rely on what is always going to be included and not have to worry about including a file manually.

So it turns out that it’s best to use the wrapper functions, which are:

And some others defined in the wp-includes/http.php file.

So taking that into account, here are Ozh’s examples rewritten (and slightly modified) using the HTTP wrapper functions:

Simple HTTP GET Request

 $result = wp_remote_get( 'http://search.twitter.com/search.json?q=rabbits' );
 $json = json_encode( $result['body'] );
 print_r( $json );

Assuming that json_encode is available on your PHP installation.

Simple HTTP POST Request

 $url = 'http://your.api/endpoint';
 $post_data = array( 'name' => 'Konstantin' );
 $result = wp_remote_post( $url, array( 'body' => $post_data ) );

Check the $result variable for possible errors or output from your API.

Basic Authentication

 $url = 'http://your.api/endpoint';
 $username = 'your-username';
 $password = 'your-password';
 $headers = array( 'Authorization' => 'Basic ' . base64_encode( "$username:$password" ) );
 $result = wp_remote_get( $url, array( 'headers' => $headers ) );

Or use wp_remote_post and include the $post_data array if you’re firing a POST request with basic auth. Don’t forget to change the URLs used above to something more realistic, your.api doesn’t really exist (or does it?). A good place to find APIs to play around with is ProgrammableWeb.

So that’s about it! Doesn’t solve my redirect question though, but was definitely worth a try ;) Thank you for reading and of course retweeting!

Benchmarking: Your Web Hosting is Not That Perfect

Today I realized that the VPS I’m renting for $20/mo is not as good as it seemed at first. Ever thought about high loads? Okay, this may sound like some DDoS hacking tools, but no! 100 requests with 10 simultaneous made my virtual private server think for ~ 1,5 minutes. Jeez!

It took me quite some time to find good software for running some load tests on my webserver, linux has some good utilities (linux.com/feature/143896), but I suggest you start from ApacheBench which is a command line utility bundled with the Apache distribution. It’s cross-platform, therefore you can use it on Windows (I did). Anyways, here’s how you launch a test:

ab -n 100 -c 10 http://www.microsoft.com/

Why did I pick Microsoft? Well, if I get like 10,000 views tomorrow and everybody tries that command, that’d be a DDoS attack on Microsoft servers and I think they’re good enough to handle it. My server would just explode :)

Anyways, take a look at what the results may be like:

Benchmarking www.kovshenin.com (be patient).....done

Server Software:        Apache/2.2.8
Server Hostname:        www.kovshenin.com
Server Port:            80

Document Path:          /
Document Length:        84 bytes

Concurrency Level:      10
Time taken for tests:   90.984 seconds
Complete requests:      100
Failed requests:        1
   (Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors:           0
Non-2xx responses:      100
Total transferred:      36564 bytes
HTML transferred:       8674 bytes
Requests per second:    1.10 [#/sec] (mean)
Time per request:       9098.438 [ms] (mean)
Time per request:       909.844 [ms] (mean, across all concurrent requests)
Transfer rate:          0.39 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   15   3.4     16      16
Processing:  2203 8866 8879.2   6188   48797
Waiting:     1969 8532 8664.9   5891   48750
Total:       2219 8880 8879.6   6203   48813

Percentage of the requests served within a certain time (ms)
  50%   6203
  66%   7281
  75%   8141
  80%   8313
  90%  17078
  95%  32266
  98%  43813
  99%  48813
 100%  48813 (longest request)

Ah.. And a failed request there, how sad… You might also want to check out your load on the server while benchmarking. Use the ‘top’ command, it should produce similar output:

Yup, although the super cache plugin is working, wordpress consumes a lot of memory… I also ran this with a 500/100 requests, that made my server go down for like 6 minutes, I had over 200 failed requests and my blog kept saying database connection error until the test had finished. Free memory dropped down to 0! Scary? For more information about how ab works, read Apache HTTP server benchmarking tool documentation at apache.org.