server_fuzzer.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <cstdint>
  2. #include <httplib.h>
  3. class FuzzedStream : public httplib::Stream {
  4. public:
  5. FuzzedStream(const uint8_t *data, size_t size)
  6. : data_(data), size_(size), read_pos_(0) {}
  7. ssize_t read(char *ptr, size_t size) override {
  8. if (size + read_pos_ > size_) { size = size_ - read_pos_; }
  9. memcpy(ptr, data_ + read_pos_, size);
  10. read_pos_ += size;
  11. return static_cast<ssize_t>(size);
  12. }
  13. ssize_t write(const char *ptr, size_t size) override {
  14. response_.append(ptr, size);
  15. return static_cast<int>(size);
  16. }
  17. ssize_t write(const char *ptr) { return write(ptr, strlen(ptr)); }
  18. ssize_t write(const std::string &s) { return write(s.data(), s.size()); }
  19. bool is_readable() const override { return true; }
  20. bool wait_readable() const override { return true; }
  21. bool wait_writable() const override { return true; }
  22. void get_remote_ip_and_port(std::string &ip, int &port) const override {
  23. ip = "127.0.0.1";
  24. port = 8080;
  25. }
  26. void get_local_ip_and_port(std::string &ip, int &port) const override {
  27. ip = "127.0.0.1";
  28. port = 8080;
  29. }
  30. socket_t socket() const override { return 0; }
  31. time_t duration() const override { return 0; };
  32. private:
  33. const uint8_t *data_;
  34. size_t size_;
  35. size_t read_pos_;
  36. std::string response_;
  37. };
  38. class FuzzableServer : public httplib::Server {
  39. public:
  40. void ProcessFuzzedRequest(FuzzedStream &stream) {
  41. bool connection_close = false;
  42. process_request(stream,
  43. /*remote_addr=*/"",
  44. /*remote_port =*/0,
  45. /*local_addr=*/"",
  46. /*local_port =*/0,
  47. /*last_connection=*/false, connection_close, nullptr);
  48. }
  49. };
  50. static FuzzableServer g_server;
  51. extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) {
  52. g_server.Get(R"(.*)",
  53. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  54. res.set_content("response content", "text/plain");
  55. });
  56. g_server.Post(R"(.*)",
  57. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  58. res.set_content("response content", "text/plain");
  59. });
  60. g_server.Put(R"(.*)",
  61. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  62. res.set_content("response content", "text/plain");
  63. });
  64. g_server.Patch(R"(.*)",
  65. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  66. res.set_content("response content", "text/plain");
  67. });
  68. g_server.Delete(
  69. R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
  70. res.set_content("response content", "text/plain");
  71. });
  72. g_server.Options(
  73. R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
  74. res.set_content("response content", "text/plain");
  75. });
  76. return 0;
  77. }
  78. extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  79. FuzzedStream stream{data, size};
  80. g_server.ProcessFuzzedRequest(stream);
  81. return 0;
  82. }