Class: Net::Gemini
Overview
A Gemini client API for Ruby.
Net::Gemini provides a rich library which can be used to build Gemini user-agents. Net::Gemini is designed to work closely with URI.
Simple Examples
All examples assume you have loaded Net::Gemini with:
require 'net/gemini'
This will also require ‘uri’ so you don’t need to require it separately.
The Net::Gemini methods in the following section do not persist connections.
GET by URI
uri = URI('gemini://example.com/index.html?count=10')
Net::Gemini.get(uri) # => String
GET with Dynamic Parameters
uri = URI('gemini://example.com/index.html')
params = { :limit => 10, :page => 3 }
uri.query = URI.encode_www_form(params)
res = Net::Gemini.get_response(uri)
puts res.body if res.body_permitted?
Response Data
res = Net::Gemini.get_response(URI('gemini://exemple.com/home'))
# Status
puts res.status # => '20'
puts res.meta # => 'text/gemini; charset=UTF-8; lang=en'
# Headers
puts res.header.inspect
# => { status: '20', meta: 'text/gemini; charset=UTF-8',
mimetype: 'text/gemini', lang: 'en',
charset: 'utf-8', format: nil }
The lang, charset and format headers will only be provided in case of ‘text/*` mimetype, and only if body for 2* status codes.
# Body
puts res.body if res.body_permitted?
puts res.body(flowed: 85)
Following Redirection
The #fetch method, contrary to the #request one will try to automatically resolves redirection, leading you to the final destination.
u = URI('gemini://exemple.com/redirect')
res = Net::Gemini.start(u.host, u.port) do |g|
g.request(u)
end
puts "#{res.status} - #{res.}" # => '30 final/dest'
puts res.uri.to_s # => 'gemini://exemple.com/redirect'
u = URI('gemini://exemple.com/redirect')
res = Net::Gemini.start(u.host, u.port) do |g|
g.fetch(u)
end
puts "#{res.status} - #{res.}" # => '20 - text/gemini;'
puts res.uri.to_s # => 'gemini://exemple.com/final/dest'
Instance Attribute Summary collapse
-
#certs_path ⇒ Object
writeonly
Sets the attribute certs_path.
Class Method Summary collapse
Instance Method Summary collapse
- #fetch(uri, limit = 5) ⇒ Object
-
#initialize(host, port) ⇒ Gemini
constructor
A new instance of Gemini.
- #request(uri) ⇒ Object
Constructor Details
#initialize(host, port) ⇒ Gemini
Returns a new instance of Gemini.
95 96 97 98 99 |
# File 'lib/net/gemini.rb', line 95 def initialize(host, port) @host = host @port = port @certs_path = '~/.cache/gemini/certs' end |
Instance Attribute Details
#certs_path=(value) ⇒ Object (writeonly)
Sets the attribute certs_path
93 94 95 |
# File 'lib/net/gemini.rb', line 93 def certs_path=(value) @certs_path = value end |
Class Method Details
.get(uri) ⇒ Object
144 145 146 |
# File 'lib/net/gemini.rb', line 144 def get(uri) get_response(uri).body end |
.get_response(uri) ⇒ Object
140 141 142 |
# File 'lib/net/gemini.rb', line 140 def get_response(uri) start(uri.host, uri.port) { |gem| gem.fetch(uri) } end |
.start(host_or_uri, port = nil) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/net/gemini.rb', line 128 def start(host_or_uri, port = nil) if host_or_uri.is_a? URI::Gemini host = host_or_uri.host port = host_or_uri.port else host = host_or_uri end gem = new(host, port) return yield(gem) if block_given? gem end |
Instance Method Details
#fetch(uri, limit = 5) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/net/gemini.rb', line 114 def fetch(uri, limit = 5) raise GeminiError, 'Too many Gemini redirects' if limit.zero? r = request(uri) return r unless r.status[0] == '3' begin uri = handle_redirect(r) rescue ArgumentError, URI::InvalidURIError return r end warn "Redirect to #{uri}" if $VERBOSE fetch(uri, limit - 1) end |
#request(uri) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/net/gemini.rb', line 101 def request(uri) init_sockets req = GeminiRequest.new uri req.write @ssl_socket res = GeminiResponse.read_new(@ssl_socket) res.uri = uri res.reading_body(@ssl_socket) ensure # Stop remaining connection, even if they should be already cut # by the server finish end |