File: Http3HeaderFramer.cc

package info (click to toggle)
trafficserver 9.2.5%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 53,008 kB
  • sloc: cpp: 345,484; ansic: 31,134; python: 24,200; sh: 7,271; makefile: 3,045; perl: 2,261; java: 277; pascal: 119; sql: 94; xml: 2
file content (116 lines) | stat: -rw-r--r-- 3,510 bytes parent folder | download | duplicates (2)
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
/** @file
 *
 *  A brief file description
 *
 *  @section license License
 *
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "Http3HeaderFramer.h"

#include "I_VIO.h"

#include "HTTP.h"
#include "HTTP2.h"

#include "Http3Frame.h"
#include "Http3Transaction.h"

Http3HeaderFramer::Http3HeaderFramer(Http3Transaction *transaction, VIO *source, QPACK *qpack, uint64_t stream_id)
  : _transaction(transaction), _source_vio(source), _qpack(qpack), _stream_id(stream_id)
{
  http_parser_init(&this->_http_parser);
}

Http3FrameUPtr
Http3HeaderFramer::generate_frame()
{
  if (!this->_source_vio->get_reader()) {
    return Http3FrameFactory::create_null_frame();
  }

  ink_assert(!this->_transaction->is_response_header_sent());

  if (!this->_header_block) {
    // this->_header_block will be filled if it is ready
    this->_generate_header_block();
  }

  if (this->_header_block) {
    uint64_t len = std::min(this->_header_block_len - this->_header_block_wrote, UINT64_C(64 * 1024));

    Http3FrameUPtr frame = Http3FrameFactory::create_headers_frame(this->_header_block_reader, len);

    this->_header_block_wrote += len;

    if (this->_header_block_len == this->_header_block_wrote) {
      this->_sent_all_data = true;
    }
    return frame;
  } else {
    return Http3FrameFactory::create_null_frame();
  }
}

bool
Http3HeaderFramer::is_done() const
{
  return this->_sent_all_data;
}

void
Http3HeaderFramer::_convert_header_from_1_1_to_3(HTTPHdr *hdrs)
{
  http2_convert_header_from_1_1_to_2(hdrs);
}

void
Http3HeaderFramer::_generate_header_block()
{
  // Prase response header and generate header block
  int bytes_used           = 0;
  ParseResult parse_result = PARSE_RESULT_ERROR;

  if (this->_transaction->direction() == NET_VCONNECTION_OUT) {
    this->_header.create(HTTP_TYPE_REQUEST);
    http2_init_pseudo_headers(this->_header);
    parse_result = this->_header.parse_req(&this->_http_parser, this->_source_vio->get_reader(), &bytes_used, false);
  } else {
    this->_header.create(HTTP_TYPE_RESPONSE);
    http2_init_pseudo_headers(this->_header);
    parse_result = this->_header.parse_resp(&this->_http_parser, this->_source_vio->get_reader(), &bytes_used, false);
  }
  this->_source_vio->ndone += bytes_used;

  switch (parse_result) {
  case PARSE_RESULT_DONE: {
    this->_convert_header_from_1_1_to_3(&this->_header);

    this->_header_block        = new_MIOBuffer(BUFFER_SIZE_INDEX_32K);
    this->_header_block_reader = this->_header_block->alloc_reader();

    this->_qpack->encode(this->_stream_id, this->_header, this->_header_block, this->_header_block_len);
    break;
  }
  case PARSE_RESULT_CONT:
    break;
  default:
    Debug("http3_trans", "Ignore invalid headers");
    break;
  }
}