content_stream_test.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2019 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "content_stream.h"
  15. #include "string_buffer.h"
  16. #include "gmock/gmock.h"
  17. #include "gtest/gtest.h"
  18. #include <memory>
  19. namespace {
  20. // SingleByteReader wraps a dap::Reader to only provide a single byte for each
  21. // read() call, regardless of the number of bytes actually requested.
  22. class SingleByteReader : public dap::Reader {
  23. public:
  24. SingleByteReader(std::unique_ptr<dap::Reader>&& inner)
  25. : inner(std::move(inner)) {}
  26. bool isOpen() override { return inner->isOpen(); }
  27. void close() override { return inner->close(); }
  28. size_t read(void* buffer, size_t) override { return inner->read(buffer, 1); };
  29. private:
  30. std::unique_ptr<dap::Reader> inner;
  31. };
  32. } // namespace
  33. TEST(ContentStreamTest, Write) {
  34. auto sb = dap::StringBuffer::create();
  35. auto ptr = sb.get();
  36. dap::ContentWriter cw(std::move(sb));
  37. cw.write("Content payload number one");
  38. cw.write("Content payload number two");
  39. cw.write("Content payload number three");
  40. ASSERT_EQ(ptr->string(),
  41. "Content-Length: 26\r\n\r\nContent payload number one"
  42. "Content-Length: 26\r\n\r\nContent payload number two"
  43. "Content-Length: 28\r\n\r\nContent payload number three");
  44. }
  45. TEST(ContentStreamTest, Read) {
  46. auto sb = dap::StringBuffer::create();
  47. sb->write("Content-Length: 26\r\n\r\nContent payload number one");
  48. sb->write("some unrecognised garbage");
  49. sb->write("Content-Length: 26\r\n\r\nContent payload number two");
  50. sb->write("some more unrecognised garbage");
  51. sb->write("Content-Length: 28\r\n\r\nContent payload number three");
  52. dap::ContentReader cs(std::move(sb));
  53. ASSERT_EQ(cs.read(), "Content payload number one");
  54. ASSERT_EQ(cs.read(), "Content payload number two");
  55. ASSERT_EQ(cs.read(), "Content payload number three");
  56. ASSERT_EQ(cs.read(), "");
  57. }
  58. TEST(ContentStreamTest, ShortRead) {
  59. auto sb = dap::StringBuffer::create();
  60. sb->write("Content-Length: 26\r\n\r\nContent payload number one");
  61. sb->write("some unrecognised garbage");
  62. sb->write("Content-Length: 26\r\n\r\nContent payload number two");
  63. sb->write("some more unrecognised garbage");
  64. sb->write("Content-Length: 28\r\n\r\nContent payload number three");
  65. dap::ContentReader cs(
  66. std::unique_ptr<SingleByteReader>(new SingleByteReader(std::move(sb))));
  67. ASSERT_EQ(cs.read(), "Content payload number one");
  68. ASSERT_EQ(cs.read(), "Content payload number two");
  69. ASSERT_EQ(cs.read(), "Content payload number three");
  70. ASSERT_EQ(cs.read(), "");
  71. }
  72. TEST(ContentStreamTest, PartialReadAndParse) {
  73. auto sb = std::make_shared<dap::StringBuffer>();
  74. sb->write("Content");
  75. sb->write("-Length: ");
  76. sb->write("26");
  77. sb->write("\r\n\r\n");
  78. sb->write("Content payload number one");
  79. dap::ContentReader cs(sb);
  80. ASSERT_EQ(cs.read(), "Content payload number one");
  81. ASSERT_EQ(cs.read(), "");
  82. }
  83. TEST(ContentStreamTest, HttpRequest) {
  84. const char* const part1 =
  85. "POST / HTTP/1.1\r\n"
  86. "Host: localhost:8001\r\n"
  87. "Connection: keep-alive\r\n"
  88. "Content-Length: 99\r\n";
  89. const char* const part2 =
  90. "Pragma: no-cache\r\n"
  91. "Cache-Control: no-cache\r\n"
  92. "Content-Type: text/plain;charset=UTF-8\r\n"
  93. "Accept: */*\r\n"
  94. "Origin: null\r\n"
  95. "Sec-Fetch-Site: cross-site\r\n"
  96. "Sec-Fetch-Mode: cors\r\n"
  97. "Sec-Fetch-Dest: empty\r\n"
  98. "Accept-Encoding: gzip, deflate, br\r\n"
  99. "Accept-Language: en-US,en;q=0.9\r\n"
  100. "\r\n"
  101. "{\"type\":\"request\",\"command\":\"launch\",\"arguments\":{\"cmd\":\"/"
  102. "bin/sh -c 'echo remote code execution'\"}}";
  103. auto sb = dap::StringBuffer::create();
  104. sb->write(part1);
  105. sb->write(part2);
  106. dap::ContentReader cr(std::move(sb), dap::kClose);
  107. ASSERT_EQ(cr.read(), "");
  108. ASSERT_FALSE(cr.isOpen());
  109. }