diff --git a/httplib.h b/httplib.h
index 3809828..e96b561 100644
--- a/httplib.h
+++ b/httplib.h
@@ -902,6 +902,7 @@ public:
   Result Head(const std::string &path, const Headers &headers);
 
   Result Post(const std::string &path);
+  Result Post(const std::string &path, const Headers &headers);
   Result Post(const std::string &path, const char *body, size_t content_length,
               const std::string &content_type);
   Result Post(const std::string &path, const Headers &headers, const char *body,
@@ -1263,6 +1264,7 @@ public:
   Result Head(const std::string &path, const Headers &headers);
 
   Result Post(const std::string &path);
+  Result Post(const std::string &path, const Headers &headers);
   Result Post(const std::string &path, const char *body, size_t content_length,
               const std::string &content_type);
   Result Post(const std::string &path, const Headers &headers, const char *body,
@@ -2877,19 +2879,19 @@ inline void get_remote_ip_and_port(socket_t sock, std::string &ip, int &port) {
 #ifndef _WIN32
     if (addr.ss_family == AF_UNIX) {
 #if defined(__linux__)
-        struct ucred ucred;
-        socklen_t len = sizeof(ucred);
-        if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == 0) {
-            port = ucred.pid;
-        }
-#elif defined(SOL_LOCAL) && defined(SO_PEERPID)  // __APPLE__
-        pid_t pid;
-        socklen_t len = sizeof(pid);
-        if (getsockopt(sock, SOL_LOCAL, SO_PEERPID, &pid, &len) == 0) {
-            port = pid;
-        }
+      struct ucred ucred;
+      socklen_t len = sizeof(ucred);
+      if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == 0) {
+        port = ucred.pid;
+      }
+#elif defined(SOL_LOCAL) && defined(SO_PEERPID) // __APPLE__
+      pid_t pid;
+      socklen_t len = sizeof(pid);
+      if (getsockopt(sock, SOL_LOCAL, SO_PEERPID, &pid, &len) == 0) {
+        port = pid;
+      }
 #endif
-        return;
+      return;
     }
 #endif
     get_remote_ip_and_port(addr, addr_len, ip, port);
@@ -4745,7 +4747,7 @@ inline bool SocketStream::is_readable() const {
 
 inline bool SocketStream::is_writable() const {
   return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0 &&
-    is_socket_alive(sock_);
+         is_socket_alive(sock_);
 }
 
 inline ssize_t SocketStream::read(char *ptr, size_t size) {
@@ -6752,6 +6754,11 @@ inline Result ClientImpl::Post(const std::string &path) {
   return Post(path, std::string(), std::string());
 }
 
+inline Result ClientImpl::Post(const std::string &path,
+                               const Headers &headers) {
+  return Post(path, headers, nullptr, 0, std::string());
+}
+
 inline Result ClientImpl::Post(const std::string &path, const char *body,
                                size_t content_length,
                                const std::string &content_type) {
@@ -7369,7 +7376,7 @@ inline bool SSLSocketStream::is_readable() const {
 
 inline bool SSLSocketStream::is_writable() const {
   return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0 &&
-    is_socket_alive(sock_);
+         is_socket_alive(sock_);
 }
 
 inline ssize_t SSLSocketStream::read(char *ptr, size_t size) {
@@ -8075,6 +8082,9 @@ inline Result Client::Head(const std::string &path, const Headers &headers) {
 }
 
 inline Result Client::Post(const std::string &path) { return cli_->Post(path); }
+inline Result Client::Post(const std::string &path, const Headers &headers) {
+  return cli_->Post(path, headers);
+}
 inline Result Client::Post(const std::string &path, const char *body,
                            size_t content_length,
                            const std::string &content_type) {
diff --git a/test/test.cc b/test/test.cc
index 266eebc..a92d0a5 100644
--- a/test/test.cc
+++ b/test/test.cc
@@ -1715,6 +1715,22 @@ protected:
                 EXPECT_EQ("0", req.get_header_value("Content-Length"));
                 res.set_content("empty-no-content-type", "text/plain");
               })
+        .Post("/path-only",
+              [&](const Request &req, Response &res) {
+                EXPECT_EQ(req.body, "");
+                EXPECT_EQ("", req.get_header_value("Content-Type"));
+                EXPECT_EQ("0", req.get_header_value("Content-Length"));
+                res.set_content("path-only", "text/plain");
+              })
+        .Post("/path-headers-only",
+              [&](const Request &req, Response &res) {
+                EXPECT_EQ(req.body, "");
+                EXPECT_EQ("", req.get_header_value("Content-Type"));
+                EXPECT_EQ("0", req.get_header_value("Content-Length"));
+                EXPECT_EQ("world", req.get_header_value("hello"));
+                EXPECT_EQ("world2", req.get_header_value("hello2"));
+                res.set_content("path-headers-only", "text/plain");
+              })
         .Post("/post-large",
               [&](const Request &req, Response &res) {
                 EXPECT_EQ(req.body, LARGE_DATA);
@@ -2125,6 +2141,21 @@ TEST_F(ServerTest, PostEmptyContentWithNoContentType) {
   ASSERT_EQ("empty-no-content-type", res->body);
 }
 
+TEST_F(ServerTest, PostPathOnly) {
+  auto res = cli_.Post("/path-only");
+  ASSERT_TRUE(res);
+  ASSERT_EQ(200, res->status);
+  ASSERT_EQ("path-only", res->body);
+}
+
+TEST_F(ServerTest, PostPathAndHeadersOnly) {
+  auto res = cli_.Post("/path-headers-only",
+                       Headers({{"hello", "world"}, {"hello2", "world2"}}));
+  ASSERT_TRUE(res);
+  ASSERT_EQ(200, res->status);
+  ASSERT_EQ("path-headers-only", res->body);
+}
+
 TEST_F(ServerTest, PostLarge) {
   auto res = cli_.Post("/post-large", LARGE_DATA, "text/plain");
   ASSERT_TRUE(res);
@@ -4181,7 +4212,8 @@ protected:
       res.set_content("Hello World!", "text/plain");
     });
 
-    t_ = thread([&]() { ASSERT_TRUE(svr_.listen(std::string(), PORT, AI_PASSIVE)); });
+    t_ = thread(
+        [&]() { ASSERT_TRUE(svr_.listen(std::string(), PORT, AI_PASSIVE)); });
 
     while (!svr_.is_running()) {
       std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -4753,7 +4785,7 @@ TEST(SendAPI, SimpleInterface_Online) {
 
 TEST(ClientImplMethods, GetSocketTest) {
   httplib::Server svr;
-  svr.Get( "/", [&](const httplib::Request& /*req*/, httplib::Response& res) {
+  svr.Get("/", [&](const httplib::Request & /*req*/, httplib::Response &res) {
     res.status = 200;
   });
 
@@ -5067,7 +5099,7 @@ TEST(MultipartFormDataTest, PostCustomBoundary) {
   SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
 
   svr.Post("/post_customboundary", [&](const Request &req, Response & /*res*/,
-                        const ContentReader &content_reader) {
+                                       const ContentReader &content_reader) {
     if (req.is_multipart_form_data()) {
       MultipartFormDataItems files;
       content_reader(
@@ -5127,7 +5159,7 @@ TEST(MultipartFormDataTest, PostCustomBoundary) {
 }
 
 TEST(MultipartFormDataTest, PostInvalidBoundaryChars) {
-  
+
   std::this_thread::sleep_for(std::chrono::seconds(1));
 
   std::string data(1024 * 1024 * 2, '&');
@@ -5141,12 +5173,12 @@ TEST(MultipartFormDataTest, PostInvalidBoundaryChars) {
       {"hello", "world", "", ""},
   };
 
-  for (const char& c: " \t\r\n") {
-    auto res = cli.Post("/invalid_boundary", {}, items, string("abc123").append(1, c));
+  for (const char &c : " \t\r\n") {
+    auto res =
+        cli.Post("/invalid_boundary", {}, items, string("abc123").append(1, c));
     ASSERT_EQ(Error::UnsupportedMultipartBoundaryChars, res.error());
     ASSERT_FALSE(res);
   }
-
 }
 
 TEST(MultipartFormDataTest, PutFormData) {
@@ -5215,38 +5247,39 @@ TEST(MultipartFormDataTest, PutFormData) {
 TEST(MultipartFormDataTest, PutFormDataCustomBoundary) {
   SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
 
-  svr.Put("/put_customboundary", [&](const Request &req, const Response & /*res*/,
-                      const ContentReader &content_reader) {
-    if (req.is_multipart_form_data()) {
-      MultipartFormDataItems files;
-      content_reader(
-          [&](const MultipartFormData &file) {
-            files.push_back(file);
-            return true;
-          },
-          [&](const char *data, size_t data_length) {
-            files.back().content.append(data, data_length);
-            return true;
+  svr.Put("/put_customboundary",
+          [&](const Request &req, const Response & /*res*/,
+              const ContentReader &content_reader) {
+            if (req.is_multipart_form_data()) {
+              MultipartFormDataItems files;
+              content_reader(
+                  [&](const MultipartFormData &file) {
+                    files.push_back(file);
+                    return true;
+                  },
+                  [&](const char *data, size_t data_length) {
+                    files.back().content.append(data, data_length);
+                    return true;
+                  });
+
+              EXPECT_TRUE(std::string(files[0].name) == "document");
+              EXPECT_EQ(size_t(1024 * 1024 * 2), files[0].content.size());
+              EXPECT_TRUE(files[0].filename == "2MB_data");
+              EXPECT_TRUE(files[0].content_type == "application/octet-stream");
+
+              EXPECT_TRUE(files[1].name == "hello");
+              EXPECT_TRUE(files[1].content == "world");
+              EXPECT_TRUE(files[1].filename == "");
+              EXPECT_TRUE(files[1].content_type == "");
+            } else {
+              std::string body;
+              content_reader([&](const char *data, size_t data_length) {
+                body.append(data, data_length);
+                return true;
+              });
+            }
           });
 
-      EXPECT_TRUE(std::string(files[0].name) == "document");
-      EXPECT_EQ(size_t(1024 * 1024 * 2), files[0].content.size());
-      EXPECT_TRUE(files[0].filename == "2MB_data");
-      EXPECT_TRUE(files[0].content_type == "application/octet-stream");
-
-      EXPECT_TRUE(files[1].name == "hello");
-      EXPECT_TRUE(files[1].content == "world");
-      EXPECT_TRUE(files[1].filename == "");
-      EXPECT_TRUE(files[1].content_type == "");
-    } else {
-      std::string body;
-      content_reader([&](const char *data, size_t data_length) {
-        body.append(data, data_length);
-        return true;
-      });
-    }
-  });
-
   auto t = std::thread([&]() { svr.listen("localhost", 8080); });
   while (!svr.is_running()) {
     std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -5291,7 +5324,7 @@ TEST(MultipartFormDataTest, PutInvalidBoundaryChars) {
       {"hello", "world", "", ""},
   };
 
-  for (const char& c: " \t\r\n") {
+  for (const char &c : " \t\r\n") {
     auto res = cli.Put("/put", {}, items, string("abc123").append(1, c));
     ASSERT_EQ(Error::UnsupportedMultipartBoundaryChars, res.error());
     ASSERT_FALSE(res);
@@ -5303,9 +5336,7 @@ TEST(MultipartFormDataTest, PutInvalidBoundaryChars) {
 #ifndef _WIN32
 class UnixSocketTest : public ::testing::Test {
 protected:
-  void TearDown() override {
-    std::remove(pathname_.c_str());
-  }
+  void TearDown() override { std::remove(pathname_.c_str()); }
 
   void client_GET(const std::string &addr) {
     httplib::Client cli{addr};
@@ -5320,9 +5351,9 @@ protected:
     EXPECT_EQ(resp.body, content_);
   }
 
-  const std::string pathname_ {"./httplib-server.sock"};
-  const std::string pattern_ {"/hi"};
-  const std::string content_ {"Hello World!"};
+  const std::string pathname_{"./httplib-server.sock"};
+  const std::string pattern_{"/hi"};
+  const std::string content_{"Hello World!"};
 };
 
 TEST_F(UnixSocketTest, pathname) {
@@ -5331,8 +5362,9 @@ TEST_F(UnixSocketTest, pathname) {
     res.set_content(content_, "text/plain");
   });
 
-  std::thread t {[&] {
-    ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(pathname_, 80)); }};
+  std::thread t{[&] {
+    ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(pathname_, 80));
+  }};
   while (!svr.is_running()) {
     std::this_thread::sleep_for(std::chrono::milliseconds(1));
   }
@@ -5344,8 +5376,8 @@ TEST_F(UnixSocketTest, pathname) {
   t.join();
 }
 
-#if defined(__linux__) \
-  || /* __APPLE__ */ (defined(SOL_LOCAL) && defined(SO_PEERPID))
+#if defined(__linux__) ||                                                      \
+    /* __APPLE__ */ (defined(SOL_LOCAL) && defined(SO_PEERPID))
 TEST_F(UnixSocketTest, PeerPid) {
   httplib::Server svr;
   std::string remote_port_val;
@@ -5354,8 +5386,9 @@ TEST_F(UnixSocketTest, PeerPid) {
     remote_port_val = req.get_header_value("REMOTE_PORT");
   });
 
-  std::thread t {[&] {
-    ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(pathname_, 80)); }};
+  std::thread t{[&] {
+    ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(pathname_, 80));
+  }};
   while (!svr.is_running()) {
     std::this_thread::sleep_for(std::chrono::milliseconds(1));
   }
@@ -5371,16 +5404,17 @@ TEST_F(UnixSocketTest, PeerPid) {
 
 #ifdef __linux__
 TEST_F(UnixSocketTest, abstract) {
-  constexpr char svr_path[] {"\x00httplib-server.sock"};
-  const std::string abstract_addr {svr_path, sizeof(svr_path) - 1};
+  constexpr char svr_path[]{"\x00httplib-server.sock"};
+  const std::string abstract_addr{svr_path, sizeof(svr_path) - 1};
 
   httplib::Server svr;
   svr.Get(pattern_, [&](const httplib::Request &, httplib::Response &res) {
     res.set_content(content_, "text/plain");
   });
 
-  std::thread t {[&] {
-    ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(abstract_addr, 80)); }};
+  std::thread t{[&] {
+    ASSERT_TRUE(svr.set_address_family(AF_UNIX).listen(abstract_addr, 80));
+  }};
   while (!svr.is_running()) {
     std::this_thread::sleep_for(std::chrono::milliseconds(1));
   }
@@ -5394,58 +5428,58 @@ TEST_F(UnixSocketTest, abstract) {
 #endif
 
 TEST(SocketStream, is_writable_UNIX) {
-  int fd[2];
-  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
+  int fds[2];
+  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, fds));
 
-  const auto asSocketStream =
-    [&] (socket_t fd, std::function<bool(Stream &)> func) {
-      return detail::process_client_socket(fd, 0, 0, 0, 0, func);
-    };
-  asSocketStream(fd[0], [&] (Stream &s0) {
-    EXPECT_EQ(s0.socket(), fd[0]);
+  const auto asSocketStream = [&](socket_t fd,
+                                  std::function<bool(Stream &)> func) {
+    return detail::process_client_socket(fd, 0, 0, 0, 0, func);
+  };
+  asSocketStream(fds[0], [&](Stream &s0) {
+    EXPECT_EQ(s0.socket(), fds[0]);
     EXPECT_TRUE(s0.is_writable());
 
-    EXPECT_EQ(0, close(fd[1]));
+    EXPECT_EQ(0, close(fds[1]));
     EXPECT_FALSE(s0.is_writable());
 
     return true;
   });
-  EXPECT_EQ(0, close(fd[0]));
+  EXPECT_EQ(0, close(fds[0]));
 }
 
 TEST(SocketStream, is_writable_INET) {
   sockaddr_in addr;
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
-  addr.sin_port = htons(PORT+1);
+  addr.sin_port = htons(PORT + 1);
   addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 
   int disconnected_svr_sock = -1;
-  std::thread svr {[&] {
+  std::thread svr{[&] {
     const int s = socket(AF_INET, SOCK_STREAM, 0);
     ASSERT_LE(0, s);
-    ASSERT_EQ(0, ::bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)));
+    ASSERT_EQ(0, ::bind(s, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)));
     ASSERT_EQ(0, listen(s, 1));
     ASSERT_LE(0, disconnected_svr_sock = accept(s, nullptr, nullptr));
     ASSERT_EQ(0, close(s));
   }};
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
-  std::thread cli {[&] {
+  std::thread cli{[&] {
     const int s = socket(AF_INET, SOCK_STREAM, 0);
     ASSERT_LE(0, s);
-    ASSERT_EQ(0, connect(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)));
+    ASSERT_EQ(0, connect(s, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)));
     ASSERT_EQ(0, close(s));
   }};
   cli.join();
   svr.join();
   ASSERT_NE(disconnected_svr_sock, -1);
 
-  const auto asSocketStream =
-    [&] (socket_t fd, std::function<bool(Stream &)> func) {
-      return detail::process_client_socket(fd, 0, 0, 0, 0, func);
-    };
-  asSocketStream(disconnected_svr_sock, [&] (Stream &ss) {
+  const auto asSocketStream = [&](socket_t fd,
+                                  std::function<bool(Stream &)> func) {
+    return detail::process_client_socket(fd, 0, 0, 0, 0, func);
+  };
+  asSocketStream(disconnected_svr_sock, [&](Stream &ss) {
     EXPECT_EQ(ss.socket(), disconnected_svr_sock);
     EXPECT_FALSE(ss.is_writable());
 
@@ -5454,4 +5488,4 @@ TEST(SocketStream, is_writable_INET) {
 
   ASSERT_EQ(0, close(disconnected_svr_sock));
 }
-#endif  // #ifndef _WIN32
+#endif // #ifndef _WIN32