proxygen
LineBasedFrameDecoder.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 namespace wangle {
20 
21 using folly::io::Cursor;
22 using folly::IOBuf;
23 using folly::IOBufQueue;
24 
26  bool stripDelimiter,
27  TerminatorType terminatorType)
28  : maxLength_(maxLength)
29  , stripDelimiter_(stripDelimiter)
30  , terminatorType_(terminatorType) {}
31 
33  IOBufQueue& buf,
34  std::unique_ptr<IOBuf>& result,
35  size_t&) {
36  int64_t eol = findEndOfLine(buf);
37 
38  if (!discarding_) {
39  if (eol >= 0) {
40  Cursor c(buf.front());
41  c += eol;
42  auto delimLength = c.read<char>() == '\r' ? 2 : 1;
43  if (eol > maxLength_) {
44  buf.split(eol + delimLength);
45  fail(ctx, folly::to<std::string>(eol));
46  return false;
47  }
48 
49  std::unique_ptr<folly::IOBuf> frame;
50 
51  if (stripDelimiter_) {
52  frame = buf.split(eol);
53  buf.trimStart(delimLength);
54  } else {
55  frame = buf.split(eol + delimLength);
56  }
57 
58  result = std::move(frame);
59  return true;
60  } else {
61  auto len = buf.chainLength();
62  if (len > maxLength_) {
63  discardedBytes_ = len;
64  buf.trimStart(len);
65  discarding_ = true;
66  fail(ctx, "over " + folly::to<std::string>(len));
67  }
68  return false;
69  }
70  } else {
71  if (eol >= 0) {
72  Cursor c(buf.front());
73  c += eol;
74  auto delimLength = c.read<char>() == '\r' ? 2 : 1;
75  buf.trimStart(eol + delimLength);
76  discardedBytes_ = 0;
77  discarding_ = false;
78  } else {
80  buf.move();
81  }
82 
83  return false;
84  }
85 }
86 
88  ctx->fireReadException(
89  folly::make_exception_wrapper<std::runtime_error>(
90  "frame length" + len +
91  " exeeds max " + folly::to<std::string>(maxLength_)));
92 }
93 
95  Cursor c(buf.front());
96  for (uint32_t i = 0; i < maxLength_ && i < buf.chainLength(); i++) {
97  auto b = c.read<char>();
99  return i;
101  b == '\r' && !c.isAtEnd() && c.read<char>() == '\n') {
102  return i;
103  }
104  }
105 
106  return -1;
107 }
108 
109 } // namespace wangle
std::unique_ptr< folly::IOBuf > split(size_t n)
Definition: IOBufQueue.h:420
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
size_t chainLength() const
Definition: IOBufQueue.h:492
char b
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< folly::IOBuf > move()
Definition: IOBufQueue.h:459
LineBasedFrameDecoder(uint32_t maxLength=UINT_MAX, bool stripDelimiter=true, TerminatorType terminatorType=TerminatorType::BOTH)
void fail(Context *ctx, std::string len)
InboundHandler< folly::IOBufQueue &, M >::Context Context
int64_t findEndOfLine(folly::IOBufQueue &buf)
const char * string
Definition: Conv.cpp:212
bool decode(Context *ctx, folly::IOBufQueue &buf, std::unique_ptr< folly::IOBuf > &result, size_t &) override
void trimStart(size_t amount)
Definition: IOBufQueue.cpp:255
char c