server_fuzzer.cc 2.7 KB

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