server_fuzzer.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include <httplib.h>
  2. #include <memory>
  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. std::string get_remote_addr() const { return ""; }
  20. bool is_readable() const override { return true; }
  21. bool is_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. socket_t socket() const override { return 0; }
  27. private:
  28. const uint8_t *data_;
  29. size_t size_;
  30. size_t read_pos_;
  31. std::string response_;
  32. };
  33. class FuzzableServer : public httplib::Server {
  34. public:
  35. void ProcessFuzzedRequest(FuzzedStream &stream) {
  36. bool connection_close = false;
  37. process_request(stream, /*last_connection=*/false, connection_close,
  38. nullptr);
  39. }
  40. };
  41. static FuzzableServer g_server;
  42. extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) {
  43. g_server.Get(R"(.*)",
  44. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  45. res.set_content("response content", "text/plain");
  46. });
  47. g_server.Post(R"(.*)",
  48. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  49. res.set_content("response content", "text/plain");
  50. });
  51. g_server.Put(R"(.*)",
  52. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  53. res.set_content("response content", "text/plain");
  54. });
  55. g_server.Patch(R"(.*)",
  56. [&](const httplib::Request & /*req*/, httplib::Response &res) {
  57. res.set_content("response content", "text/plain");
  58. });
  59. g_server.Delete(
  60. R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
  61. res.set_content("response content", "text/plain");
  62. });
  63. g_server.Options(
  64. R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
  65. res.set_content("response content", "text/plain");
  66. });
  67. return 0;
  68. }
  69. extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  70. FuzzedStream stream{data, size};
  71. g_server.ProcessFuzzedRequest(stream);
  72. return 0;
  73. }