Class: Pakyow::Connection

Inherits:
Object
  • Object
show all
Includes:
Support::Inspectable, Support::Hookable, Support::Pipeline::Object
Defined in:
lib/pakyow/connection.rb,
lib/pakyow/connection/params.rb,
lib/pakyow/connection/statuses.rb,
lib/pakyow/connection/query_parser.rb,
lib/pakyow/connection/multipart_input.rb,
lib/pakyow/connection/multipart_parser.rb

Overview

Represents the connection throughout a request/response lifecycle.

Direct Known Subclasses

Rack::Connection

Defined Under Namespace

Classes: Endpoint, MultipartInput, MultipartParser, Params, QueryParser, Statuses

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request) ⇒ Connection

Returns a new instance of Connection.



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/pakyow/connection.rb', line 56

def initialize(request)
  @id = SecureRandom.hex(4)
  @timestamp = Time.now
  @status = 200
  @headers = {}
  @request = request
  @body = Async::HTTP::Body::Buffered.wrap(StringIO.new)
  @params = Pakyow::Connection::Params.new
  @logger = Logger.new(:http, started_at: @timestamp, id: @id, output: Pakyow.global_logger, level: Pakyow.config.logger.level)
  @streams = []
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body.



43
44
45
# File 'lib/pakyow/connection.rb', line 43

def body
  @body
end

#errorObject

Contains the error object when the connection is in a failed state.



47
48
49
# File 'lib/pakyow/connection.rb', line 47

def error
  @error
end

#headersObject (readonly)

Returns the value of attribute headers.



43
44
45
# File 'lib/pakyow/connection.rb', line 43

def headers
  @headers
end

#idObject (readonly)

Returns the value of attribute id.



43
44
45
# File 'lib/pakyow/connection.rb', line 43

def id
  @id
end

#input_parser=(value) ⇒ Object (writeonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



50
51
52
# File 'lib/pakyow/connection.rb', line 50

def input_parser=(value)
  @input_parser = value
end

#loggerObject (readonly)

Returns the value of attribute logger.



43
44
45
# File 'lib/pakyow/connection.rb', line 43

def logger
  @logger
end

#requestObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



52
53
54
# File 'lib/pakyow/connection.rb', line 52

def request
  @request
end

#statusObject

Returns the value of attribute status.



43
44
45
# File 'lib/pakyow/connection.rb', line 43

def status
  @status
end

#timestampObject (readonly)

Returns the value of attribute timestamp.



43
44
45
# File 'lib/pakyow/connection.rb', line 43

def timestamp
  @timestamp
end

Instance Method Details

#authorityObject



136
137
138
# File 'lib/pakyow/connection.rb', line 136

def authority
  @request.authority
end

#closeObject



282
283
284
# File 'lib/pakyow/connection.rb', line 282

def close
  @body.close
end

#cookiesObject



242
243
244
245
246
247
248
# File 'lib/pakyow/connection.rb', line 242

def cookies
  unless instance_variable_defined?(:@cookies)
    parse_cookies
  end

  @cookies
end

#delete_header(key) ⇒ Object



94
95
96
# File 'lib/pakyow/connection.rb', line 94

def delete_header(key)
  @headers.delete(normalize_header(key))
end

#endpointObject



188
189
190
191
192
193
194
# File 'lib/pakyow/connection.rb', line 188

def endpoint
  unless instance_variable_defined?(:@endpoint)
    @endpoint = Endpoint.new(path, params).freeze
  end

  @endpoint
end

#finalizeObject



320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/pakyow/connection.rb', line 320

def finalize
  performing :finalize do
    if request_method == "HEAD"
      if streaming?
        @streams.each(&:stop); @streams = []
      end

      close; @body = Async::HTTP::Body::Buffered.wrap(StringIO.new)
    end

    set_cookies

    if streaming?
      Async::Reactor.run do
        while stream = @streams.shift
          stream.wait
        end

        close
      end
    end

    if instance_variable_defined?(:@response)
      @response
    else
      Async::HTTP::Protocol::Response.new(nil, @status, finalize_headers, @body)
    end
  end
end

#formatObject

Returns the symbolized format of the request.

Examples:

request.format
=> :html


202
203
204
205
206
207
208
# File 'lib/pakyow/connection.rb', line 202

def format
  unless instance_variable_defined?(:@format)
    parse_format
  end

  @format
end

#format=(format) ⇒ Object

Sets the Content-Type header based on the format.

Examples:

request.format = :json
request.content_type
=> "application/json"


257
258
259
260
261
262
263
# File 'lib/pakyow/connection.rb', line 257

def format=(format)
  if mime = MiniMime.lookup_by_extension(format.to_s)
    set_header("content-type", mime.content_type)
  end

  @format = format
end

#fullpathObject



180
181
182
# File 'lib/pakyow/connection.rb', line 180

def fullpath
  @request.path
end

#header(key) ⇒ Object



80
81
82
# File 'lib/pakyow/connection.rb', line 80

def header(key)
  @headers[normalize_header(key)]
end

#header?(key) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/pakyow/connection.rb', line 76

def header?(key)
  @headers.key?(normalize_header(key))
end

#hijack!Object



316
317
318
# File 'lib/pakyow/connection.rb', line 316

def hijack!
  @request.hijack!
end

#hijack?Boolean

Returns:

  • (Boolean)


312
313
314
# File 'lib/pakyow/connection.rb', line 312

