http snippets

Simple Mongrel HTTP server and custom Mongrel handler example

Tagged mongrel, http, server, handler  Languages ruby
# http://mongrel.rubyforge.org/rdoc/index.html
# gem install -y mongrel
require 'rubygems'
require 'mongrel'

# Usage: ruby mongrel_http_server.rb <host> <port> <docroot>
host    = ARGV[0] || "127.0.0.1"
port    = ARGV[1] || 80
docroot = ARGV[2] || "html/"

# Simple Mongrel handler that prints the current date and time
class HandlerExample < Mongrel::HttpHandler
   def process(request, response)
      response.start(200) do |head, out|
         head["Content-Type"] = "text/html"
         out.write Time.now
      end
   end
end

# Configure Mongrel and handlers
config = Mongrel::Configurator.new :host => host, :port => port do
  listener do
    uri "/",              :handler => Mongrel::DirHandler.new(docroot)
    uri "/handler_example", :handler => HandlerExample.new, :in_front => true
  end

  # CTRL+C to stop server
  trap("INT") { stop }
  run
end

# Start Mongrel
puts "Mongrel listening on '#{host}:#{port}', serving documents from '#{docroot}'."
config.join

A simple HTTP client for PHP

Tagged client, http, php  Languages php

A simple HTTP client for PHP that uses curl:

class HTTP {
    static function get($url, $headers=null) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_HEADER, true);

        if($headers) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        // Execute request
        $response = curl_exec($ch);

        // Split headers and body
        list($header_text, $body) = explode("\r\n\r\n", $response, 2);
        $header_lines = explode("\r\n", $header_text);

        // Extract HTTP status
        $header_line = array_shift($header_lines);
        if (preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@', $header_line, $matches)) {
            $status = $matches[1];
        }

        // Extract HTTP headers
        $headers = array();
        foreach ($header_lines as $header_line) {
            list($header, $value) = explode(': ', $header_line, 2);
            $headers[$header] = $value;
        }

        $info = curl_getinfo($ch); 

        curl_close($ch);    

        $status = $info['http_code'];

        return new Response($status, $body, $headers, $info);
    }
}

Even supports reading response headers.

class Response  {
    public function Response($code, $body, $headers, $info=null) {
        $this->code = $code;
        $this->body = $body;
        $this->headers = $headers;
        $this->info = $info;
    }
}

How to print all HTTP headers with PHP

Tagged php, request, headers, http  Languages php
<ul>
 <?php
   foreach($_SERVER as $h=>$v)
     if(ereg('HTTP_(.+)',$h,$hp))
       echo "<li>$h = $v</li>\n";
   header('Content-type: text/html');
  ?>
</ul>

Example of how to fetch a URL with Net:HTTP and Ruby

Tagged headers, http, ruby, example, net  Languages ruby
require 'net/http'
require 'net/https'

url = URI.parse('http://www.google.com/yo?query=yahoo')

http = Net::HTTP.new(url.host, url.port)

http.open_timeout = http.read_timeout = 10  # Set open and read timeout to 10 seconds
http.use_ssl = (url.scheme == "https")
       
headers = {
  'User-Agent'          => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12',
  'If-Modified-Since'   => '',
  'If-None-Match'       => ''
}

# Note to self, use request_uri not path: http://www.ruby-doc.org/core/classes/URI/HTTP.html#M004934
response, body = http.get(url.request_uri, headers)

puts response.code
puts response.message

response.each {|key, val| puts key + ' = ' + val}

A simple Python HTTP client

Tagged http, client, python  Languages python

A simple HTTP client I had laying around that I wrote a long time ago. It supports cookies, redirects and stuff:

#!/usr/bin/env python
#
#     Http
#
#     A simple HTTP client that supports persistent cookies
#

import cookielib
import httplib
#httplib.HTTPConnection.debuglevel = 1
import urllib2

class Http:
  def __init__(self, redirect_callback = None):
    self.redirect_callback = redirect_callback
    self.cookie_jar = cookielib.CookieJar()
    self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor (self.cookie_jar))

    urllib2.install_opener(self.opener)

  def get(self, url, headers = None):
    request = urllib2.Request(url, headers = headers)
    return self.execute_request(request)

  def post(self, url, headers = None, parameters = None):
    data = None
    if parameters != None:
      data = urllib.urlencode(parameters)

    request = urllib2.Request(url, data, headers)
    return self.execute_request(request)

  def execute_request(self, request):
    response = self.opener.open(request)
    # Check for redirect, maybe better way to do this
    if response.geturl() != request.get_full_url():
      if self.redirect_callback == None:
        raise "Redirected to '" + response.geturl() + "' but no redirect callback defined"
      else:
        self.redirect_callback(response)

    return response

