版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010643777/article/details/81040639
quic中传输http协议,采取了信令与媒体分离的策略,就是http的header与body分别采用不同的stream进行传输。
在客户端有两个特殊的QuicStreamId。kCryptoStreamId用于握手,kHeadersStreamId用于http头的传输。
// Reserved ID for the crypto stream.
const QuicStreamId kCryptoStreamId = 1;
// Reserved ID for the headers stream.
const QuicStreamId kHeadersStreamId = 3;
HeadersStream在代码中的初始化:
void QuicSpdySession::Initialize() {
QuicSession::Initialize();
headers_stream_ = QuicMakeUnique<QuicHeadersStream>((this));
DCHECK_EQ(kHeadersStreamId, headers_stream_->id());
static_streams()[kHeadersStreamId] = headers_stream_.get();
}
客户端在发送header数据时,会携带body使用的StreamId。
void QuicSpdyClientBase::SendRequest(const spdy::SpdyHeaderBlock& headers,
QuicStringPiece body,
bool fin) {
stream->SendRequest(headers.Clone(), body, fin);
}
size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
QuicStringPiece body,
bool fin) {
//send header
header_bytes_written_ =
WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
bytes_sent += header_bytes_written_;
if (!body.empty()) {
//send body
WriteOrBufferData(body, fin, nullptr);
}
return bytes_sent;
}
size_t QuicSpdyStream::WriteHeaders(
SpdyHeaderBlock header_block,
bool fin,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
size_t bytes_written = spdy_session_->WriteHeaders(
id(), std::move(header_block), fin, priority(), std::move(ack_listener));
//这里的id()是body的StreamId
return bytes_written;
}
size_t QuicSpdySession::WriteHeaders(
QuicStreamId id,
SpdyHeaderBlock headers,
bool fin,
SpdyPriority priority,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
return WriteHeadersImpl(
id, std::move(headers), fin, Spdy3PriorityToHttp2Weight(priority),
/*parent_stream_id=*/0, /*exclusive=*/false, std::move(ack_listener));
}
size_t QuicSpdySession::WriteHeadersImpl(
QuicStreamId id,
SpdyHeaderBlock headers,
bool fin,
int weight,
QuicStreamId parent_stream_id,
bool exclusive,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
SpdyHeadersIR headers_frame(id, std::move(headers));
headers_frame.set_fin(fin);
if (perspective() == Perspective::IS_CLIENT) {
headers_frame.set_has_priority(true);
headers_frame.set_weight(weight);
headers_frame.set_parent_stream_id(parent_stream_id);
headers_frame.set_exclusive(exclusive);
}
SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
headers_stream_->WriteOrBufferData(
QuicStringPiece(frame.data(), frame.size()), false,
std::move(ack_listener));
return frame.size();
}
而在服务侧,因为在QuicSpdySession::Initialize创建了kHeadersStreamId的stream,因此数据流到达之后,先去处理http的header。
void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id,
bool fin,
size_t frame_len,
const QuicHeaderList& header_list) {
//创建处理数据的流。
QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
}