Class: Net::Gemini::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/net/gemini/response.rb,
lib/net/gemini/response/parser.rb

Overview

Reopen Response class to add specific private method to parse text/gemini documents.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status = nil, meta = nil) ⇒ Response

Returns a new instance of Response.



54
55
56
57
58
59
60
61
62
# File 'lib/net/gemini/response.rb', line 54

def initialize(status = nil, meta = nil)
  @status = status
  @meta = meta
  @header = parse_meta
  @uri = nil
  @body = nil
  @links = []
  @socket = nil
end

Instance Attribute Details

#body(reflow_at: -1)) ⇒ String

Return the response body (i.e. the requested document content).

Parameters:

  • reflow_at (Integer) (defaults to: -1))

    The column at which body content must be reflowed. Default is -1, which means “do not reflow”.

Returns:

  • (String)

    the body content



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/net/gemini/response.rb', line 102

def body(reflow_at: -1)
  return '' if @body.nil? # Maybe not ready?

  unless reflow_at.is_a? Integer
    raise(
      ArgumentError, "reflow_at must be Integer, #{reflow_at.class} given"
    )
  end

  return @body if reflow_at <= 0 || @header[:format] == 'fixed'

  Net::Text::Reflow.format_body(@body, reflow_at)
end

#headerHash{Symbol => String, nil} (readonly)

Returns The Gemini response <META>.

Examples:

{ status: '20', meta: 'text/gemini; charset=UTF-8',
  mimetype: 'text/gemini', lang: 'en',
  charset: 'utf-8', format: nil }

Returns:

  • (Hash{Symbol => String, nil})

    The Gemini response <META>.



36
37
38
# File 'lib/net/gemini/response.rb', line 36

def header
  @header
end

All links found on a Gemini response of MIME text/gemini

Each link is a Hash with the keys ‘:uri` containing the link URI, and `:label` containing the link label as a String, or nil if none was provided.

Returns:

  • (Array<Hash{:uri => ::URI; :label => String, nil}>)


52
53
54
# File 'lib/net/gemini/response.rb', line 52

def links
  @links
end

#metaString (readonly)

Returns The Gemini response <META> message sent by the server.

Examples:

"text/gemini"

Returns:

  • (String)

    The Gemini response <META> message sent by the server.



29
30
31
# File 'lib/net/gemini/response.rb', line 29

def meta
  @meta
end

#statusString (readonly)

Returns The Gemini response <STATUS> string.

Examples:

"20"

Returns:

  • (String)

    The Gemini response <STATUS> string.



24
25
26
# File 'lib/net/gemini/response.rb', line 24

def status
  @status
end

#uri::URI

The URI related to this response as an URI object.

Returns:



43
44
45
# File 'lib/net/gemini/response.rb', line 43

def uri
  @uri
end

Class Method Details

.read_new(sock) ⇒ Object

Raises:



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/net/gemini/response.rb', line 117

def read_new(sock)
  # Read up to 1029 bytes:
  # - 3 bytes for code and space separator
  # - 1024 bytes max for the message
  # - 2 bytes for <CR><LF>
  str = sock.gets($INPUT_RECORD_SEPARATOR, 1029)
  m = /\A([1-6]\d) (.*)\r\n\z/.match(str)
  raise BadResponse, "wrong status line: #{str.dump}" if m.nil?

  new(*m.captures)
end

Instance Method Details

#body_permitted?Boolean

Whether the current Net::Gemini::Response has a body of interest

(i.e. is not an error or a redirection).

Returns:

  • (Boolean)


67
68
69
# File 'lib/net/gemini/response.rb', line 67

def body_permitted?
  @status && @status[0] == '2'
end

#read_body {|self| ... } ⇒ String?

Read data from the SSL socket.

Yields:

  • (self)

Returns:

  • (String, nil)

    The data read from the socket (aka. the Response body)



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/net/gemini/response.rb', line 85

def read_body(&)
  return @body unless @socket

  @body = read_chunked(&)
  return @body unless @header[:mimetype] == 'text/gemini'

  parse_body
  @body
ensure
  @socket = nil
end

#reading_body(sock) ⇒ self

Set the socket to read data through #read_body.

Parameters:

  • sock (OpenSSL::SSL::SSLSocket)

Returns:

  • (self)


74
75
76
77
78
79
# File 'lib/net/gemini/response.rb', line 74

def reading_body(sock)
  return self unless body_permitted?

  @socket = sock
  self
end