lib/http/2/framer.rb in http-2-1.0.1 vs lib/http/2/framer.rb in http-2-1.0.2

- old
+ new

@@ -2,14 +2,13 @@ module HTTP2 # Performs encoding, decoding, and validation of binary HTTP/2 frames. # class Framer - using StringExtensions - include Error include PackingExtensions + include BufferUtils # Default value of max frame size (16384 bytes) DEFAULT_MAX_FRAME_SIZE = 2 << 13 # maximum frame size @@ -163,11 +162,11 @@ frame[:length] = (len_hi << FRAME_LENGTH_HISHIFT) | len_lo frame[:type], = FRAME_TYPES.find { |_t, pos| type == pos } if frame[:type] frame[:flags] = FRAME_FLAGS[frame[:type]].each_with_object([]) do |(name, pos), acc| - acc << name if (flags & (1 << pos)) > 0 + acc << name if flags.anybits?((1 << pos)) end end frame[:stream] = stream & RBIT frame @@ -342,12 +341,12 @@ frame = read_common_header(buf) return if buf.size < 9 + frame[:length] raise ProtocolError, "payload too large" if frame[:length] > @local_max_frame_size - buf.read(9) - payload = buf.read(frame[:length]) + read_str(buf, 9) + payload = read_str(buf, frame[:length]) # Implementations MUST discard frames # that have unknown or unsupported types. # - http://tools.ietf.org/html/draft-ietf-httpbis-http2-16#section-5.5 return frame if frame[:type].nil? @@ -355,11 +354,11 @@ # Process padding padlen = 0 if FRAME_TYPES_WITH_PADDING.include?(frame[:type]) padded = frame[:flags].include?(:padded) if padded - padlen = payload.read(1).unpack1(UINT8) + padlen = read_str(payload, 1).unpack1(UINT8) frame[:padding] = padlen + 1 raise ProtocolError, "padding too long" if padlen > payload.bytesize payload = payload.byteslice(0, payload.bytesize - padlen) if padlen > 0 frame[:length] -= frame[:padding] @@ -367,85 +366,85 @@ end end case frame[:type] when :data, :ping, :continuation - frame[:payload] = payload.read(frame[:length]) + frame[:payload] = read_str(payload, frame[:length]) when :headers if frame[:flags].include? :priority - e_sd = payload.read_uint32 + e_sd = read_uint32(payload) frame[:dependency] = e_sd & RBIT - frame[:exclusive] = (e_sd & EBIT) != 0 + frame[:exclusive] = e_sd.anybits?(EBIT) weight = payload.byteslice(0, 1).ord + 1 frame[:weight] = weight payload = payload.byteslice(1..-1) end - frame[:payload] = payload.read(frame[:length]) + frame[:payload] = read_str(payload, frame[:length]) when :priority raise FrameSizeError, "Invalid length for PRIORITY_STREAM (#{frame[:length]} != 5)" if frame[:length] != 5 - e_sd = payload.read_uint32 + e_sd = read_uint32(payload) frame[:dependency] = e_sd & RBIT - frame[:exclusive] = (e_sd & EBIT) != 0 + frame[:exclusive] = e_sd.anybits?(EBIT) weight = payload.byteslice(0, 1).ord + 1 frame[:weight] = weight payload = payload.byteslice(1..-1) when :rst_stream raise FrameSizeError, "Invalid length for RST_STREAM (#{frame[:length]} != 4)" if frame[:length] != 4 - frame[:error] = unpack_error payload.read_uint32 + frame[:error] = unpack_error read_uint32(payload) when :settings # NOTE: frame[:length] might not match the number of frame[:payload] # because unknown extensions are ignored. frame[:payload] = [] raise ProtocolError, "Invalid settings payload length" unless (frame[:length] % 6).zero? raise ProtocolError, "Invalid stream ID (#{frame[:stream]})" if (frame[:stream]).nonzero? (frame[:length] / 6).times do - id = payload.read(2).unpack1(UINT16) - val = payload.read_uint32 + id = read_str(payload, 2).unpack1(UINT16) + val = read_uint32(payload) # Unsupported or unrecognized settings MUST be ignored. # Here we send it along. name, = DEFINED_SETTINGS.find { |_name, v| v == id } frame[:payload] << [name, val] if name end when :push_promise - frame[:promise_stream] = payload.read_uint32 & RBIT - frame[:payload] = payload.read(frame[:length]) + frame[:promise_stream] = read_uint32(payload) & RBIT + frame[:payload] = read_str(payload, frame[:length]) when :goaway - frame[:last_stream] = payload.read_uint32 & RBIT - frame[:error] = unpack_error payload.read_uint32 + frame[:last_stream] = read_uint32(payload) & RBIT + frame[:error] = unpack_error read_uint32(payload) size = frame[:length] - 8 # for last_stream and error - frame[:payload] = payload.read(size) if size > 0 + frame[:payload] = read_str(payload, size) if size > 0 when :window_update if frame[:length] % 4 != 0 raise FrameSizeError, "Invalid length for WINDOW_UPDATE (#{frame[:length]} not multiple of 4)" end - frame[:increment] = payload.read_uint32 & RBIT + frame[:increment] = read_uint32(payload) & RBIT when :altsvc - frame[:max_age], frame[:port] = payload.read(6).unpack(UINT32 + UINT16) + frame[:max_age], frame[:port] = read_str(payload, 6).unpack(UINT32 + UINT16) len = payload.byteslice(0, 1).ord payload = payload.byteslice(1..-1) - frame[:proto] = payload.read(len) if len > 0 + frame[:proto] = read_str(payload, len) if len > 0 len = payload.byteslice(0, 1).ord payload = payload.byteslice(1..-1) - frame[:host] = payload.read(len) if len > 0 + frame[:host] = read_str(payload, len) if len > 0 - frame[:origin] = payload.read(payload.size) unless payload.empty? + frame[:origin] = read_str(payload, payload.size) unless payload.empty? when :origin origins = [] until payload.empty? - len = payload.read(2).unpack1(UINT16) - origins << payload.read(len) + len = read_str(payload, 2).unpack1(UINT16) + origins << read_str(payload, len) end frame[:payload] = origins # else # Unknown frame type is explicitly allowed end