def hijack?
  @request.hijack?
end

#hostObject



140
141
142
143
144
145
146
# File 'lib/pakyow/connection.rb', line 140

def host
  unless instance_variable_defined?(:@host)
    parse_authority
  end

  @host
end

#inputObject



98
99
100
# File 'lib/pakyow/connection.rb', line 98

def input
  @request.body
end

#ipObject



184
185
186
# File 'lib/pakyow/connection.rb', line 184

def ip
  request_header("x-forwarded-for").to_a.first || @request.remote_address.ip_address
end

#methodObject

Returns the request method (e.g. ‘:get`).



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/pakyow/connection.rb', line 112

def method
  unless instance_variable_defined?(:@method)
    @method = if request_method == "POST" && params.include?(:"pw-http-method")
      params[:"pw-http-method"].downcase.to_sym
    else
      request_method.downcase.to_sym
    end
  end

  @method
end

#paramsObject

Returns an indifferentized params hash.



234
235
236
237
238
239
240
# File 'lib/pakyow/connection.rb', line 234

def params
  unless instance_variable_defined?(:@built_params)
    build_params
  end

  @params
end

#parsed_inputObject



102
103
104
105
106
107
108
# File 'lib/pakyow/connection.rb', line 102

def parsed_input
  unless instance_variable_defined?(:@parsed_input)
    @parsed_input = nil; @parsed_input = parse_input
  end

  @parsed_input
end

#pathObject



164
165
166
167
168
169
170
# File 'lib/pakyow/connection.rb', line 164

def path
  unless instance_variable_defined?(:@path)
    parse_path
  end

  @path
end

#portObject



148
149
150
151
152
153
154
# File 'lib/pakyow/connection.rb', line 148

def port
  unless instance_variable_defined?(:@port)
    parse_authority
  end

  @port
end

#queryObject



172
173
174
175
176
177
178
# File 'lib/pakyow/connection.rb', line 172

def query
  unless instance_variable_defined?(:@query)
    parse_path
  end

  @query
end

#request_header(key) ⇒ Object



72
73
74
# File 'lib/pakyow/connection.rb', line 72

def request_header(key)
  @request.headers[normalize_header(key)]
end

#request_header?(key) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/pakyow/connection.rb', line 68

def request_header?(key)
  @request.headers.include?(normalize_header(key))
end

#request_methodObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



351
352
353
# File 'lib/pakyow/connection.rb', line 351

def request_method
  @request.method
end

#request_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



356
357
358
# File 'lib/pakyow/connection.rb', line 356

def request_path
  @request.path
end

#schemeObject



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/pakyow/connection.rb', line 124

def scheme
  if request_header("https").to_s == "on" || request_header("x-forwarded-ssl").to_s == "on"
    "https"
  elsif value = request_header("x-forwarded-scheme")
    value[0]
  elsif value = request_header("x-forwarded-proto")
    value[0]
  else
    @request.scheme
  end
end

#secure?Boolean

Returns:

  • (Boolean)


228
229
230
# File 'lib/pakyow/connection.rb', line 228

def secure?
  scheme == "https"
end

#set_header(key, value) ⇒ Object



84
85
86
# File 'lib/pakyow/connection.rb', line 84

def set_header(key, value)
  @headers[normalize_header(key)] = normalize_header_value(value)
end

#set_headers(headers) ⇒ Object



88
89
90
91
92
# File 'lib/pakyow/connection.rb', line 88

def set_headers(headers)
  headers.each do |key, value|
    set_header(normalize_header(key), value)
  end
end

#sleep(seconds) ⇒ Object



308
309
310
# File 'lib/pakyow/connection.rb', line 308

def sleep(seconds)
  Async::Task.current.sleep(seconds)
end

#stream(length = nil) ⇒ Object



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/pakyow/connection.rb', line 286

def stream(length = nil)
  unless streaming?
    @body = Async::HTTP::Body::Writable.new(length)
  end

  @streams << Async::Task.current.async { |task|
    Thread.current[:pakyow_logger] = @logger

    begin
      yield self
    rescue => error
      @logger.error(error: error)
    end

    @streams.delete(task)
  }
end

#streaming?Boolean

Returns:

  • (Boolean)


304
305
306
# File 'lib/pakyow/connection.rb', line 304

def streaming?
  @streams.any?
end

#subdomainObject



156
157
158
159
160
161
162
# File 'lib/pakyow/connection.rb', line 156

def subdomain
  unless instance_variable_defined?(:@subdomain)
    parse_subdomain
  end

  @subdomain
end

#typeObject Also known as: media_type



210
211
212
213
214
215
216
# File 'lib/pakyow/connection.rb', line 210

def type
  unless instance_variable_defined?(:@type)
    parse_content_type
  end

  @type
end

#type_paramsObject Also known as: media_type_params



219
220
221
222
223
224
225
# File 'lib/pakyow/connection.rb', line 219

def type_params
  unless instance_variable_defined?(:@parsed_type_params)
    @parsed_type_params = build_type_params
  end

  @parsed_type_params
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



361
362
363
364
365
# File 'lib/pakyow/connection.rb', line 361

def update_request_cookie(key, value)
  if @request_cookies.key?(key)
    @request_cookies[key] = value
  end
end

#write(content) ⇒ Object Also known as: <<



277
278
279
# File 'lib/pakyow/connection.rb', line 277

def write(content)
  @body.write(content)
end