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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
// use std::{fmt, mem};
// use crate::{Http2Error, WebError, WebResult, Buf, BufMut, Serialize};
// use super::{
// frame::FrameHeader, read_u64, ErrorCode, Flag, Kind, ParserSettings, SizeIncrement,
// StreamIdentifier, Settings,
// };
// const PRIORITY_BYTES: u32 = 5;
// const PADDING_BYTES: u32 = 1;
// #[derive(Clone, Debug, PartialEq, Eq, Hash)]
// pub enum Payload<T>
// where T: Buf {
// Data {
// data: T,
// },
// Headers {
// priority: Option<Priority>,
// block: T,
// },
// Priority(Priority),
// Reset(ErrorCode),
// Settings(Settings),
// PushPromise {
// promised: StreamIdentifier,
// block: T,
// },
// Ping(u64),
// GoAway {
// last: StreamIdentifier,
// error: ErrorCode,
// data: T,
// },
// WindowUpdate(SizeIncrement),
// Continuation(T),
// Unregistered(T),
// }
// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
// pub struct Priority {
// exclusive: bool,
// dependency: StreamIdentifier,
// weight: u8,
// }
// impl Priority {
// #[inline]
// pub fn parse<T: Buf+MarkBuf>(present: bool, mut buffer: T) -> WebResult<(T, Option<Priority>)> {
// if present {
// let first = buffer.peek().unwrap();
// let id = StreamIdentifier::parse(&mut buffer);
// let weight = buffer.get_u8();
// Ok((
// buffer.mark_clone_slice(),
// Some(Priority {
// // Most significant bit.
// exclusive: first & 0x7F != first,
// dependency: id,
// weight,
// }),
// ))
// } else {
// Ok((buffer, None))
// }
// }
// }
// impl Serialize for Priority {
// fn serialize<B: Buf+BufMut>(&self, buffer: &mut B) -> WebResult<usize> {
// let mut dependency = self.dependency;
// if self.exclusive {
// dependency.0 |= 1 << 31
// }
// dependency.serialize(buffer)?;
// buffer.put_u8(self.weight);
// Ok(PRIORITY_BYTES as usize)
// }
// }
// #[repr(u16)]
// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
// pub enum SettingIdentifier {
// //允许发送者以八位字节的形式通知远程端点用于解码头块的头压缩表的最大尺寸。编码器可以通过使用特定于头部块内头部压缩格式的信令来选择等于或小于此值的任何大小(请参见[压缩])。初始值是4,096个八位字节。
// HeaderTableSize = 0x1,
// //此设置可用于禁用服务器推送(第8.2节)。如果一个端点接收到这个参数设置为0的值,它不应该发送一个PUSH_PROMISE帧。一个端点既将这个参数设置为0,并且确认它也必须将PUSH_PROMISE帧的接收视为连接错误(见5.4节)。 1)类型PROTOCOL_ERROR。初始值为1,表示允许服务器推送。除0或1以外的任何值必须视为PROTOCOL_ERROR类型的连接错误
// EnablePush = 0x2,
// //表示发件人允许的最大并发流数。这个限制是有方向性的:它适用于发送者允许接收者创建的数据流。最初,这个值没有限制。建议此值不小于100,以免不必要地限制并行性。值为0的SETTINGS_MAX_CONCURRENT_STREAMS不应被视为特殊的端点。零值确实会阻止创建新的流;然而,这也可能发生在活动流所耗尽的任何限制上。服务器应该只在短时间内设置一个零值;如果服务器不希望接受请求,关闭连接更合适。
// MaxConcurrentStreams = 0x3,
// //指示发送者的流级别流控制的初始窗口大小(以八位字节为单位)。初始值是2 ^ 16-1(65,535)个八位组。该设置会影响所有流的窗口大小(请参阅第6.9.2节)。高于最大流量控制窗口大小2 ^ 31-1的值必须视为FLOW_CONTROL_ERROR类型的连接错误;然而,这也可能发生在活动流所耗尽的任何限制上。服务器应该只在短时间内设置一个零值;如果服务器不希望接受请求,关闭连接更合适。
// InitialWindowSize = 0x4,
// //指示发送者愿意接收的最大帧有效载荷的大小,以八位字节为单位。初始值是2 ^ 14(16,384)个八位字节。端点通告的值必须在该初始值和最大允许帧大小之间(2 ^ 24-1或16,777,215个八位字节),包括在内。此范围之外的值务必视为PROTOCOL_ERROR类型的连接错误
// MaxFrameSize = 0x5,
// //此通报设置以八位字节的形式通知对等方发送方准备接受的标题列表的最大大小。该值基于头字段的未压缩大小,包括名称和八位字节的值的长度,以及每个头字段的开销32个字节。对于任何给定的请求,可能会强制实施一个比所宣传的更低的限制。
// MaxHeaderListSize = 0x6,
// }
// impl<T: Buf+MarkBuf> Payload<T> {
// #[inline]
// pub fn kind(&self) -> Kind {
// use self::Payload::*;
// match *self {
// Data { .. } => Kind::Data,
// Headers { .. } => Kind::Headers,
// Priority(..) => Kind::Priority,
// Reset(..) => Kind::Reset,
// Settings(..) => Kind::Settings,
// PushPromise { .. } => Kind::PushPromise,
// Ping(..) => Kind::Ping,
// GoAway { .. } => Kind::GoAway,
// WindowUpdate(_) => Kind::WindowUpdate,
// Continuation(_) => Kind::Continuation,
// Unregistered(_) => Kind::Unregistered,
// }
// }
// #[inline]
// pub fn parse(header: FrameHeader, buffer: &mut T) -> WebResult<Payload<T>> {
// let settings = ParserSettings {
// padding: header.flag.contains(Flag::padded()),
// priority: header.flag.contains(Flag::priority()),
// };
// if buffer.remaining() < header.length as usize {
// return Err(Http2Error::into(Http2Error::Short));
// }
// let min_payload_length = if settings.priority && settings.padding {
// PRIORITY_BYTES + PADDING_BYTES
// } else if settings.priority {
// PRIORITY_BYTES
// } else if settings.padding {
// PADDING_BYTES
// } else {
// 0
// };
// if header.length < min_payload_length {
// return Err(Http2Error::into(Http2Error::PayloadLengthTooShort));
// }
// let buf = buffer.mark_clone_slice_range(..header.length as isize);
// buffer.advance(header.length as usize);
// match header.kind {
// Kind::Data => Payload::parse_data(header, buf, settings),
// Kind::Headers => Payload::parse_headers(header, buf, settings),
// Kind::Priority => {
// let (_, priority) = Priority::parse(true, buf)?;
// Ok(Payload::Priority(priority.unwrap()))
// }
// Kind::Reset => Payload::parse_reset(header, buf),
// Kind::Settings => Payload::parse_settings(header, buf),
// Kind::Ping => Payload::parse_ping(header, buf),
// Kind::GoAway => Payload::parse_goaway(header, buf),
// Kind::WindowUpdate => Payload::parse_window_update(header, buf),
// Kind::PushPromise => Payload::parse_push_promise(header, buf, settings),
// Kind::Continuation => Ok(Payload::Continuation(buf)),
// Kind::Unregistered => Ok(Payload::Unregistered(buf)),
// }
// }
// #[inline]
// /// How many bytes this Payload would be encoded.
// pub fn encoded_len(&self) -> usize {
// use self::Payload::*;
// match *self {
// Data { ref data } => data.remaining(),
// Headers {
// ref priority,
// ref block,
// } => {
// let priority_len = if priority.is_some() { 5 } else { 0 };
// priority_len + block.remaining()
// }
// Reset(_) => 4,
// Settings(ref settings) => settings.payload_len(),
// Ping(_) => 8,
// GoAway { ref data, .. } => 4 + 4 + data.remaining(),
// WindowUpdate(_) => 4,
// PushPromise { ref block, .. } => 4 + block.remaining(),
// Priority(_) => 5,
// Continuation(ref block) => block.remaining(),
// Unregistered(ref block) => block.remaining(),
// }
// }
// #[inline]
// pub fn padded(&self) -> Option<u32> {
// None
// }
// #[inline]
// pub fn priority(&self) -> Option<&Priority> {
// match *self {
// Payload::Priority(ref priority) => Some(priority),
// Payload::Headers { ref priority, .. } => priority.as_ref(),
// _ => None,
// }
// }
// #[inline]
// fn parse_data(
// header: FrameHeader,
// mut buf: T,
// settings: ParserSettings,
// ) -> WebResult<Payload<T>> {
// trim_padding(settings, header, &mut buf)?;
// Ok(Payload::Data {
// data: buf,
// })
// }
// #[inline]
// fn parse_headers(
// header: FrameHeader,
// mut buf: T,
// settings: ParserSettings,
// ) -> WebResult<Payload<T>> {
// trim_padding(settings, header, &mut buf)?;
// let (buf, priority) = Priority::parse(settings.priority, buf)?;
// Ok(Payload::Headers {
// priority: priority,
// block: buf,
// })
// }
// #[inline]
// fn parse_reset(header: FrameHeader, mut buf: T) -> WebResult<Payload<T>> {
// if header.length < 4 {
// return Err(Http2Error::into(Http2Error::PayloadLengthTooShort));
// }
// Ok(Payload::Reset(ErrorCode::parse(&mut buf)))
// }
// #[inline]
// fn parse_settings(header: FrameHeader, mut buf: T) -> WebResult<Payload<T>> {
// let s = Settings::decode(header, &mut buf)?;
// Ok(Payload::Settings(s))
// }
// #[inline]
// fn parse_ping(header: FrameHeader, mut buf: T) -> WebResult<Payload<T>> {
// if header.length != 8 {
// return Err(Http2Error::into(Http2Error::InvalidPayloadLength));
// }
// let data = read_u64(&mut buf);
// Ok(Payload::Ping(data))
// }
// #[inline]
// fn parse_goaway(header: FrameHeader, mut buf: T) -> WebResult<Payload<T>> {
// if header.length < 8 {
// return Err(Http2Error::into(Http2Error::PayloadLengthTooShort));
// }
// let last = StreamIdentifier::parse(&mut buf);
// let error = ErrorCode::parse(&mut buf);
// Ok(Payload::GoAway {
// last,
// error,
// data: buf.mark_clone_slice(),
// })
// }
// #[inline]
// fn parse_window_update(header: FrameHeader, mut buf: T) -> WebResult<Payload<T>> {
// if header.length != 4 {
// return Err(Http2Error::into(Http2Error::InvalidPayloadLength));
// }
// Ok(Payload::WindowUpdate(SizeIncrement::parse(&mut buf)))
// }
// #[inline]
// fn parse_push_promise(
// header: FrameHeader,
// mut buf: T,
// settings: ParserSettings,
// ) -> WebResult<Payload<T>> {
// trim_padding(settings, header, &mut buf)?;
// if buf.remaining() < 4 {
// return Err(Http2Error::into(Http2Error::PayloadLengthTooShort));
// }
// let promised = StreamIdentifier::parse(&mut buf);
// let block = buf.mark_clone_slice();
// Ok(Payload::PushPromise {
// promised,
// block,
// })
// }
// }
// impl<T: Buf+MarkBuf> Serialize for Payload<T> {
// fn serialize<B: Buf+BufMut>(&self, buffer: &mut B) -> WebResult<usize> {
// let size = match *self {
// Payload::Data { ref data } => encode_memory(data, buffer),
// Payload::Headers {
// ref priority,
// ref block,
// } => {
// let priority_wrote = if let Some(p) = priority {
// p.serialize(buffer)?
// } else {
// 0
// };
// let block_wrote = encode_memory(block, buffer);
// priority_wrote + block_wrote
// }
// Payload::Reset(ref err) => err.serialize(buffer)?,
// Payload::Settings(ref settings) => {
// settings.encode(buffer)
// },
// Payload::Ping(data) => {
// buffer.put_u64(data);
// 8
// },
// Payload::GoAway {
// ref data,
// ref last,
// ref error,
// } => {
// let last_wrote = last.serialize(buffer)?;
// let error_wrote = error.serialize(buffer)?;
// encode_memory(data, buffer) + last_wrote + error_wrote
// }
// Payload::WindowUpdate(ref increment) => increment.encode(buffer),
// Payload::PushPromise {
// ref promised,
// ref block,
// } => {
// promised.serialize(buffer)?;
// encode_memory(block, buffer) + 4
// }
// Payload::Priority(ref priority) => priority.serialize(buffer)?,
// Payload::Continuation(ref block) => encode_memory(block, buffer),
// Payload::Unregistered(ref block) => encode_memory(block, buffer),
// };
// Ok(size)
// }
// }
// #[inline]
// fn encode_memory<T: Buf, B: Buf + BufMut>(src: &T, mut dst: &mut B) -> usize {
// dst.put_slice(src.chunk())
// }
// #[inline]
// fn trim_padding<T: Buf>(settings: ParserSettings, header: FrameHeader, buf: &mut T) -> WebResult<()> {
// if settings.padding && buf.has_remaining() {
// let pad_length = buf.peek().unwrap();
// if pad_length as u32 > header.length {
// return Err(Http2Error::into(Http2Error::TooMuchPadding(pad_length)))
// } else {
// buf.advance(1);
// buf.mark_len(header.length as usize - pad_length as usize - 1);
// }
// }
// Ok(())
// }