#include <boost/beast/core/buffers_cat.hpp>
#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/beast/core/buffers_suffix.hpp>
+#include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/core/multi_buffer.hpp>
#include <boost/beast/core/ostream.hpp>
#include <boost/beast/http/parser.hpp>
BEAST_EXPECT(p.is_done());
}
+ void
+ testChunkedOverflow()
+ {
+ {
+ const std::string hdr =
+ "HTTP/1.1 200 OK" "\r\n"
+ "Server: test" "\r\n"
+ "Transfer-Encoding: chunked" "\r\n"
+ "\r\n";
+ const std::string chunk1 =
+ "10000000000000000" "\r\n"
+ "data...";
+ test_parser<false> p;
+ error_code ec;
+ p.put(net::buffer(hdr), ec);
+ BEAST_EXPECT(!ec);
+ BEAST_EXPECT(p.is_header_done());
+ auto bt = p.put(net::buffer(chunk1), ec);
+ BEAST_EXPECT(bt == 0);
+ BEAST_EXPECT(ec == error::bad_chunk);
+ }
+ {
+ const std::string hdr =
+ "HTTP/1.1 200 OK" "\r\n"
+ "Server: test" "\r\n"
+ "Transfer-Encoding: chunked" "\r\n"
+ "\r\n"
+ "1" "\r\n"
+ "x" "\r\n";
+ const std::string chunk2 =
+ "FFFFFFFFFFFFFFFF" "\r\n"
+ "data...";
+ test_parser<false> p;
+ p.eager(true);
+ error_code ec;
+ flat_buffer fb;
+ fb.commit(net::buffer_copy(fb.prepare(10000), net::buffer(hdr)));
+ fb.consume(p.put(fb.data(), ec));
+ BEAST_EXPECT(p.is_header_done());
+ BEAST_EXPECT(ec = error::need_more);
+ fb.commit(net::buffer_copy(fb.prepare(10000), net::buffer(chunk2)));
+ auto bt = p.put(fb.data(), ec);
+ BEAST_EXPECT(bt == 0);
+ BEAST_EXPECT(ec == error::body_limit);
+ }
+ {
+ const std::string hdr =
+ "HTTP/1.1 200 OK" "\r\n"
+ "Server: test" "\r\n"
+ "Transfer-Encoding: chunked" "\r\n"
+ "\r\n"
+ "1" "\r\n"
+ "x" "\r\n";
+ const std::string chunk2 =
+ "FFFFFFFFFFFFFFFF" "\r\n"
+ "data...";
+ test_parser<false> p;
+ p.eager(true);
+ p.body_limit(boost::none);
+ error_code ec;
+ flat_buffer fb;
+ fb.commit(net::buffer_copy(fb.prepare(10000), net::buffer(hdr)));
+ fb.consume(p.put(fb.data(), ec));
+ BEAST_EXPECT(p.is_header_done());
+ BEAST_EXPECTS(ec = error::need_more, ec.message());
+ fb.commit(net::buffer_copy(fb.prepare(10000), net::buffer(chunk2)));
+ auto bt = p.put(fb.data(), ec);
+ BEAST_EXPECT(bt == 27);
+ BEAST_EXPECT(!ec);
+ }
+ }
+
+ void testChunkedBodySize()
+ {
+ string_view resp =
+ "HTTP/1.1 200 OK\r\n"
+ "Server: test\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+
+ // chunk 1
+ "4\r\n"
+ "Wiki\r\n"
+
+ // chunk 2
+ "5\r\n"
+ "pedia\r\n"
+
+ // chunk 3
+ "E\r\n"
+ " in\r\n"
+ "\r\n"
+ "chunks.\r\n"
+
+ // end
+ "0\r\n"
+ "\r\n";
+
+ { // body limit not exceeded
+ test_parser<false> p;
+ p.eager(true);
+ p.body_limit(23);
+ error_code ec;
+ p.put(net::buffer(resp.data(), resp.size()), ec);
+ BEAST_EXPECT(!ec);
+ p.put_eof(ec);
+ BEAST_EXPECT(!ec);
+ }
+
+ { // body limit exceeded
+ test_parser<false> p;
+ p.eager(true);
+ p.body_limit(22);
+ error_code ec;
+ p.put(net::buffer(resp.data(), resp.size()), ec);
+ BEAST_EXPECT(ec == error::body_limit);
+ p.put_eof(ec);
+ BEAST_EXPECT(ec == error::partial_message);
+ }
+ }
+
+ void
+ testUnlimitedBody()
+ {
+ const char data[] =
+ "POST / HTTP/1.1\r\n"
+ "Content-Length: 5\r\n"
+ "\r\n"
+ "*****";
+
+ test::fail_count fc(1000);
+ test_parser<true> p(fc);
+ p.body_limit(none);
+ error_code ec;
+ p.put(net::buffer(data, strlen(data)), ec);
+ BEAST_EXPECTS(!ec, ec.message());
+ }
+
//--------------------------------------------------------------------------
void
testRegression1();
testIssue1211();
testIssue1267();
+ testChunkedOverflow();
+ testChunkedBodySize();
+ testUnlimitedBody();
}
};