Example of how to use Ruby's NET::HTTP

Tagged example, net::http, http, ruby, debug, https, timeout, proxy  Languages ruby

I always forget how to use NET:HTTP and examples online are of little help, so I use this code as a starting point when I work with NET:HTTP.

The code supports: * HTTP redirects * POST/GET * Headers * SSL/HTTPs * Proxies * Debugging HTTP traffic * HTTP connection and read timeout

require 'net/http'
require 'net/https'
require 'uri'

class HTTP
  class << self
    def get(url, options = {})
      execute(url, options)
    end

    def post(url, options = { :method => :post })
      execute(url, options)
    end

    protected
      def proxy
        http_proxy = ENV["http_proxy"]
        URI.parse(http_proxy) rescue nil
      end

      def to_uri(url)
        begin
          if !url.kind_of?(URI) 

            url = URI.parse(url)
          end
        rescue
          raise URI::InvalidURIError, "Invalid url '#{url}'"
        end

        if (url.class != URI::HTTP && url.class != URI::HTTPS)
          raise URI::InvalidURIError, "Invalid url '#{url}'"
        end

        url
      end

      def execute(url, options = {})
        options = { :parameters => {}, :debug => false, 
                    :http_timeout => 60, :method => :get, 
                    :headers => {}, :redirect_count => 0, 
                    :max_redirects => 10 }.merge(options)

        url = to_uri(url)
        
        if proxy
          http = Net::HTTP::Proxy(proxy.host, proxy.port).new(url.host, url.port)
        else
          http = Net::HTTP.new(url.host, url.port)
        end
        
        if url.scheme == 'https'
          http.use_ssl = true
          http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        end
        
        http.open_timeout = http.read_timeout = options[:http_timeout]
        
        http.set_debug_output $stderr if options[:debug]
        
        request = case options[:method]
          when :post
            request = Net::HTTP::Post.new(url.request_uri)
            request.set_form_data(options[:parameters])
            request
          else
            Net::HTTP::Get.new(url.request_uri)
        end

        options[:headers].each { |key, value| request[key] = value }
        response = http.request(request)

        if response.kind_of?(Net::HTTPRedirection)      
          options[:redirect_count] += 1

          if options[:redirect_count] > options[:max_redirects]
            raise "Too many redirects (#{options[:redirect_count]}): #{url}" 
          end

          redirect_url = redirect_url(response)

          if redirect_url.start_with?('/')
            url = to_uri("#{url.scheme}://#{url.host}#{redirect_url}")
          end

          response = execute(url, options)
        end

        response
      end

      # From http://railstips.org/blog/archives/2009/03/04/following-redirects-with-nethttp/
      def redirect_url(response)
        if response['location'].nil?
          response.body.match(/<a href=\"([^>]+)\">/i)[1]
        else
          response['location']
        end
      end
  end
end

You can also find my Net:HTTP example on Github

How to configure and use ASIHttpRequest with XCode

Tagged asihttprequest, objective-c, http, xcode  Languages objectivec

Get ASIHttpRequest from GitHub

$ cd project-dir
$ git clone git://github.com/pokeb/asi-http-request.git
mkdir -p lib/ASIHttpRequest
mv asi-http-request/Classes/* lib/ASIHttpRequest

Link required frameworks

In Groups & Files in XCode, right-click Frameworks > Linked Frameworks choose Add Existing Frameworks.

Select CoreServices.framework. Do the same for SystemConfiguration.framework.

Next add libz.1.2.3.dylib by selecting Add Existing Files from the same menu. The full path to this file is /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libz.1.2.3.dylib

Making asynchronous requests

- (void)requestDone:(ASIHTTPRequest *)request
{
    NSString *response = [request responseString];
    NSLog ( @"Response %@", response );

}

- (void)requestWentWrong:(ASIHTTPRequest *)request
{
    NSError *error = [request error];
    NSLog ( @"Something wrong" );
}

- (void)requestURL()
{
    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
    ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
    
    [request setDelegate:self];
    [request setDidFinishSelector:@selector(requestDone:)];
    [request setDidFailSelector:@selector(requestWentWrong:)];
    
        [networkQueue addOperation:request];
    [networkQueue go];
}

Making synchronous requests

NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
    ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
    [request start];
    NSError *error = [request error];
    
    if (!error) {
        NSString *response = [request responseString];
        NSLog ( @"Response: %@", response );
    } else {
        NSLog ( @"Something went wrong" );
    }

How to make asynchronous HTTP requests with NSURLConnection

Tagged nsurlconnection, objective-c, http  Languages objectivec

Example of how to make asynchronous HTTP requests with NSURLConnection:

//
//  HTTP.h
//
#import <Cocoa/Cocoa.h>
#import "HTTPDelegate.h"

@interface HTTP : NSObject {
    id delegate;
    NSMutableData *receivedData;
    NSURL *url;
}
@property (nonatomic,retain) NSMutableData *receivedData;
@property (retain) id delegate;

- (void)get: (NSString *)urlString;
- (void)post: (NSString *)urlString;

@end
//
//  HTTP.m
//

#import "HTTP.h"


@implementation HTTP

@synthesize receivedData;

- init {
    if ((self = [super init])) {
        
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}


- (void)setDelegate:(id)val
{
    delegate = val;
}

- (id)delegate
{
    return delegate;
}

- (void)get: (NSString *)urlString {
    
    NSLog ( @"GET: %@", urlString );

    self.receivedData = [[NSMutableData alloc] init];
    
       NSURLRequest *request = [[NSURLRequest alloc]
                             initWithURL: [NSURL URLWithString:urlString]
                             cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
                             timeoutInterval: 10
                             ];

       NSURLConnection *connection = [[NSURLConnection alloc]
                                   initWithRequest:request
                                   delegate:self
                                   startImmediately:YES];
    if(!connection) {
        NSLog(@"connection failed :(");
    } else {
        NSLog(@"connection succeeded  :)");
        
    }
    
    [connection release];
        [request release];  
        [receivedData release];  
}


- (void)post: (NSString *)urlString {
    
    // POST
    //[request setHTTPMethod:@"POST"];
    // NSString *postString = @"Some post string";
    //[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
}   

// ====================
// Callbacks
// ====================

#pragma mark NSURLConnection delegate methods
- (NSURLRequest *)connection:(NSURLConnection *)connection
             willSendRequest:(NSURLRequest *)request
            redirectResponse:(NSURLResponse *)redirectResponse {
    NSLog(@"Connection received data, retain count");
       return request;
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"Received response: %@", response);
    
      [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"Received %d bytes of data", [data length]); 
    
       [receivedData appendData:data];
    NSLog(@"Received data is now %d bytes", [receivedData length]); 

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Error receiving response: %@", error);
       [[NSAlert alertWithError:error] runModal];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
       // Once this method is invoked, "responseData" contains the complete result
    NSLog(@"Succeeded! Received %d bytes of data", [receivedData length]); 
    
    NSString *dataStr=[[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
    NSLog(@"Succeeded! Received %@ bytes of data", dataStr); 
    
    if ([delegate respondsToSelector:@selector(didFinishDownload:)]) {
        NSLog(@"Calling the delegate"); 
        //NSString* dataAsString = [[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease];
        [delegate performSelector:@selector(didFinishDownload:) withObject: dataStr];
    }
    
    [dataStr release];
}


@end

Hack for using OpenURI with SSL

Tagged hack, openuri, ssl, http  Languages ruby

This problem occurs with OpenURI and Ruby 1.8:

/usr/lib/ruby/1.8/net/http.rb:586:in connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: ce
rtificate verify failed (OpenSSL::SSL::SSLError)
        from /usr/lib/ruby/1.8/net/http.rb:586:in connect'
        from /usr/lib/ruby/1.8/net/http.rb:553:in do_start'
        from /usr/lib/ruby/1.8/net/http.rb:542:in start'
        from /usr/lib/ruby/1.8/open-uri.rb:242:in open_http'

With Ruby 1.9 you have an option to fix it like this:

open(uri,:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE)

For Ruby 1.8 you could do this:

require 'open-uri'
require 'openssl'

url = 'https://www....'
proxy = 'http://...'

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

puts open(url, :proxy => proxy).read

Code found here