Skip to content

Instantly share code, notes, and snippets.

@iaintshine
Created August 13, 2014 17:50
Show Gist options
  • Save iaintshine/91e40d52e04269c05585 to your computer and use it in GitHub Desktop.
Save iaintshine/91e40d52e04269c05585 to your computer and use it in GitHub Desktop.
A sample Ruby application showing how to make an HTTP request using TCP Sockets
#!/usr/bin/env ruby
# http.rb
#
# Sample application showing how to create HTTP request using TCP Sockets in Ruby
require 'socket'
class Request
attr_reader :method, :host, :resource, :client, :lines
def initialize(method, host, resource = '/index.html' , client = 'http')
@method, @host, @resource, @client = method, host, resource, client
prepare_message
end
private
def prepare_message
@lines ||= [
"#{@method} #{resource} HTTP/1.1\r\n",
"Host: #{@host}\r\n",
"User-Agent: #{@client}\r\n",
"\r\n"
]
end
end
class Response
REGEXP_HTTP_STATUS_LINE = /HTTP\/1.1 (\d{3}) (.*)/
attr_reader :lines, :status, :reason, :headers, :body
def initialize(lines)
@lines = lines
extract_status_line
extract_headers
extract_body
end
private
def extract_status_line
@lines[0].chop.match(REGEXP_HTTP_STATUS_LINE) do |match|
@status = match.captures[0]
@reason = match.captures[1]
end
end
def extract_headers
sep = @lines.find_index { |line| line == "\r\n" }
@headers = @lines[0, sep].map { |line| line.chop }
end
def extract_body
sep = @lines.find_index { |line| line == "\r\n" }
@body = @lines[(sep + 1..-1)]
end
end
class HTTP
class << self
def get(url)
s = TCPSocket.new url, 80
req = Request.new :GET, url
req.lines.each { |line| s.print line }
lines = []
while line = s.gets
lines << line
end
res = Response.new lines
s.close
res
end
end
end
ARGV.each do |url|
response = HTTP.get url
puts %Q{"#{url}" response with #{response.status} #{response.reason}}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment