@@ -22,6 +22,103 @@ data class Http2Frame(
22
22
val length get()= payload.size
23
23
val padLength get()= padding.size
24
24
val prioLength get()= priotity.size
25
+
26
+ companion object {
27
+ @JvmStatic
28
+ fun parse (buff : ByteArray ):Pair <Http2Frame ,ByteArray >{
29
+ if (buff.size< 9 )throw Http2Error .MalformedFrame (" frame was ${buff.size} " )
30
+ var start= 0
31
+ val length= ((buff[0 ].toInt() and 0xff ) shl 16 ) or ((buff[1 ].toInt() and 0xff ) shl 8 ) or (buff[2 ].toInt() and 0xff )
32
+ val opcode= buff[3 ].toInt() and 0xff
33
+ val flags= buff[4 ].toInt() and 0xff
34
+ val streamID= ((buff[5 ].toInt() and 0xff ) shl 24 ) or ((buff[6 ].toInt() and 0xff ) shl 16 ) or
35
+ ((buff[7 ].toInt() and 0xff ) shl 8 ) or (buff[8 ].toInt() and 0xff )
36
+
37
+ val padLength=
38
+ if ((flags and 0x8 )!= 0 ){ // padded
39
+ val b= buff[start].toInt() and 0xff
40
+ start+ = 1
41
+ b
42
+ } else { 0 }
43
+
44
+ val frameLength= 9 + length
45
+
46
+ // println("length = $length")
47
+
48
+ val priority=
49
+ if ((flags and 0x20 )!= 0 ){
50
+ val p= buff.copyOfRange(start, start+ 5 )
51
+ start+ = 5
52
+ p
53
+ } else {
54
+ ByteArray (0 )
55
+ }
56
+
57
+ val payload= buff.copyOfRange(9 + start, 9 + length- padLength)
58
+ // if((flags and 0x20)==0)buff.copyOfRange(9+start, 9+start+length-padLength)
59
+ // else buff.copyOfRange(start+5, start+length)
60
+
61
+ val padding= buff.copyOfRange(9 + length- padLength, 9 + length)
62
+
63
+ val remaining= buff.copyOfRange(frameLength, buff.size)
64
+
65
+ val (type,stringType)= when (opcode){
66
+ 0 -> Http2FrameType .Data to " Data"
67
+ 1 -> Http2FrameType .Headers to " Headers"
68
+ 2 -> Http2FrameType .Priority to " Priority"
69
+ 3 -> Http2FrameType .RstStream to " RstStream"
70
+ 4 -> Http2FrameType .Settings to " Settings"
71
+ 5 -> Http2FrameType .PushPromise to " PushPromise"
72
+ 6 -> Http2FrameType .Ping to " Ping"
73
+ 7 -> Http2FrameType .Goaway to " Goaway"
74
+ 8 -> Http2FrameType .WindowUpdate to " WindowUpdate"
75
+ 9 -> Http2FrameType .Continuation to " Continuation"
76
+ else -> Http2FrameType .Unknown to " Unkown"
77
+ }
78
+
79
+ val settings: Http2Settings =
80
+ if (opcode== 0x4 ){
81
+ // var header_table_size:Int?=null
82
+ // var enable_push:Int?=null
83
+ // var max_concurrent_streams:Int?=null
84
+ // var initial_window_size:Int?=null
85
+ // var max_frame_size:Int?=null
86
+ // var max_header_list_size:Int?=null
87
+ // for(i in 0 until payload.size step 6){val it=payload.copyOfRange(i,6) // more efficient?
88
+ // // buff.asList().chunked(6).forEach{
89
+ // val name=((it[0].toInt() and 0xff) shl 8) or (it[1].toInt() and 0xff)
90
+ // val value=((it[2].toInt() and 0xff) shl 24) or ((it[3].toInt() and 0xff) shl 16) or
91
+ // ((it[4].toInt() and 0xff) shl 8) or (it[5].toInt() and 0xff)
92
+ // when(name){
93
+ // 1->header_table_size=value
94
+ // 2->enable_push=value
95
+ // 3->max_concurrent_streams=value
96
+ // 4->initial_window_size=value
97
+ // 5->max_frame_size=value
98
+ // 6->max_header_list_size=value
99
+ // }
100
+ // }
101
+ // Http2Settings(header_table_size, enable_push, max_concurrent_streams, initial_window_size, max_frame_size, max_header_list_size)
102
+ Http2Settings .parse(payload)
103
+ } else {
104
+ Http2Settings (null ,null ,null ,null ,null ,null )
105
+ }
106
+
107
+ return Http2Frame (
108
+ frameLength,
109
+ streamID,
110
+ opcode,
111
+ type,
112
+ stringType,
113
+ flags,
114
+ payload,
115
+ padding,
116
+ priority,
117
+ settings,
118
+ ) to
119
+ remaining
120
+ }
121
+ }
25
122
}
26
123
27
124
data class Http2Settings (
@@ -58,121 +155,33 @@ data class Http2Settings(
58
155
}
59
156
return buff.toByteArray()
60
157
}
61
- }
62
-
63
- fun parseHttp2Frame (buff : ByteArray ):Pair <Http2Frame ,ByteArray >{
64
- if (buff.size< 9 )throw Http2Error .MalformedFrame (" frame was ${buff.size} " )
65
- var start= 9
66
- val length= ((buff[0 ].toInt() and 0xff ) shl 16 ) or ((buff[1 ].toInt() and 0xff ) shl 8 ) or (buff[2 ].toInt() and 0xff )
67
- val opcode= buff[3 ].toInt() and 0xff
68
- val flags= buff[4 ].toInt() and 0xff
69
- val streamID= ((buff[5 ].toInt() and 0xff ) shl 24 ) or ((buff[6 ].toInt() and 0xff ) shl 16 ) or
70
- ((buff[7 ].toInt() and 0xff ) shl 8 ) or (buff[8 ].toInt() and 0xff )
71
-
72
- val padLength=
73
- if ((flags and 0x8 )!= 0 ){ // padded
74
- start+ = 1
75
- buff[9 ].toInt() and 0xff
76
- } else { 0 }
77
158
78
- val frameLength= start+ length+ padLength
79
-
80
- // println("length = $length")
81
-
82
- val priority=
83
- if ((flags and 0x20 )!= 0 ){
84
- buff.copyOfRange(start, start+ 5 )
85
- } else {
86
- ByteArray (0 )
87
- }
88
-
89
- val payload=
90
- if ((flags and 0x20 )== 0 )buff.copyOfRange(start, start+ length)
91
- else buff.copyOfRange(start+ 5 , start+ length)
92
-
93
- val padding= buff.copyOfRange(start+ length, start+ length+ padLength)
94
-
95
- val remaining= buff.copyOfRange(frameLength, buff.size)
96
-
97
- val (type,stringType)= when (opcode){
98
- 0 -> Http2FrameType .Data to " Data"
99
- 1 -> Http2FrameType .Headers to " Headers"
100
- 2 -> Http2FrameType .Priority to " Priority"
101
- 3 -> Http2FrameType .RstStream to " RstStream"
102
- 4 -> Http2FrameType .Settings to " Settings"
103
- 5 -> Http2FrameType .PushPromise to " PushPromise"
104
- 6 -> Http2FrameType .Ping to " Ping"
105
- 7 -> Http2FrameType .Goaway to " Goaway"
106
- 8 -> Http2FrameType .WindowUpdate to " WindowUpdate"
107
- 9 -> Http2FrameType .Continuation to " Continuation"
108
- else -> Http2FrameType .Unknown to " Unkown"
109
- }
110
-
111
- val settings: Http2Settings =
112
- if (opcode== 0x4 ){
113
- // var header_table_size:Int?=null
114
- // var enable_push:Int?=null
115
- // var max_concurrent_streams:Int?=null
116
- // var initial_window_size:Int?=null
117
- // var max_frame_size:Int?=null
118
- // var max_header_list_size:Int?=null
119
- // for(i in 0 until payload.size step 6){val it=payload.copyOfRange(i,6) // more efficient?
120
- // // buff.asList().chunked(6).forEach{
121
- // val name=((it[0].toInt() and 0xff) shl 8) or (it[1].toInt() and 0xff)
122
- // val value=((it[2].toInt() and 0xff) shl 24) or ((it[3].toInt() and 0xff) shl 16) or
123
- // ((it[4].toInt() and 0xff) shl 8) or (it[5].toInt() and 0xff)
124
- // when(name){
125
- // 1->header_table_size=value
126
- // 2->enable_push=value
127
- // 3->max_concurrent_streams=value
128
- // 4->initial_window_size=value
129
- // 5->max_frame_size=value
130
- // 6->max_header_list_size=value
131
- // }
132
- // }
133
- // Http2Settings(header_table_size, enable_push, max_concurrent_streams, initial_window_size, max_frame_size, max_header_list_size)
134
- parseHttp2Settings(payload)
135
- } else {
136
- Http2Settings (null ,null ,null ,null ,null ,null )
137
- }
138
-
139
- return Http2Frame (
140
- frameLength,
141
- streamID,
142
- opcode,
143
- type,
144
- stringType,
145
- flags,
146
- payload,
147
- padding,
148
- priority,
149
- settings,
150
- ) to
151
- remaining
152
- }
153
-
154
- fun parseHttp2Settings (buff : ByteArray ):Http2Settings {
155
- var header_table_size: Int? = null
156
- var enable_push: Int? = null
157
- var max_concurrent_streams: Int? = null
158
- var initial_window_size: Int? = null
159
- var max_frame_size: Int? = null
160
- var max_header_list_size: Int? = null
161
- for (i in 0 until buff.size step 6 ){ val it= buff.copyOfRange(i,i+ 6 ) // more efficient?
162
- // buff.asList().chunked(6).forEach{
163
- val name= ((it[0 ].toInt() and 0xff ) shl 8 ) or (it[1 ].toInt() and 0xff )
164
- val value= ((it[2 ].toInt() and 0xff ) shl 24 ) or ((it[3 ].toInt() and 0xff ) shl 16 ) or
165
- ((it[4 ].toInt() and 0xff ) shl 8 ) or (it[5 ].toInt() and 0xff )
166
- when (name){
167
- 1 -> header_table_size= value
168
- 2 -> enable_push= value
169
- 3 -> max_concurrent_streams= value
170
- 4 -> initial_window_size= value
171
- 5 -> max_frame_size= value
172
- 6 -> max_header_list_size= value
159
+ companion object {
160
+ @JvmStatic
161
+ fun parse (buff : ByteArray ):Http2Settings {
162
+ var header_table_size: Int? = null
163
+ var enable_push: Int? = null
164
+ var max_concurrent_streams: Int? = null
165
+ var initial_window_size: Int? = null
166
+ var max_frame_size: Int? = null
167
+ var max_header_list_size: Int? = null
168
+ for (i in 0 until buff.size step 6 ){ val it= buff.copyOfRange(i,i+ 6 ) // more efficient?
169
+ // buff.asList().chunked(6).forEach{
170
+ val name= ((it[0 ].toInt() and 0xff ) shl 8 ) or (it[1 ].toInt() and 0xff )
171
+ val value= ((it[2 ].toInt() and 0xff ) shl 24 ) or ((it[3 ].toInt() and 0xff ) shl 16 ) or
172
+ ((it[4 ].toInt() and 0xff ) shl 8 ) or (it[5 ].toInt() and 0xff )
173
+ when (name){
174
+ 1 -> header_table_size= value
175
+ 2 -> enable_push= value
176
+ 3 -> max_concurrent_streams= value
177
+ 4 -> initial_window_size= value
178
+ 5 -> max_frame_size= value
179
+ 6 -> max_header_list_size= value
180
+ }
181
+ }
182
+ return Http2Settings (header_table_size, enable_push, max_concurrent_streams, initial_window_size, max_frame_size, max_header_list_size)
173
183
}
174
184
}
175
- return Http2Settings (header_table_size, enable_push, max_concurrent_streams, initial_window_size, max_frame_size, max_header_list_size)
176
185
}
177
186
178
187
// 11.2 #autoid-88
0 commit comments