Class: H2::Server::Stream

Inherits:
Object
  • Object
show all
Defined in:
lib/h2/server/stream.rb,
lib/h2/server/stream/request.rb,
lib/h2/server/stream/response.rb,
lib/h2/server/stream/event_source.rb,
lib/h2/server/stream/push_promise.rb

Defined Under Namespace

Classes: EventSource, PushPromise, Request, Response

Constant Summary collapse

STREAM_EVENTS =

each stream event method is wrapped in a block to call a local instance method of the same name

[
  :active,
  :close,
  :half_close
]
STREAM_DATA_EVENTS =

the above take only the event, the following receive both the event and the data

[
  :headers,
  :data
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection:, stream:) ⇒ Stream

Returns a new instance of Stream.



29
30
31
32
33
34
35
36
37
38
# File 'lib/h2/server/stream.rb', line 29

def initialize connection:, stream:
  @closed        = false
  @completed     = false
  @connection    = connection
  @push_promises = Set.new
  @responded     = false
  @stream        = stream

  bind_events
end

Instance Attribute Details

#completeObject (readonly)

Returns the value of attribute complete.



22
23
24
# File 'lib/h2/server/stream.rb', line 22

def complete
  @complete
end

#connectionObject (readonly)

Returns the value of attribute connection.



22
23
24
# File 'lib/h2/server/stream.rb', line 22

def connection
  @connection
end

#push_promisesObject (readonly)

Returns the value of attribute push_promises.



22
23
24
# File 'lib/h2/server/stream.rb', line 22

def push_promises
  @push_promises
end

#requestObject (readonly)

Returns the value of attribute request.



22
23
24
# File 'lib/h2/server/stream.rb', line 22

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



22
23
24
# File 'lib/h2/server/stream.rb', line 22

def response
  @response
end

#streamObject (readonly)

Returns the value of attribute stream.



22
23
24
# File 'lib/h2/server/stream.rb', line 22

def stream
  @stream
end

Instance Method Details

#goaway_on_completeObject

trigger a GOAWAY frame when this stream is responded to and any/all push promises are complete



110
111
112
# File 'lib/h2/server/stream.rb', line 110

def goaway_on_complete
  on_complete { connection.goaway }
end

#log(level, msg) ⇒ Object

logging helper



116
117
118
# File 'lib/h2/server/stream.rb', line 116

def log level, msg
  Logger.__send__ level, "[stream #{@stream.id}] #{msg}"
end

#make_promise(p) ⇒ Object

begin the new push promise stream from this @stream by sending the initial headers frame

See Also:

  • H2::Server::Stream.+PushPromise+PushPromise#make_on!+
  • H2::Server::Stream.+HTTP2+HTTP2::Stream+HTTP2::Stream#promise+


81
82
83
84
85
# File 'lib/h2/server/stream.rb', line 81

def make_promise p
  p.make_on self
  push_promises << p
  p
end

#on_complete(&block) ⇒ Object

set or call @complete callback



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/h2/server/stream.rb', line 89

def on_complete &block
  return true if @completed
  if block
    @complete = block
  elsif @completed = (@responded and push_promises_complete?)
    @complete[] if Proc === complete
    true
  else
    false
  end
end

#push_promise(*args) ⇒ Object

create a push promise, send the headers, then queue an asynchronous task on the reactor to deliver the data



60
61
62
63
64
# File 'lib/h2/server/stream.rb', line 60

def push_promise *args
  pp = push_promise_for(*args)
  make_promise pp
  @connection.server.async.handle_push_promise pp
end

#push_promise_for(path:, headers: {}, body: nil) ⇒ Object

create a push promise



68
69
70
71
72
73
# File 'lib/h2/server/stream.rb', line 68

def push_promise_for path:, headers: {}, body: nil
  headers.merge! AUTHORITY_KEY => @request.authority,
                 SCHEME_KEY    => @request.scheme

  PushPromise.new path: path, headers: headers, body: body
end

#push_promises_complete?Boolean

check for push promises completion

Returns:

  • (Boolean)


103
104
105
# File 'lib/h2/server/stream.rb', line 103

def push_promises_complete?
  @push_promises.empty? or @push_promises.all? {|p| p.kept? or p.canceled?}
end

#respond(status:, headers: {}, body: '') ⇒ Object

write status, headers, and body to @stream



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/h2/server/stream.rb', line 42

def respond status:, headers: {}, body: ''
  response = Response.new stream: self,
                          status: status,
                          headers: headers,
                          body: body

  if @closed
    log :warn, 'stream closed before response sent'
  else
    log :info, response
    response.respond_on(stream)
    @responded = true
  end
end

#to_eventsource(headers: {}) ⇒ H2::Server::Stream::EventSource

make this stream into an SSE event source

raises StreamError if the request’s content-type is not valid



126
127
128
# File 'lib/h2/server/stream.rb', line 126

def to_eventsource headers: {}
  EventSource.new stream: self, headers: headers
end