23 using namespace folly;
27 DEFINE_string(input,
"compress.in",
"Input file for decoding");
30 DEFINE_bool(ack,
true,
"Encoder assumes immediate ack of all frames");
39 std::unique_ptr<folly::IOBuf> buf) {
46 std::vector<std::vector<compress::Header>>& blocks) {
51 folly::File outputF(FLAGS_output, O_CREAT | O_RDWR | O_TRUNC);
56 for (
auto& block : blocks) {
57 auto result = encoder.
encode(block, streamId);
61 result.stream->computeChainDataLength(),
63 writeFrame(appender, streamId,
std::move(result.stream));
70 writeFrame(appender, 0,
std::move(result.control));
80 auto out = outbuf.
move();
81 auto iov = out->getIov();
82 bytesOut +=
writevFull(outputF.fd(), iov.data(), iov.size());
85 LOG(INFO) <<
"Encoded " << (streamId - 1) <<
" streams. Bytes in=" 86 << bytesIn <<
" Bytes out=" << bytesOut <<
" Ratio=" 87 <<
int32_t(100 * (1 - (bytesOut /
double(bytesIn))));
91 std::vector<std::vector<compress::Header>> blocks;
92 std::vector<std::vector<std::string>> cookies{har.
requests.size()};
97 encodeBlocks(decoder, blocks);
108 virtual ssize_t
read() {
113 auto pre = inbuf.preallocate(4096, 4096);
114 rc =
readNoInt(inputF.fd(), pre.first, pre.second);
116 LOG(ERROR) <<
"Read failed on " << FLAGS_input;
119 inbuf.postallocate(rc);
122 if (!inbuf.empty()) {
123 LOG(ERROR) <<
"Premature end of file";
133 class CompressedReader :
public Reader {
138 std::unique_ptr<folly::IOBuf>)> callback;
141 explicit CompressedReader(
143 std::unique_ptr<folly::IOBuf>)> cb)
144 : Reader(FLAGS_input),
163 auto buf = inbuf.
split(length);
164 callback(streamId, length,
std::move(buf));
172 std::map<uint64_t, SimStreamingCallback> streams;
173 CompressedReader creader(
175 std::unique_ptr<folly::IOBuf> buf) {
180 auto res = streams.emplace(std::piecewise_construct,
181 std::forward_as_tuple(streamId),
182 std::forward_as_tuple(streamId,
nullptr,
185 streamId,
std::move(buf), length, &res.first->second);
188 if (creader.read()) {
192 for (
const auto& req : streams) {
194 LOG(ERROR) <<
"request=" << req.first
195 <<
" failed to decode error=" << req.second.error;
198 if (!(req.second.msg == har.
requests[i])) {
199 LOG(ERROR) <<
"requests are not equal, got=" << req.second.msg
204 LOG(INFO) <<
"Verified " << i <<
" streams.";
210 QIFCallback(
uint64_t id_, std::ofstream& of_) :
217 of <<
"# stream " <<
id << std::endl;
220 of << name <<
"\t" << value << std::endl;
227 LOG(FATAL) <<
"Decode error with stream=" <<
id <<
" err=" << decodeError;
233 bool complete{
false};
237 std::ofstream of(FLAGS_output, std::ofstream::trunc);
238 std::map<uint64_t, QIFCallback> streams;
240 CompressedReader creader(
242 std::unique_ptr<folly::IOBuf> buf) {
246 encoderStreamBytes += length;
248 auto res = streams.emplace(std::piecewise_construct,
249 std::forward_as_tuple(streamId),
250 std::forward_as_tuple(streamId, of));
252 streamId,
std::move(buf), length, &res.first->second);
255 if (creader.read()) {
259 for (
const auto&
stream : streams) {
260 CHECK(
stream.second.complete) <<
"Stream " <<
stream.first <<
263 LOG(INFO) <<
"encoderStreamBytes=" << encoderStreamBytes;
268 std::unique_ptr<HTTPArchive> har = (FLAGS_public) ?
272 LOG(ERROR) <<
"Failed to read har file='" << FLAGS_har <<
"'";
275 if (FLAGS_mode ==
"encode") {
276 encodeHar(decoder, *har);
277 }
else if (FLAGS_mode ==
"decode") {
278 return decodeAndVerify(decoder, *har);
280 LOG(ERROR) <<
"Usage" << std::endl;
286 struct QIFReader :
public Reader {
288 std::vector<std::string>
strings;
289 std::vector<std::vector<Header>> blocks{1};
290 enum { LINESTART, COMMENT,
NAME, VALUE, EOL } state_{LINESTART};
294 : Reader(FLAGS_input) {
295 strings.reserve(32768);
298 ssize_t
read()
override {
303 CHECK(blocks.back().empty());
309 return ch ==
'\r' || ch ==
'\n';
314 while (!
c.isAtEnd()) {
320 switch (p.first[0]) {
326 if (!blocks.back().empty()) {
327 blocks.emplace_back();
333 strings.emplace_back();
348 if (p.first[0] ==
'\n') {
353 }
else if (p.first[0] ==
'\r') {
360 strings.back() +=
c.readWhile([] (
uint8_t ch) {
366 strings.emplace_back();
370 strings.back() +=
c.readWhile([] (
uint8_t ch) {
374 CHECK_GE(strings.size(), 2);
375 blocks.back().emplace_back(
377 *(strings.rbegin() + 1), *strings.rbegin()));
389 if (FLAGS_mode ==
"encode") {
391 if (reader.read() != 0) {
392 LOG(ERROR) <<
"Failed to read QIF file='" << FLAGS_input <<
"'";
395 encodeBlocks(decoder, reader.blocks);
396 }
else if (FLAGS_mode ==
"decode") {
397 decodeToQIF(decoder);
399 LOG(ERROR) <<
"Usage" << std::endl;
413 if (!FLAGS_har.empty()) {
414 return interopHAR(decoder);
416 return interopQIF(decoder);
std::unique_ptr< folly::IOBuf > split(size_t n)
const folly::IOBuf * front() const
size_t chainLength() const
DEFINE_string(output,"compress.out","Output file for encoding")
constexpr detail::Map< Move > move
ssize_t readNoInt(int fd, void *buf, size_t count)
std::unique_ptr< folly::IOBuf > move()
void setMaxVulnerable(uint32_t maxVulnerable)
static std::unique_ptr< HTTPArchive > fromPublicFile(const std::string &fname)
—— Concurrent Priority Queue Implementation ——
std::vector< compress::Header > prepareMessageForCompression(const HTTPMessage &msg, std::vector< string > &cookies)
QPACKEncoder::EncodeResult encode(std::vector< compress::Header > &headers, uint64_t id) noexcept
void insert(std::unique_ptr< folly::IOBuf > buf)
ssize_t writevFull(int fd, iovec *iov, int count)
folly::Optional< PskKeyExchangeMode > mode
void init(int *argc, char ***argv, bool removeFlags)
DEFINE_bool(ack, true,"Encoder assumes immediate ack of all frames")
static Options cacheChainLength()
DEFINE_int32(table_size, 4096,"Dynamic table size")
size_t read(T &out, folly::io::Cursor &cursor)
static std::unique_ptr< HTTPArchive > fromFile(const std::string &filename)
HPACK::DecodeError decodeEncoderStream(std::unique_ptr< folly::IOBuf > buf)
void setDecoderHeaderTableMaxSize(uint32_t size)
std::unique_ptr< folly::IOBuf > encodeHeaderAck(uint64_t streamId)
int main(int argc, char **argv)
static const char *const value
HPACK::DecodeError decodeDecoderStream(std::unique_ptr< folly::IOBuf > buf)
void setMaxBlocking(uint32_t maxBlocking)
std::size_t computeChainDataLength() const
std::unique_ptr< folly::IOBuf > encodeTableStateSync()
void setEncoderHeaderTableSize(uint32_t size)
void trimStart(size_t amount)
std::vector< HTTPMessage > requests
static vector< fbstring > strings
constexpr detail::First first
void decodeStreaming(uint64_t streamId, std::unique_ptr< folly::IOBuf > block, uint32_t length, HPACK::StreamingCallback *streamingCb) noexcept