Ruby Net::HTTP tutorial
last modified October 18, 2026
In this article we show how to work with the standard Ruby Net::HTTP module. We grab data, post data, work with JSON, and connect to a secure web page. The tutorial uses Sinatra applications for several examples. ZetCode has also a concise Ruby tutorial.
The Hypertext Transfer Protocol (HTTP) is an application protocol for distributed, collaborative, hypermedia information systems. HTTP is the foundation of data communication for the World Wide Web.
Ruby Net::HTTP provides a rich library which can be used to build
HTTP clients.
Ruby Net::HTTP status
The code and message methods of the response give its
status.
#!/usr/bin/ruby require 'net/http' uri = URI 'https://example.com' res = Net::HTTP.get_response uri puts res.message puts res.code uri = URI 'https://example.com/news/' res = Net::HTTP.get_response uri puts res.message puts res.code uri = URI 'https://httpbin.org/redirect/1' res = Net::HTTP.get_response uri puts res.message puts res.code
We perform three HTTP requests with the get_response method
and check the returned status.
uri = URI 'https://example.com/news/' res = Net::HTTP.get_response uri puts res.message puts res.code
The status of the HTTP response is checked with the message
and code methods.
$ ./status_code.rb OK 200 Not Found 404 FOUND 302
200 is a standard response for successful HTTP requests, 404 tells that the requested resource could not be found, and 302 tells that the resource was temporarily redirected.
Ruby Net::HTTP HEAD request
A HEAD request is an HTTP GET request without a message body. The header of a request/response contains metadata, such as HTTP protocol version or content type.
The head method retrieves document headers. The headers consist of
fields, including date, server, content type, or last modification time.
#!/usr/bin/ruby require 'net/http' uri = URI "https://httpbin.org/response-headers?Last-Modified=Tue%2C%2013%20Oct%202026%2022%3A05%3A48%20GMT&Content-Type=text%2Fhtml" http = Net::HTTP.new uri.host, uri.port http.use_ssl = true res = http.head uri.request_uri puts res['server'] puts res['date'] puts res['last-modified'] puts res['content-type'] puts res['content-length']
The example prints the server, date, last modification time, content type, and
content length returned by an httpbin.org endpoint.
$ ./http_head.rb gunicorn/19.9.0 Sun, 18 Oct 2026 10:06:27 GMT Tue, 13 Oct 2026 22:05:48 GMT text/html 150
Ruby Net::HTTP GET request
The HTTP GET method requests a representation of the specified resource.
#!/usr/bin/ruby require 'net/http' uri = URI 'https://httpbin.org/xml' content = Net::HTTP.get uri puts content
The script grabs a small XML document from httpbin.org. The
net/http library is designed to work closely with the
uri module.
require 'net/http'
This will also require uri so we do not need to require
it separately.
content = Net::HTTP.get uri
The get method generates a GET request to the specified resource.
$ ./http_get.rb
<?xml version='1.0' encoding='us-ascii'?>
<!-- A SAMPLE set of slides -->
<slideshow
title="Sample Slide Show"
date="Date of publication"
author="Yours Truly"
>
<!-- TITLE SLIDE -->
<slide type="all">
<title>Wake up to WonderWidgets!</title>
</slide>
<!-- OVERVIEW -->
<slide type="all">
<title>Overview</title>
<item>Why <em>WonderWidgets</em> are great</item>
<item/>
<item>Who <em>buys</em> WonderWidgets</item>
</slide>
</slideshow>
The following program gets a small web page and strips its HTML tags.
#!/usr/bin/ruby
require 'net/http'
uri = URI "http://example.com"
doc = Net::HTTP.get uri
puts doc.gsub %r{</?[^>]+?>}, ''
The script strips the HTML tags of the example.com web page.
puts doc.gsub %r{</?[^>]+?>}, ''
A simple regular expression is used to strip the HTML tags.
Ruby Net::HTTP concurrent requests
In the following example, we make multiple requests concurrently.
#!/usr/bin/ruby
require 'net/http'
require 'uri'
urls = [
'https://example.com',
'https://httpbin.org',
'https://httpbin.org/html',
'https://www.ruby-lang.org'
]
threads = urls.map do |url|
Thread.new { Net::HTTP.get_response(URI url) }
end
threads.map(&:value).each do |res|
puts "#{res.message} #{res.code}"
end
We make the requests concurrently in separate threads and print their status codes and messages.
$ ./concurrent_requests.rb OK 200 OK 200 OK 200 OK 200
Sinatra
Sinatra is a popular Ruby web application framework. It is easy to install and set up. Some of our examples will also use a Sinatra application.
$ sudo gem install sinatra rackup webrick
We install Sinatra, the rackup server handler, and the WEBrick web
server. Sinatra 4 runs on Rack 3.
#!/usr/bin/ruby
require 'sinatra'
get '/' do
"First application"
end
The application reacts to the / route. It sends a simple message
back to the client.
$ ruby main.rb [2026-10-18 12:07:20] INFO WEBrick 1.7.0 [2026-10-18 12:07:20] INFO ruby 3.0.2 (2021-07-07) [x86_64-linux-gnu] == Sinatra (v4.2.1) has taken the stage on 4567 for development with backup from WEBrick [2026-10-18 12:07:20] INFO Rackup::Handler::WEBrick::Server#start: pid=41329 port=4567
The application is started with the ruby main.rb command. The
WEBrick server is launched; it listens on port 4567.
$ curl localhost:4567 First application
With the curl command line tool, we connect to the server and
access the / route. A message appears on the console.
Sinatra get method
The get method issues a GET request to the server. The GET method
requests a representation of the specified resource.
#!/usr/bin/ruby
require 'sinatra'
get '/greet' do
"Hello #{params[:name]}"
end
This is the Sinatra application file. Upon receiving the /greet
route, it returns a message containing the name which was sent by the client.
#!/usr/bin/ruby
require 'net/http'
uri = URI "http://localhost:4567/greet"
params = { :name => 'Peter' }
uri.query = URI.encode_www_form params
puts Net::HTTP.get uri
The script sends a variable with a value to the Sinatra application. The variable is specified directly in the URL.
params = { :name => 'Peter' }
This is the parameter that we send to the server.
uri.query = URI.encode_www_form params
We encode the parameter into the URL with the encode_www_form method.
puts Net::HTTP.get uri
The get method sends a GET request to the server. It returns the
response which is printed to the console.
$ ./client_get.rb Hello Peter
This is the output of the example.
127.0.0.1 - - [18/Oct/2026:12:07:45 +0200] "GET /greet?name=Peter HTTP/1.1" 200 11 0.0015
In this log of the WEBrick server we can see that the parameter was encoded into the URL.
We can directly put the parameter into the URL string.
#!/usr/bin/ruby require 'net/http' uri = URI "http://localhost:4567/greet?name=Peter" puts Net::HTTP.get uri
This is another way of issuing the GET message; it is essentially the same as the previous example.
Sinatra get user agent
In this section, we specify the name of the user agent.
#!/usr/bin/ruby
require 'sinatra'
get '/agent' do
request.user_agent
end
The Sinatra application returns the user agent sent by the client.
#!/usr/bin/ruby
require 'net/http'
uri = URI "http://localhost:4567"
http = Net::HTTP.new uri.host, uri.port
res = http.get '/agent', {'User-Agent' => 'Ruby script'}
puts res.body
This script creates a simple GET request to the Sinatra application.
res = http.get '/agent', {'User-Agent' => 'Ruby script'}
The user agent is specified in the second parameter of the get
method.
$ ./client_agent.rb Ruby script
The server responded with the name of the agent that we have sent with the request.
Sinatra posting a value
The post method dispatches a POST request on the given URL,
providing the key/value pairs for the fill-in form content.
#!/usr/bin/ruby
require 'sinatra'
post '/target' do
"Hello #{params[:name]}"
end
The Sinatra application returns a greeting on the /target
route. It takes the value from the params hash.
#!/usr/bin/ruby
require 'net/http'
uri = URI "http://localhost:4567/target"
params = { :name => 'Peter' }
res = Net::HTTP.post_form uri, params
puts res.body
The script sends a request with a name key having
Peter value. The POST request is issued with the
Net::HTTP.post_form method.
$ ./client_post.rb Hello Peter
127.0.0.1 - - [18/Oct/2026:12:09:36 +0200] "POST /target HTTP/1.1" 200 11 0.0007
With the POST method, the value is not sent in the request URL.
Retrieving definitions from a dictionary
In the following example, we look up a term with the dictionary service at
dict.org.
$ sudo gem install nokogiri
To parse the HTML response, we use the nokogiri gem.
#!/usr/bin/ruby
require 'net/http'
require 'nokogiri'
term = 'cat'
uri = URI 'https://dict.org/bin/Dict'
res = Net::HTTP.post_form(uri, 'Form' => 'Dict2', 'Query' => term,
'Database' => 'wn')
doc = Nokogiri::HTML res.body
puts doc.css('pre').map(&:text).join.strip
The script posts the term to the DICT web interface. The wn
database selects WordNet. Nokogiri::HTML parses the returned HTML.
res = Net::HTTP.post_form(uri, 'Form' => 'Dict2', 'Query' => term,
'Database' => 'wn')
The post_form method sends the form fields to the server.
doc = Nokogiri::HTML res.body
puts doc.css('pre').map(&:text).join.strip
We extract the text of the pre elements, which contain the
definitions.
$ ./get_term.rb
cat
n 1: feline mammal usually having thick soft fur and no ability
to roar: domestic cats; wildcats [syn: cat, true cat]
2: an informal term for a youth or man; "a nice guy"; "the guy's
only doing it for some doll" [syn: guy, cat, hombre,
bozo]
3: a spiteful woman gossip; "what a cat she is!"
...
The output is truncated here; WordNet returns all senses of the word.
JSON
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write and for machines to parse and generate.
Ruby includes the json library in its standard library, so no
separate installation is needed.
require 'sinatra'
require 'json'
get '/example.json' do
content_type :json
{ :name => 'Jane', :age => 17 }.to_json
end
The Sinatra application sends JSON data. It uses the to_json method
to do the job.
#!/usr/bin/ruby require 'net/http' require 'json' uri = URI 'http://localhost:4567/example.json' res = Net::HTTP.get uri data = JSON.parse res puts data["name"] puts data["age"]
The example reads JSON data sent by the Sinatra application.
$ ./parse_json.rb Jane 17
Next, we send JSON data to a Sinatra application from a Ruby script.
require 'sinatra'
require 'json'
post '/readjson' do
data = JSON.parse request.body.read
"#{data["name"]} is #{data["age"]} years old"
end
This application reads JSON data and sends back a message with the parsed values.
#!/usr/bin/ruby
require 'net/http'
require 'json'
uri = URI 'http://localhost:4567/readjson'
req = Net::HTTP::Post.new uri.path, initheader = {'Content-Type' =>'application/json'}
req.body = {:name => 'Jane', :age => 17}.to_json
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request req
end
puts res.body
This script sends JSON data to the Sinatra application and reads its response.
req = Net::HTTP::Post.new uri.path, initheader = {'Content-Type' =>'application/json'}
The 'application/json' content type must be specified in the header
of the request.
$ ./post_json.rb Jane is 17 years old
Redirection
Redirection is the process of forwarding one URL to a different URL. The HTTP response status code 302 is used for temporary URL redirection.
require 'sinatra'
get "/oldpage" do
redirect to("/files/newpage.html"), 302
end
In the Sinatra application, we use the redirect command to redirect
to a different location.
<!DOCTYPE html> <html> <head> <title>New page</title> </head> <body> <p> This is a new page </p> </body> </html>
This is the newpage.html file located in the
public/files subdirectory.
#!/usr/bin/ruby
require 'net/http'
uri = URI 'http://localhost:4567/oldpage'
res = Net::HTTP.get_response uri
if res.code == "302"
res = Net::HTTP.get_response URI res.header['location']
end
puts res.body
This script accesses the old page and follows the redirect. Note that this works for a single redirection.
res = Net::HTTP.get_response URI res.header['location']
The header's location field contains the address to which the file was redirected.
$ ./redirect.rb <!DOCTYPE html> <html> <head> <title>New page</title> </head> <body> <p> This is a new page </p> </body> </html>
127.0.0.1 - - [18/Oct/2026:12:09:43 +0200] "GET /oldpage HTTP/1.1" 302 - 0.0009 127.0.0.1 - - [18/Oct/2026:12:09:43 +0200] "GET /files/newpage.html HTTP/1.1" 200 113 0.0009
From the log we see that the request was redirected to a new file name. The communication consists of two GET messages.
In this article we have worked with the Ruby net/http module.
There are also similar Ruby HTTPClient and
Ruby Faraday on ZetCode.
List all Ruby tutorials.