lib/http/2/stream.rb in http-2-0.8.2 vs lib/http/2/stream.rb in http-2-0.8.3

- old
+ new

@@ -52,11 +52,11 @@ attr_reader :dependency # Size of current stream flow control window. attr_reader :local_window attr_reader :remote_window - alias_method :window, :local_window + alias window local_window # Reason why connection was closed. attr_reader :closed # Initializes new stream. @@ -115,11 +115,11 @@ emit(frame[:type], frame) end complete_transition(frame) end - alias_method :<<, :receive + alias << receive # Processes outgoing HTTP 2.0 frames. Data frames may be automatically # split and buffered based on maximum frame size and current stream flow # control window size. # @@ -180,20 +180,34 @@ # @param end_stream [Boolean] indicates last response DATA frame def data(payload, end_stream: true) # Split data according to each frame is smaller enough # TODO: consider padding? max_size = @connection.remote_settings[:settings_max_frame_size] - while payload.bytesize > max_size - chunk = payload.slice!(0, max_size) - send(type: :data, flags: [], payload: chunk) + + if payload.bytesize > max_size + payload = chunk_data(payload, max_size) do |chunk| + send(type: :data, flags: [], payload: chunk) + end end flags = [] flags << :end_stream if end_stream send(type: :data, flags: flags, payload: payload) end + # Chunk data into max_size, yield each chunk, then return final chunk + # + def chunk_data(payload, max_size) + total = payload.bytesize + cursor = 0 + while (total - cursor) > max_size + yield payload.byteslice(cursor, max_size) + cursor += max_size + end + payload.byteslice(cursor, total - cursor) + end + # Sends a RST_STREAM frame which closes current stream - this does not # close the underlying connection. # # @param error [:Symbol] optional reason why stream was closed def close(error = :stream_closed) @@ -318,18 +332,18 @@ # A PRIORITY or WINDOW_UPDATE frame MAY be received in this state. # Receiving any type of frame other than RST_STREAM, PRIORITY or # WINDOW_UPDATE on a stream in this state MUST be treated as a # connection error (Section 5.4.1) of type PROTOCOL_ERROR. when :reserved_local - if sending - @state = case frame[:type] + @state = if sending + case frame[:type] when :headers then event(:half_closed_remote) when :rst_stream then event(:local_rst) else stream_error end else - @state = case frame[:type] + case frame[:type] when :rst_stream then event(:remote_rst) when :priority, :window_update then @state else stream_error end end @@ -347,17 +361,17 @@ # this state. # Receiving any type of frame other than HEADERS, RST_STREAM or # PRIORITY on a stream in this state MUST be treated as a connection # error (Section 5.4.1) of type PROTOCOL_ERROR. when :reserved_remote - if sending - @state = case frame[:type] + @state = if sending + case frame[:type] when :rst_stream then event(:local_rst) when :priority, :window_update then @state else stream_error end else - @state = case frame[:type] + case frame[:type] when :headers then event(:half_closed_local) when :rst_stream then event(:remote_rst) else stream_error end end