File: padded.rb

package info (click to toggle)
ruby-protocol-http2 0.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 472 kB
  • sloc: ruby: 3,627; makefile: 4
file content (76 lines) | stat: -rw-r--r-- 2,148 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2019-2025, by Samuel Williams.

require_relative "frame"

module Protocol
	module HTTP2
		# Certain frames can have padding:
		# https://http2.github.io/http2-spec/#padding
		#
		# +---------------+
		# |Pad Length? (8)|
		# +---------------+-----------------------------------------------+
		# |                            Data (*)                         ...
		# +---------------------------------------------------------------+
		# |                           Padding (*)                       ...
		# +---------------------------------------------------------------+
		#
		# Provides padding functionality for HTTP/2 frames.
		# Padding can be used to obscure the actual size of frame payloads.
		module Padded
			# Check if the frame has padding enabled.
			# @returns [Boolean] True if the PADDED flag is set.
			def padded?
				flag_set?(PADDED)
			end
			
			# Pack data with optional padding into the frame.
			# @parameter data [String] The data to pack.
			# @parameter padding_size [Integer | Nil] Number of padding bytes to add.
			# @parameter maximum_size [Integer | Nil] Maximum frame size limit.
			def pack(data, padding_size: nil, maximum_size: nil)
				if padding_size
					set_flags(PADDED)
					
					buffer = String.new.b
					
					buffer << padding_size
					buffer << data
					
					if padding_size
						buffer << ("\0" * padding_size)
					end
					
					super buffer
				else
					clear_flags(PADDED)
					
					super data
				end
			end
			
			# Unpack frame data, removing padding if present.
			# @returns [String] The unpacked data without padding.
			# @raises [ProtocolError] If padding length is invalid.
			def unpack
				if padded?
					padding_size = @payload[0].ord
					
					# 1 byte for the padding octet, and padding_size bytes for the padding itself:
					data_size = @payload.bytesize - (1 + padding_size)
					
					if data_size < 0
						raise ProtocolError, "Invalid padding length: #{padding_size}"
					end
					
					return @payload.byteslice(1, data_size)
				else
					return @payload
				end
			end
		end
	end
end