1
0

httplib.h 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729
  1. //
  2. // httplib.h
  3. //
  4. // Copyright (c) 2025 Yuji Hirose. All rights reserved.
  5. // MIT License
  6. //
  7. #ifndef CPPHTTPLIB_HTTPLIB_H
  8. #define CPPHTTPLIB_HTTPLIB_H
  9. #define CPPHTTPLIB_VERSION "0.27.0"
  10. #define CPPHTTPLIB_VERSION_NUM "0x001B00"
  11. /*
  12. * Platform compatibility check
  13. */
  14. #if defined(_WIN32) && !defined(_WIN64)
  15. #if defined(_MSC_VER)
  16. #pragma message( \
  17. "cpp-httplib doesn't support 32-bit Windows. Please use a 64-bit compiler.")
  18. #else
  19. #warning \
  20. "cpp-httplib doesn't support 32-bit Windows. Please use a 64-bit compiler."
  21. #endif
  22. #elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ < 8
  23. #warning \
  24. "cpp-httplib doesn't support 32-bit platforms. Please use a 64-bit compiler."
  25. #elif defined(__SIZEOF_SIZE_T__) && __SIZEOF_SIZE_T__ < 8
  26. #warning \
  27. "cpp-httplib doesn't support platforms where size_t is less than 64 bits."
  28. #endif
  29. #ifdef _WIN32
  30. #if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0A00
  31. #error \
  32. "cpp-httplib doesn't support Windows 8 or lower. Please use Windows 10 or later."
  33. #endif
  34. #endif
  35. /*
  36. * Configuration
  37. */
  38. #ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND
  39. #define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5
  40. #endif
  41. #ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_CHECK_INTERVAL_USECOND
  42. #define CPPHTTPLIB_KEEPALIVE_TIMEOUT_CHECK_INTERVAL_USECOND 10000
  43. #endif
  44. #ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT
  45. #define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 100
  46. #endif
  47. #ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND
  48. #define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300
  49. #endif
  50. #ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND
  51. #define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0
  52. #endif
  53. #ifndef CPPHTTPLIB_SERVER_READ_TIMEOUT_SECOND
  54. #define CPPHTTPLIB_SERVER_READ_TIMEOUT_SECOND 5
  55. #endif
  56. #ifndef CPPHTTPLIB_SERVER_READ_TIMEOUT_USECOND
  57. #define CPPHTTPLIB_SERVER_READ_TIMEOUT_USECOND 0
  58. #endif
  59. #ifndef CPPHTTPLIB_SERVER_WRITE_TIMEOUT_SECOND
  60. #define CPPHTTPLIB_SERVER_WRITE_TIMEOUT_SECOND 5
  61. #endif
  62. #ifndef CPPHTTPLIB_SERVER_WRITE_TIMEOUT_USECOND
  63. #define CPPHTTPLIB_SERVER_WRITE_TIMEOUT_USECOND 0
  64. #endif
  65. #ifndef CPPHTTPLIB_CLIENT_READ_TIMEOUT_SECOND
  66. #define CPPHTTPLIB_CLIENT_READ_TIMEOUT_SECOND 300
  67. #endif
  68. #ifndef CPPHTTPLIB_CLIENT_READ_TIMEOUT_USECOND
  69. #define CPPHTTPLIB_CLIENT_READ_TIMEOUT_USECOND 0
  70. #endif
  71. #ifndef CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_SECOND
  72. #define CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_SECOND 5
  73. #endif
  74. #ifndef CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_USECOND
  75. #define CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_USECOND 0
  76. #endif
  77. #ifndef CPPHTTPLIB_CLIENT_MAX_TIMEOUT_MSECOND
  78. #define CPPHTTPLIB_CLIENT_MAX_TIMEOUT_MSECOND 0
  79. #endif
  80. #ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND
  81. #define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0
  82. #endif
  83. #ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND
  84. #ifdef _WIN32
  85. #define CPPHTTPLIB_IDLE_INTERVAL_USECOND 1000
  86. #else
  87. #define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0
  88. #endif
  89. #endif
  90. #ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH
  91. #define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192
  92. #endif
  93. #ifndef CPPHTTPLIB_HEADER_MAX_LENGTH
  94. #define CPPHTTPLIB_HEADER_MAX_LENGTH 8192
  95. #endif
  96. #ifndef CPPHTTPLIB_HEADER_MAX_COUNT
  97. #define CPPHTTPLIB_HEADER_MAX_COUNT 100
  98. #endif
  99. #ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT
  100. #define CPPHTTPLIB_REDIRECT_MAX_COUNT 20
  101. #endif
  102. #ifndef CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT
  103. #define CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT 1024
  104. #endif
  105. #ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH
  106. #define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits<size_t>::max)())
  107. #endif
  108. #ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
  109. #define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH 8192
  110. #endif
  111. #ifndef CPPHTTPLIB_RANGE_MAX_COUNT
  112. #define CPPHTTPLIB_RANGE_MAX_COUNT 1024
  113. #endif
  114. #ifndef CPPHTTPLIB_TCP_NODELAY
  115. #define CPPHTTPLIB_TCP_NODELAY false
  116. #endif
  117. #ifndef CPPHTTPLIB_IPV6_V6ONLY
  118. #define CPPHTTPLIB_IPV6_V6ONLY false
  119. #endif
  120. #ifndef CPPHTTPLIB_RECV_BUFSIZ
  121. #define CPPHTTPLIB_RECV_BUFSIZ size_t(16384u)
  122. #endif
  123. #ifndef CPPHTTPLIB_SEND_BUFSIZ
  124. #define CPPHTTPLIB_SEND_BUFSIZ size_t(16384u)
  125. #endif
  126. #ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ
  127. #define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u)
  128. #endif
  129. #ifndef CPPHTTPLIB_THREAD_POOL_COUNT
  130. #define CPPHTTPLIB_THREAD_POOL_COUNT \
  131. ((std::max)(8u, std::thread::hardware_concurrency() > 0 \
  132. ? std::thread::hardware_concurrency() - 1 \
  133. : 0))
  134. #endif
  135. #ifndef CPPHTTPLIB_RECV_FLAGS
  136. #define CPPHTTPLIB_RECV_FLAGS 0
  137. #endif
  138. #ifndef CPPHTTPLIB_SEND_FLAGS
  139. #define CPPHTTPLIB_SEND_FLAGS 0
  140. #endif
  141. #ifndef CPPHTTPLIB_LISTEN_BACKLOG
  142. #define CPPHTTPLIB_LISTEN_BACKLOG 5
  143. #endif
  144. #ifndef CPPHTTPLIB_MAX_LINE_LENGTH
  145. #define CPPHTTPLIB_MAX_LINE_LENGTH 32768
  146. #endif
  147. /*
  148. * Headers
  149. */
  150. #ifdef _WIN32
  151. #ifndef _CRT_SECURE_NO_WARNINGS
  152. #define _CRT_SECURE_NO_WARNINGS
  153. #endif //_CRT_SECURE_NO_WARNINGS
  154. #ifndef _CRT_NONSTDC_NO_DEPRECATE
  155. #define _CRT_NONSTDC_NO_DEPRECATE
  156. #endif //_CRT_NONSTDC_NO_DEPRECATE
  157. #if defined(_MSC_VER)
  158. #if _MSC_VER < 1900
  159. #error Sorry, Visual Studio versions prior to 2015 are not supported
  160. #endif
  161. #pragma comment(lib, "ws2_32.lib")
  162. using ssize_t = __int64;
  163. #endif // _MSC_VER
  164. #ifndef S_ISREG
  165. #define S_ISREG(m) (((m) & S_IFREG) == S_IFREG)
  166. #endif // S_ISREG
  167. #ifndef S_ISDIR
  168. #define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
  169. #endif // S_ISDIR
  170. #ifndef NOMINMAX
  171. #define NOMINMAX
  172. #endif // NOMINMAX
  173. #include <io.h>
  174. #include <winsock2.h>
  175. #include <ws2tcpip.h>
  176. #if defined(__has_include)
  177. #if __has_include(<afunix.h>)
  178. // afunix.h uses types declared in winsock2.h, so has to be included after it.
  179. #include <afunix.h>
  180. #define CPPHTTPLIB_HAVE_AFUNIX_H 1
  181. #endif
  182. #endif
  183. #ifndef WSA_FLAG_NO_HANDLE_INHERIT
  184. #define WSA_FLAG_NO_HANDLE_INHERIT 0x80
  185. #endif
  186. using nfds_t = unsigned long;
  187. using socket_t = SOCKET;
  188. using socklen_t = int;
  189. #else // not _WIN32
  190. #include <arpa/inet.h>
  191. #if !defined(_AIX) && !defined(__MVS__)
  192. #include <ifaddrs.h>
  193. #endif
  194. #ifdef __MVS__
  195. #include <strings.h>
  196. #ifndef NI_MAXHOST
  197. #define NI_MAXHOST 1025
  198. #endif
  199. #endif
  200. #include <net/if.h>
  201. #include <netdb.h>
  202. #include <netinet/in.h>
  203. #ifdef __linux__
  204. #include <resolv.h>
  205. #endif
  206. #include <csignal>
  207. #include <netinet/tcp.h>
  208. #include <poll.h>
  209. #include <pthread.h>
  210. #include <sys/mman.h>
  211. #include <sys/socket.h>
  212. #include <sys/un.h>
  213. #include <unistd.h>
  214. using socket_t = int;
  215. #ifndef INVALID_SOCKET
  216. #define INVALID_SOCKET (-1)
  217. #endif
  218. #endif //_WIN32
  219. #if defined(__APPLE__)
  220. #include <TargetConditionals.h>
  221. #endif
  222. #include <algorithm>
  223. #include <array>
  224. #include <atomic>
  225. #include <cassert>
  226. #include <cctype>
  227. #include <climits>
  228. #include <condition_variable>
  229. #include <cstring>
  230. #include <errno.h>
  231. #include <exception>
  232. #include <fcntl.h>
  233. #include <functional>
  234. #include <iomanip>
  235. #include <iostream>
  236. #include <list>
  237. #include <map>
  238. #include <memory>
  239. #include <mutex>
  240. #include <random>
  241. #include <regex>
  242. #include <set>
  243. #include <sstream>
  244. #include <string>
  245. #include <sys/stat.h>
  246. #include <thread>
  247. #include <unordered_map>
  248. #include <unordered_set>
  249. #include <utility>
  250. #if defined(CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO) || \
  251. defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN)
  252. #if TARGET_OS_MAC
  253. #include <CFNetwork/CFHost.h>
  254. #include <CoreFoundation/CoreFoundation.h>
  255. #endif
  256. #endif // CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO or
  257. // CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN
  258. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  259. #ifdef _WIN32
  260. #include <wincrypt.h>
  261. // these are defined in wincrypt.h and it breaks compilation if BoringSSL is
  262. // used
  263. #undef X509_NAME
  264. #undef X509_CERT_PAIR
  265. #undef X509_EXTENSIONS
  266. #undef PKCS7_SIGNER_INFO
  267. #ifdef _MSC_VER
  268. #pragma comment(lib, "crypt32.lib")
  269. #endif
  270. #endif // _WIN32
  271. #if defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN)
  272. #if TARGET_OS_MAC
  273. #include <Security/Security.h>
  274. #endif
  275. #endif // CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO
  276. #include <openssl/err.h>
  277. #include <openssl/evp.h>
  278. #include <openssl/ssl.h>
  279. #include <openssl/x509v3.h>
  280. #if defined(_WIN32) && defined(OPENSSL_USE_APPLINK)
  281. #include <openssl/applink.c>
  282. #endif
  283. #include <iostream>
  284. #include <sstream>
  285. #if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER)
  286. #if OPENSSL_VERSION_NUMBER < 0x1010107f
  287. #error Please use OpenSSL or a current version of BoringSSL
  288. #endif
  289. #define SSL_get1_peer_certificate SSL_get_peer_certificate
  290. #elif OPENSSL_VERSION_NUMBER < 0x30000000L
  291. #error Sorry, OpenSSL versions prior to 3.0.0 are not supported
  292. #endif
  293. #endif // CPPHTTPLIB_OPENSSL_SUPPORT
  294. #ifdef CPPHTTPLIB_ZLIB_SUPPORT
  295. #include <zlib.h>
  296. #endif
  297. #ifdef CPPHTTPLIB_BROTLI_SUPPORT
  298. #include <brotli/decode.h>
  299. #include <brotli/encode.h>
  300. #endif
  301. #ifdef CPPHTTPLIB_ZSTD_SUPPORT
  302. #include <zstd.h>
  303. #endif
  304. /*
  305. * Declaration
  306. */
  307. namespace httplib {
  308. namespace detail {
  309. /*
  310. * Backport std::make_unique from C++14.
  311. *
  312. * NOTE: This code came up with the following stackoverflow post:
  313. * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique
  314. *
  315. */
  316. template <class T, class... Args>
  317. typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
  318. make_unique(Args &&...args) {
  319. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  320. }
  321. template <class T>
  322. typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
  323. make_unique(std::size_t n) {
  324. typedef typename std::remove_extent<T>::type RT;
  325. return std::unique_ptr<T>(new RT[n]);
  326. }
  327. namespace case_ignore {
  328. inline unsigned char to_lower(int c) {
  329. const static unsigned char table[256] = {
  330. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  331. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  332. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
  333. 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  334. 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
  335. 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
  336. 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
  337. 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
  338. 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
  339. 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
  340. 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
  341. 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
  342. 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 224, 225, 226,
  343. 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
  344. 242, 243, 244, 245, 246, 215, 248, 249, 250, 251, 252, 253, 254, 223, 224,
  345. 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  346. 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
  347. 255,
  348. };
  349. return table[(unsigned char)(char)c];
  350. }
  351. inline bool equal(const std::string &a, const std::string &b) {
  352. return a.size() == b.size() &&
  353. std::equal(a.begin(), a.end(), b.begin(), [](char ca, char cb) {
  354. return to_lower(ca) == to_lower(cb);
  355. });
  356. }
  357. struct equal_to {
  358. bool operator()(const std::string &a, const std::string &b) const {
  359. return equal(a, b);
  360. }
  361. };
  362. struct hash {
  363. size_t operator()(const std::string &key) const {
  364. return hash_core(key.data(), key.size(), 0);
  365. }
  366. size_t hash_core(const char *s, size_t l, size_t h) const {
  367. return (l == 0) ? h
  368. : hash_core(s + 1, l - 1,
  369. // Unsets the 6 high bits of h, therefore no
  370. // overflow happens
  371. (((std::numeric_limits<size_t>::max)() >> 6) &
  372. h * 33) ^
  373. static_cast<unsigned char>(to_lower(*s)));
  374. }
  375. };
  376. template <typename T>
  377. using unordered_set = std::unordered_set<T, detail::case_ignore::hash,
  378. detail::case_ignore::equal_to>;
  379. } // namespace case_ignore
  380. // This is based on
  381. // "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189".
  382. struct scope_exit {
  383. explicit scope_exit(std::function<void(void)> &&f)
  384. : exit_function(std::move(f)), execute_on_destruction{true} {}
  385. scope_exit(scope_exit &&rhs) noexcept
  386. : exit_function(std::move(rhs.exit_function)),
  387. execute_on_destruction{rhs.execute_on_destruction} {
  388. rhs.release();
  389. }
  390. ~scope_exit() {
  391. if (execute_on_destruction) { this->exit_function(); }
  392. }
  393. void release() { this->execute_on_destruction = false; }
  394. private:
  395. scope_exit(const scope_exit &) = delete;
  396. void operator=(const scope_exit &) = delete;
  397. scope_exit &operator=(scope_exit &&) = delete;
  398. std::function<void(void)> exit_function;
  399. bool execute_on_destruction;
  400. };
  401. } // namespace detail
  402. enum SSLVerifierResponse {
  403. // no decision has been made, use the built-in certificate verifier
  404. NoDecisionMade,
  405. // connection certificate is verified and accepted
  406. CertificateAccepted,
  407. // connection certificate was processed but is rejected
  408. CertificateRejected
  409. };
  410. enum StatusCode {
  411. // Information responses
  412. Continue_100 = 100,
  413. SwitchingProtocol_101 = 101,
  414. Processing_102 = 102,
  415. EarlyHints_103 = 103,
  416. // Successful responses
  417. OK_200 = 200,
  418. Created_201 = 201,
  419. Accepted_202 = 202,
  420. NonAuthoritativeInformation_203 = 203,
  421. NoContent_204 = 204,
  422. ResetContent_205 = 205,
  423. PartialContent_206 = 206,
  424. MultiStatus_207 = 207,
  425. AlreadyReported_208 = 208,
  426. IMUsed_226 = 226,
  427. // Redirection messages
  428. MultipleChoices_300 = 300,
  429. MovedPermanently_301 = 301,
  430. Found_302 = 302,
  431. SeeOther_303 = 303,
  432. NotModified_304 = 304,
  433. UseProxy_305 = 305,
  434. unused_306 = 306,
  435. TemporaryRedirect_307 = 307,
  436. PermanentRedirect_308 = 308,
  437. // Client error responses
  438. BadRequest_400 = 400,
  439. Unauthorized_401 = 401,
  440. PaymentRequired_402 = 402,
  441. Forbidden_403 = 403,
  442. NotFound_404 = 404,
  443. MethodNotAllowed_405 = 405,
  444. NotAcceptable_406 = 406,
  445. ProxyAuthenticationRequired_407 = 407,
  446. RequestTimeout_408 = 408,
  447. Conflict_409 = 409,
  448. Gone_410 = 410,
  449. LengthRequired_411 = 411,
  450. PreconditionFailed_412 = 412,
  451. PayloadTooLarge_413 = 413,
  452. UriTooLong_414 = 414,
  453. UnsupportedMediaType_415 = 415,
  454. RangeNotSatisfiable_416 = 416,
  455. ExpectationFailed_417 = 417,
  456. ImATeapot_418 = 418,
  457. MisdirectedRequest_421 = 421,
  458. UnprocessableContent_422 = 422,
  459. Locked_423 = 423,
  460. FailedDependency_424 = 424,
  461. TooEarly_425 = 425,
  462. UpgradeRequired_426 = 426,
  463. PreconditionRequired_428 = 428,
  464. TooManyRequests_429 = 429,
  465. RequestHeaderFieldsTooLarge_431 = 431,
  466. UnavailableForLegalReasons_451 = 451,
  467. // Server error responses
  468. InternalServerError_500 = 500,
  469. NotImplemented_501 = 501,
  470. BadGateway_502 = 502,
  471. ServiceUnavailable_503 = 503,
  472. GatewayTimeout_504 = 504,
  473. HttpVersionNotSupported_505 = 505,
  474. VariantAlsoNegotiates_506 = 506,
  475. InsufficientStorage_507 = 507,
  476. LoopDetected_508 = 508,
  477. NotExtended_510 = 510,
  478. NetworkAuthenticationRequired_511 = 511,
  479. };
  480. using Headers =
  481. std::unordered_multimap<std::string, std::string, detail::case_ignore::hash,
  482. detail::case_ignore::equal_to>;
  483. using Params = std::multimap<std::string, std::string>;
  484. using Match = std::smatch;
  485. using DownloadProgress = std::function<bool(size_t current, size_t total)>;
  486. using UploadProgress = std::function<bool(size_t current, size_t total)>;
  487. struct Response;
  488. using ResponseHandler = std::function<bool(const Response &response)>;
  489. struct FormData {
  490. std::string name;
  491. std::string content;
  492. std::string filename;
  493. std::string content_type;
  494. Headers headers;
  495. };
  496. struct FormField {
  497. std::string name;
  498. std::string content;
  499. Headers headers;
  500. };
  501. using FormFields = std::multimap<std::string, FormField>;
  502. using FormFiles = std::multimap<std::string, FormData>;
  503. struct MultipartFormData {
  504. FormFields fields; // Text fields from multipart
  505. FormFiles files; // Files from multipart
  506. // Text field access
  507. std::string get_field(const std::string &key, size_t id = 0) const;
  508. std::vector<std::string> get_fields(const std::string &key) const;
  509. bool has_field(const std::string &key) const;
  510. size_t get_field_count(const std::string &key) const;
  511. // File access
  512. FormData get_file(const std::string &key, size_t id = 0) const;
  513. std::vector<FormData> get_files(const std::string &key) const;
  514. bool has_file(const std::string &key) const;
  515. size_t get_file_count(const std::string &key) const;
  516. };
  517. struct UploadFormData {
  518. std::string name;
  519. std::string content;
  520. std::string filename;
  521. std::string content_type;
  522. };
  523. using UploadFormDataItems = std::vector<UploadFormData>;
  524. class DataSink {
  525. public:
  526. DataSink() : os(&sb_), sb_(*this) {}
  527. DataSink(const DataSink &) = delete;
  528. DataSink &operator=(const DataSink &) = delete;
  529. DataSink(DataSink &&) = delete;
  530. DataSink &operator=(DataSink &&) = delete;
  531. std::function<bool(const char *data, size_t data_len)> write;
  532. std::function<bool()> is_writable;
  533. std::function<void()> done;
  534. std::function<void(const Headers &trailer)> done_with_trailer;
  535. std::ostream os;
  536. private:
  537. class data_sink_streambuf final : public std::streambuf {
  538. public:
  539. explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {}
  540. protected:
  541. std::streamsize xsputn(const char *s, std::streamsize n) override {
  542. sink_.write(s, static_cast<size_t>(n));
  543. return n;
  544. }
  545. private:
  546. DataSink &sink_;
  547. };
  548. data_sink_streambuf sb_;
  549. };
  550. using ContentProvider =
  551. std::function<bool(size_t offset, size_t length, DataSink &sink)>;
  552. using ContentProviderWithoutLength =
  553. std::function<bool(size_t offset, DataSink &sink)>;
  554. using ContentProviderResourceReleaser = std::function<void(bool success)>;
  555. struct FormDataProvider {
  556. std::string name;
  557. ContentProviderWithoutLength provider;
  558. std::string filename;
  559. std::string content_type;
  560. };
  561. using FormDataProviderItems = std::vector<FormDataProvider>;
  562. using ContentReceiverWithProgress = std::function<bool(
  563. const char *data, size_t data_length, size_t offset, size_t total_length)>;
  564. using ContentReceiver =
  565. std::function<bool(const char *data, size_t data_length)>;
  566. using FormDataHeader = std::function<bool(const FormData &file)>;
  567. class ContentReader {
  568. public:
  569. using Reader = std::function<bool(ContentReceiver receiver)>;
  570. using FormDataReader =
  571. std::function<bool(FormDataHeader header, ContentReceiver receiver)>;
  572. ContentReader(Reader reader, FormDataReader multipart_reader)
  573. : reader_(std::move(reader)),
  574. formdata_reader_(std::move(multipart_reader)) {}
  575. bool operator()(FormDataHeader header, ContentReceiver receiver) const {
  576. return formdata_reader_(std::move(header), std::move(receiver));
  577. }
  578. bool operator()(ContentReceiver receiver) const {
  579. return reader_(std::move(receiver));
  580. }
  581. Reader reader_;
  582. FormDataReader formdata_reader_;
  583. };
  584. using Range = std::pair<ssize_t, ssize_t>;
  585. using Ranges = std::vector<Range>;
  586. struct Request {
  587. std::string method;
  588. std::string path;
  589. std::string matched_route;
  590. Params params;
  591. Headers headers;
  592. Headers trailers;
  593. std::string body;
  594. std::string remote_addr;
  595. int remote_port = -1;
  596. std::string local_addr;
  597. int local_port = -1;
  598. // for server
  599. std::string version;
  600. std::string target;
  601. MultipartFormData form;
  602. Ranges ranges;
  603. Match matches;
  604. std::unordered_map<std::string, std::string> path_params;
  605. std::function<bool()> is_connection_closed = []() { return true; };
  606. // for client
  607. std::vector<std::string> accept_content_types;
  608. ResponseHandler response_handler;
  609. ContentReceiverWithProgress content_receiver;
  610. DownloadProgress download_progress;
  611. UploadProgress upload_progress;
  612. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  613. const SSL *ssl = nullptr;
  614. #endif
  615. bool has_header(const std::string &key) const;
  616. std::string get_header_value(const std::string &key, const char *def = "",
  617. size_t id = 0) const;
  618. size_t get_header_value_u64(const std::string &key, size_t def = 0,
  619. size_t id = 0) const;
  620. size_t get_header_value_count(const std::string &key) const;
  621. void set_header(const std::string &key, const std::string &val);
  622. bool has_trailer(const std::string &key) const;
  623. std::string get_trailer_value(const std::string &key, size_t id = 0) const;
  624. size_t get_trailer_value_count(const std::string &key) const;
  625. bool has_param(const std::string &key) const;
  626. std::string get_param_value(const std::string &key, size_t id = 0) const;
  627. size_t get_param_value_count(const std::string &key) const;
  628. bool is_multipart_form_data() const;
  629. // private members...
  630. size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT;
  631. size_t content_length_ = 0;
  632. ContentProvider content_provider_;
  633. bool is_chunked_content_provider_ = false;
  634. size_t authorization_count_ = 0;
  635. std::chrono::time_point<std::chrono::steady_clock> start_time_ =
  636. (std::chrono::steady_clock::time_point::min)();
  637. };
  638. struct Response {
  639. std::string version;
  640. int status = -1;
  641. std::string reason;
  642. Headers headers;
  643. Headers trailers;
  644. std::string body;
  645. std::string location; // Redirect location
  646. bool has_header(const std::string &key) const;
  647. std::string get_header_value(const std::string &key, const char *def = "",
  648. size_t id = 0) const;
  649. size_t get_header_value_u64(const std::string &key, size_t def = 0,
  650. size_t id = 0) const;
  651. size_t get_header_value_count(const std::string &key) const;
  652. void set_header(const std::string &key, const std::string &val);
  653. bool has_trailer(const std::string &key) const;
  654. std::string get_trailer_value(const std::string &key, size_t id = 0) const;
  655. size_t get_trailer_value_count(const std::string &key) const;
  656. void set_redirect(const std::string &url, int status = StatusCode::Found_302);
  657. void set_content(const char *s, size_t n, const std::string &content_type);
  658. void set_content(const std::string &s, const std::string &content_type);
  659. void set_content(std::string &&s, const std::string &content_type);
  660. void set_content_provider(
  661. size_t length, const std::string &content_type, ContentProvider provider,
  662. ContentProviderResourceReleaser resource_releaser = nullptr);
  663. void set_content_provider(
  664. const std::string &content_type, ContentProviderWithoutLength provider,
  665. ContentProviderResourceReleaser resource_releaser = nullptr);
  666. void set_chunked_content_provider(
  667. const std::string &content_type, ContentProviderWithoutLength provider,
  668. ContentProviderResourceReleaser resource_releaser = nullptr);
  669. void set_file_content(const std::string &path,
  670. const std::string &content_type);
  671. void set_file_content(const std::string &path);
  672. Response() = default;
  673. Response(const Response &) = default;
  674. Response &operator=(const Response &) = default;
  675. Response(Response &&) = default;
  676. Response &operator=(Response &&) = default;
  677. ~Response() {
  678. if (content_provider_resource_releaser_) {
  679. content_provider_resource_releaser_(content_provider_success_);
  680. }
  681. }
  682. // private members...
  683. size_t content_length_ = 0;
  684. ContentProvider content_provider_;
  685. ContentProviderResourceReleaser content_provider_resource_releaser_;
  686. bool is_chunked_content_provider_ = false;
  687. bool content_provider_success_ = false;
  688. std::string file_content_path_;
  689. std::string file_content_content_type_;
  690. };
  691. class Stream {
  692. public:
  693. virtual ~Stream() = default;
  694. virtual bool is_readable() const = 0;
  695. virtual bool wait_readable() const = 0;
  696. virtual bool wait_writable() const = 0;
  697. virtual ssize_t read(char *ptr, size_t size) = 0;
  698. virtual ssize_t write(const char *ptr, size_t size) = 0;
  699. virtual void get_remote_ip_and_port(std::string &ip, int &port) const = 0;
  700. virtual void get_local_ip_and_port(std::string &ip, int &port) const = 0;
  701. virtual socket_t socket() const = 0;
  702. virtual time_t duration() const = 0;
  703. ssize_t write(const char *ptr);
  704. ssize_t write(const std::string &s);
  705. };
  706. class TaskQueue {
  707. public:
  708. TaskQueue() = default;
  709. virtual ~TaskQueue() = default;
  710. virtual bool enqueue(std::function<void()> fn) = 0;
  711. virtual void shutdown() = 0;
  712. virtual void on_idle() {}
  713. };
  714. class ThreadPool final : public TaskQueue {
  715. public:
  716. explicit ThreadPool(size_t n, size_t mqr = 0)
  717. : shutdown_(false), max_queued_requests_(mqr) {
  718. while (n) {
  719. threads_.emplace_back(worker(*this));
  720. n--;
  721. }
  722. }
  723. ThreadPool(const ThreadPool &) = delete;
  724. ~ThreadPool() override = default;
  725. bool enqueue(std::function<void()> fn) override {
  726. {
  727. std::unique_lock<std::mutex> lock(mutex_);
  728. if (max_queued_requests_ > 0 && jobs_.size() >= max_queued_requests_) {
  729. return false;
  730. }
  731. jobs_.push_back(std::move(fn));
  732. }
  733. cond_.notify_one();
  734. return true;
  735. }
  736. void shutdown() override {
  737. // Stop all worker threads...
  738. {
  739. std::unique_lock<std::mutex> lock(mutex_);
  740. shutdown_ = true;
  741. }
  742. cond_.notify_all();
  743. // Join...
  744. for (auto &t : threads_) {
  745. t.join();
  746. }
  747. }
  748. private:
  749. struct worker {
  750. explicit worker(ThreadPool &pool) : pool_(pool) {}
  751. void operator()() {
  752. for (;;) {
  753. std::function<void()> fn;
  754. {
  755. std::unique_lock<std::mutex> lock(pool_.mutex_);
  756. pool_.cond_.wait(
  757. lock, [&] { return !pool_.jobs_.empty() || pool_.shutdown_; });
  758. if (pool_.shutdown_ && pool_.jobs_.empty()) { break; }
  759. fn = pool_.jobs_.front();
  760. pool_.jobs_.pop_front();
  761. }
  762. assert(true == static_cast<bool>(fn));
  763. fn();
  764. }
  765. #if defined(CPPHTTPLIB_OPENSSL_SUPPORT) && !defined(OPENSSL_IS_BORINGSSL) && \
  766. !defined(LIBRESSL_VERSION_NUMBER)
  767. OPENSSL_thread_stop();
  768. #endif
  769. }
  770. ThreadPool &pool_;
  771. };
  772. friend struct worker;
  773. std::vector<std::thread> threads_;
  774. std::list<std::function<void()>> jobs_;
  775. bool shutdown_;
  776. size_t max_queued_requests_ = 0;
  777. std::condition_variable cond_;
  778. std::mutex mutex_;
  779. };
  780. using Logger = std::function<void(const Request &, const Response &)>;
  781. // Forward declaration for Error type
  782. enum class Error;
  783. using ErrorLogger = std::function<void(const Error &, const Request *)>;
  784. using SocketOptions = std::function<void(socket_t sock)>;
  785. namespace detail {
  786. bool set_socket_opt_impl(socket_t sock, int level, int optname,
  787. const void *optval, socklen_t optlen);
  788. bool set_socket_opt(socket_t sock, int level, int optname, int opt);
  789. bool set_socket_opt_time(socket_t sock, int level, int optname, time_t sec,
  790. time_t usec);
  791. } // namespace detail
  792. void default_socket_options(socket_t sock);
  793. const char *status_message(int status);
  794. std::string get_bearer_token_auth(const Request &req);
  795. namespace detail {
  796. class MatcherBase {
  797. public:
  798. MatcherBase(std::string pattern) : pattern_(pattern) {}
  799. virtual ~MatcherBase() = default;
  800. const std::string &pattern() const { return pattern_; }
  801. // Match request path and populate its matches and
  802. virtual bool match(Request &request) const = 0;
  803. private:
  804. std::string pattern_;
  805. };
  806. /**
  807. * Captures parameters in request path and stores them in Request::path_params
  808. *
  809. * Capture name is a substring of a pattern from : to /.
  810. * The rest of the pattern is matched against the request path directly
  811. * Parameters are captured starting from the next character after
  812. * the end of the last matched static pattern fragment until the next /.
  813. *
  814. * Example pattern:
  815. * "/path/fragments/:capture/more/fragments/:second_capture"
  816. * Static fragments:
  817. * "/path/fragments/", "more/fragments/"
  818. *
  819. * Given the following request path:
  820. * "/path/fragments/:1/more/fragments/:2"
  821. * the resulting capture will be
  822. * {{"capture", "1"}, {"second_capture", "2"}}
  823. */
  824. class PathParamsMatcher final : public MatcherBase {
  825. public:
  826. PathParamsMatcher(const std::string &pattern);
  827. bool match(Request &request) const override;
  828. private:
  829. // Treat segment separators as the end of path parameter capture
  830. // Does not need to handle query parameters as they are parsed before path
  831. // matching
  832. static constexpr char separator = '/';
  833. // Contains static path fragments to match against, excluding the '/' after
  834. // path params
  835. // Fragments are separated by path params
  836. std::vector<std::string> static_fragments_;
  837. // Stores the names of the path parameters to be used as keys in the
  838. // Request::path_params map
  839. std::vector<std::string> param_names_;
  840. };
  841. /**
  842. * Performs std::regex_match on request path
  843. * and stores the result in Request::matches
  844. *
  845. * Note that regex match is performed directly on the whole request.
  846. * This means that wildcard patterns may match multiple path segments with /:
  847. * "/begin/(.*)/end" will match both "/begin/middle/end" and "/begin/1/2/end".
  848. */
  849. class RegexMatcher final : public MatcherBase {
  850. public:
  851. RegexMatcher(const std::string &pattern)
  852. : MatcherBase(pattern), regex_(pattern) {}
  853. bool match(Request &request) const override;
  854. private:
  855. std::regex regex_;
  856. };
  857. ssize_t write_headers(Stream &strm, const Headers &headers);
  858. std::string make_host_and_port_string(const std::string &host, int port,
  859. bool is_ssl);
  860. } // namespace detail
  861. class Server {
  862. public:
  863. using Handler = std::function<void(const Request &, Response &)>;
  864. using ExceptionHandler =
  865. std::function<void(const Request &, Response &, std::exception_ptr ep)>;
  866. enum class HandlerResponse {
  867. Handled,
  868. Unhandled,
  869. };
  870. using HandlerWithResponse =
  871. std::function<HandlerResponse(const Request &, Response &)>;
  872. using HandlerWithContentReader = std::function<void(
  873. const Request &, Response &, const ContentReader &content_reader)>;
  874. using Expect100ContinueHandler =
  875. std::function<int(const Request &, Response &)>;
  876. Server();
  877. virtual ~Server();
  878. virtual bool is_valid() const;
  879. Server &Get(const std::string &pattern, Handler handler);
  880. Server &Post(const std::string &pattern, Handler handler);
  881. Server &Post(const std::string &pattern, HandlerWithContentReader handler);
  882. Server &Put(const std::string &pattern, Handler handler);
  883. Server &Put(const std::string &pattern, HandlerWithContentReader handler);
  884. Server &Patch(const std::string &pattern, Handler handler);
  885. Server &Patch(const std::string &pattern, HandlerWithContentReader handler);
  886. Server &Delete(const std::string &pattern, Handler handler);
  887. Server &Delete(const std::string &pattern, HandlerWithContentReader handler);
  888. Server &Options(const std::string &pattern, Handler handler);
  889. bool set_base_dir(const std::string &dir,
  890. const std::string &mount_point = std::string());
  891. bool set_mount_point(const std::string &mount_point, const std::string &dir,
  892. Headers headers = Headers());
  893. bool remove_mount_point(const std::string &mount_point);
  894. Server &set_file_extension_and_mimetype_mapping(const std::string &ext,
  895. const std::string &mime);
  896. Server &set_default_file_mimetype(const std::string &mime);
  897. Server &set_file_request_handler(Handler handler);
  898. template <class ErrorHandlerFunc>
  899. Server &set_error_handler(ErrorHandlerFunc &&handler) {
  900. return set_error_handler_core(
  901. std::forward<ErrorHandlerFunc>(handler),
  902. std::is_convertible<ErrorHandlerFunc, HandlerWithResponse>{});
  903. }
  904. Server &set_exception_handler(ExceptionHandler handler);
  905. Server &set_pre_routing_handler(HandlerWithResponse handler);
  906. Server &set_post_routing_handler(Handler handler);
  907. Server &set_pre_request_handler(HandlerWithResponse handler);
  908. Server &set_expect_100_continue_handler(Expect100ContinueHandler handler);
  909. Server &set_logger(Logger logger);
  910. Server &set_pre_compression_logger(Logger logger);
  911. Server &set_error_logger(ErrorLogger error_logger);
  912. Server &set_address_family(int family);
  913. Server &set_tcp_nodelay(bool on);
  914. Server &set_ipv6_v6only(bool on);
  915. Server &set_socket_options(SocketOptions socket_options);
  916. Server &set_default_headers(Headers headers);
  917. Server &
  918. set_header_writer(std::function<ssize_t(Stream &, Headers &)> const &writer);
  919. Server &set_trusted_proxies(const std::vector<std::string> &proxies);
  920. Server &set_keep_alive_max_count(size_t count);
  921. Server &set_keep_alive_timeout(time_t sec);
  922. Server &set_read_timeout(time_t sec, time_t usec = 0);
  923. template <class Rep, class Period>
  924. Server &set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
  925. Server &set_write_timeout(time_t sec, time_t usec = 0);
  926. template <class Rep, class Period>
  927. Server &set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
  928. Server &set_idle_interval(time_t sec, time_t usec = 0);
  929. template <class Rep, class Period>
  930. Server &set_idle_interval(const std::chrono::duration<Rep, Period> &duration);
  931. Server &set_payload_max_length(size_t length);
  932. bool bind_to_port(const std::string &host, int port, int socket_flags = 0);
  933. int bind_to_any_port(const std::string &host, int socket_flags = 0);
  934. bool listen_after_bind();
  935. bool listen(const std::string &host, int port, int socket_flags = 0);
  936. bool is_running() const;
  937. void wait_until_ready() const;
  938. void stop();
  939. void decommission();
  940. std::function<TaskQueue *(void)> new_task_queue;
  941. protected:
  942. bool process_request(Stream &strm, const std::string &remote_addr,
  943. int remote_port, const std::string &local_addr,
  944. int local_port, bool close_connection,
  945. bool &connection_closed,
  946. const std::function<void(Request &)> &setup_request);
  947. std::atomic<socket_t> svr_sock_{INVALID_SOCKET};
  948. std::vector<std::string> trusted_proxies_;
  949. size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT;
  950. time_t keep_alive_timeout_sec_ = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND;
  951. time_t read_timeout_sec_ = CPPHTTPLIB_SERVER_READ_TIMEOUT_SECOND;
  952. time_t read_timeout_usec_ = CPPHTTPLIB_SERVER_READ_TIMEOUT_USECOND;
  953. time_t write_timeout_sec_ = CPPHTTPLIB_SERVER_WRITE_TIMEOUT_SECOND;
  954. time_t write_timeout_usec_ = CPPHTTPLIB_SERVER_WRITE_TIMEOUT_USECOND;
  955. time_t idle_interval_sec_ = CPPHTTPLIB_IDLE_INTERVAL_SECOND;
  956. time_t idle_interval_usec_ = CPPHTTPLIB_IDLE_INTERVAL_USECOND;
  957. size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH;
  958. private:
  959. using Handlers =
  960. std::vector<std::pair<std::unique_ptr<detail::MatcherBase>, Handler>>;
  961. using HandlersForContentReader =
  962. std::vector<std::pair<std::unique_ptr<detail::MatcherBase>,
  963. HandlerWithContentReader>>;
  964. static std::unique_ptr<detail::MatcherBase>
  965. make_matcher(const std::string &pattern);
  966. Server &set_error_handler_core(HandlerWithResponse handler, std::true_type);
  967. Server &set_error_handler_core(Handler handler, std::false_type);
  968. socket_t create_server_socket(const std::string &host, int port,
  969. int socket_flags,
  970. SocketOptions socket_options) const;
  971. int bind_internal(const std::string &host, int port, int socket_flags);
  972. bool listen_internal();
  973. bool routing(Request &req, Response &res, Stream &strm);
  974. bool handle_file_request(const Request &req, Response &res);
  975. bool dispatch_request(Request &req, Response &res,
  976. const Handlers &handlers) const;
  977. bool dispatch_request_for_content_reader(
  978. Request &req, Response &res, ContentReader content_reader,
  979. const HandlersForContentReader &handlers) const;
  980. bool parse_request_line(const char *s, Request &req) const;
  981. void apply_ranges(const Request &req, Response &res,
  982. std::string &content_type, std::string &boundary) const;
  983. bool write_response(Stream &strm, bool close_connection, Request &req,
  984. Response &res);
  985. bool write_response_with_content(Stream &strm, bool close_connection,
  986. const Request &req, Response &res);
  987. bool write_response_core(Stream &strm, bool close_connection,
  988. const Request &req, Response &res,
  989. bool need_apply_ranges);
  990. bool write_content_with_provider(Stream &strm, const Request &req,
  991. Response &res, const std::string &boundary,
  992. const std::string &content_type);
  993. bool read_content(Stream &strm, Request &req, Response &res);
  994. bool read_content_with_content_receiver(Stream &strm, Request &req,
  995. Response &res,
  996. ContentReceiver receiver,
  997. FormDataHeader multipart_header,
  998. ContentReceiver multipart_receiver);
  999. bool read_content_core(Stream &strm, Request &req, Response &res,
  1000. ContentReceiver receiver,
  1001. FormDataHeader multipart_header,
  1002. ContentReceiver multipart_receiver) const;
  1003. virtual bool process_and_close_socket(socket_t sock);
  1004. void output_log(const Request &req, const Response &res) const;
  1005. void output_pre_compression_log(const Request &req,
  1006. const Response &res) const;
  1007. void output_error_log(const Error &err, const Request *req) const;
  1008. std::atomic<bool> is_running_{false};
  1009. std::atomic<bool> is_decommissioned{false};
  1010. struct MountPointEntry {
  1011. std::string mount_point;
  1012. std::string base_dir;
  1013. Headers headers;
  1014. };
  1015. std::vector<MountPointEntry> base_dirs_;
  1016. std::map<std::string, std::string> file_extension_and_mimetype_map_;
  1017. std::string default_file_mimetype_ = "application/octet-stream";
  1018. Handler file_request_handler_;
  1019. Handlers get_handlers_;
  1020. Handlers post_handlers_;
  1021. HandlersForContentReader post_handlers_for_content_reader_;
  1022. Handlers put_handlers_;
  1023. HandlersForContentReader put_handlers_for_content_reader_;
  1024. Handlers patch_handlers_;
  1025. HandlersForContentReader patch_handlers_for_content_reader_;
  1026. Handlers delete_handlers_;
  1027. HandlersForContentReader delete_handlers_for_content_reader_;
  1028. Handlers options_handlers_;
  1029. HandlerWithResponse error_handler_;
  1030. ExceptionHandler exception_handler_;
  1031. HandlerWithResponse pre_routing_handler_;
  1032. Handler post_routing_handler_;
  1033. HandlerWithResponse pre_request_handler_;
  1034. Expect100ContinueHandler expect_100_continue_handler_;
  1035. mutable std::mutex logger_mutex_;
  1036. Logger logger_;
  1037. Logger pre_compression_logger_;
  1038. ErrorLogger error_logger_;
  1039. int address_family_ = AF_UNSPEC;
  1040. bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
  1041. bool ipv6_v6only_ = CPPHTTPLIB_IPV6_V6ONLY;
  1042. SocketOptions socket_options_ = default_socket_options;
  1043. Headers default_headers_;
  1044. std::function<ssize_t(Stream &, Headers &)> header_writer_ =
  1045. detail::write_headers;
  1046. };
  1047. enum class Error {
  1048. Success = 0,
  1049. Unknown,
  1050. Connection,
  1051. BindIPAddress,
  1052. Read,
  1053. Write,
  1054. ExceedRedirectCount,
  1055. Canceled,
  1056. SSLConnection,
  1057. SSLLoadingCerts,
  1058. SSLServerVerification,
  1059. SSLServerHostnameVerification,
  1060. UnsupportedMultipartBoundaryChars,
  1061. Compression,
  1062. ConnectionTimeout,
  1063. ProxyConnection,
  1064. ResourceExhaustion,
  1065. TooManyFormDataFiles,
  1066. ExceedMaxPayloadSize,
  1067. ExceedUriMaxLength,
  1068. ExceedMaxSocketDescriptorCount,
  1069. InvalidRequestLine,
  1070. InvalidHTTPMethod,
  1071. InvalidHTTPVersion,
  1072. InvalidHeaders,
  1073. MultipartParsing,
  1074. OpenFile,
  1075. Listen,
  1076. GetSockName,
  1077. UnsupportedAddressFamily,
  1078. HTTPParsing,
  1079. InvalidRangeHeader,
  1080. // For internal use only
  1081. SSLPeerCouldBeClosed_,
  1082. };
  1083. std::string to_string(Error error);
  1084. std::ostream &operator<<(std::ostream &os, const Error &obj);
  1085. class Result {
  1086. public:
  1087. Result() = default;
  1088. Result(std::unique_ptr<Response> &&res, Error err,
  1089. Headers &&request_headers = Headers{})
  1090. : res_(std::move(res)), err_(err),
  1091. request_headers_(std::move(request_headers)) {}
  1092. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1093. Result(std::unique_ptr<Response> &&res, Error err, Headers &&request_headers,
  1094. int ssl_error)
  1095. : res_(std::move(res)), err_(err),
  1096. request_headers_(std::move(request_headers)), ssl_error_(ssl_error) {}
  1097. Result(std::unique_ptr<Response> &&res, Error err, Headers &&request_headers,
  1098. int ssl_error, unsigned long ssl_openssl_error)
  1099. : res_(std::move(res)), err_(err),
  1100. request_headers_(std::move(request_headers)), ssl_error_(ssl_error),
  1101. ssl_openssl_error_(ssl_openssl_error) {}
  1102. #endif
  1103. // Response
  1104. operator bool() const { return res_ != nullptr; }
  1105. bool operator==(std::nullptr_t) const { return res_ == nullptr; }
  1106. bool operator!=(std::nullptr_t) const { return res_ != nullptr; }
  1107. const Response &value() const { return *res_; }
  1108. Response &value() { return *res_; }
  1109. const Response &operator*() const { return *res_; }
  1110. Response &operator*() { return *res_; }
  1111. const Response *operator->() const { return res_.get(); }
  1112. Response *operator->() { return res_.get(); }
  1113. // Error
  1114. Error error() const { return err_; }
  1115. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1116. // SSL Error
  1117. int ssl_error() const { return ssl_error_; }
  1118. // OpenSSL Error
  1119. unsigned long ssl_openssl_error() const { return ssl_openssl_error_; }
  1120. #endif
  1121. // Request Headers
  1122. bool has_request_header(const std::string &key) const;
  1123. std::string get_request_header_value(const std::string &key,
  1124. const char *def = "",
  1125. size_t id = 0) const;
  1126. size_t get_request_header_value_u64(const std::string &key, size_t def = 0,
  1127. size_t id = 0) const;
  1128. size_t get_request_header_value_count(const std::string &key) const;
  1129. private:
  1130. std::unique_ptr<Response> res_;
  1131. Error err_ = Error::Unknown;
  1132. Headers request_headers_;
  1133. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1134. int ssl_error_ = 0;
  1135. unsigned long ssl_openssl_error_ = 0;
  1136. #endif
  1137. };
  1138. class ClientImpl {
  1139. public:
  1140. explicit ClientImpl(const std::string &host);
  1141. explicit ClientImpl(const std::string &host, int port);
  1142. explicit ClientImpl(const std::string &host, int port,
  1143. const std::string &client_cert_path,
  1144. const std::string &client_key_path);
  1145. virtual ~ClientImpl();
  1146. virtual bool is_valid() const;
  1147. // clang-format off
  1148. Result Get(const std::string &path, DownloadProgress progress = nullptr);
  1149. Result Get(const std::string &path, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1150. Result Get(const std::string &path, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1151. Result Get(const std::string &path, const Headers &headers, DownloadProgress progress = nullptr);
  1152. Result Get(const std::string &path, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1153. Result Get(const std::string &path, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1154. Result Get(const std::string &path, const Params &params, const Headers &headers, DownloadProgress progress = nullptr);
  1155. Result Get(const std::string &path, const Params &params, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1156. Result Get(const std::string &path, const Params &params, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1157. Result Head(const std::string &path);
  1158. Result Head(const std::string &path, const Headers &headers);
  1159. Result Post(const std::string &path);
  1160. Result Post(const std::string &path, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1161. Result Post(const std::string &path, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1162. Result Post(const std::string &path, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1163. Result Post(const std::string &path, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1164. Result Post(const std::string &path, const Params &params);
  1165. Result Post(const std::string &path, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1166. Result Post(const std::string &path, const Headers &headers);
  1167. Result Post(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1168. Result Post(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1169. Result Post(const std::string &path, const Headers &headers, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1170. Result Post(const std::string &path, const Headers &headers, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1171. Result Post(const std::string &path, const Headers &headers, const Params &params);
  1172. Result Post(const std::string &path, const Headers &headers, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1173. Result Post(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const std::string &boundary, UploadProgress progress = nullptr);
  1174. Result Post(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const FormDataProviderItems &provider_items, UploadProgress progress = nullptr);
  1175. Result Post(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1176. Result Put(const std::string &path);
  1177. Result Put(const std::string &path, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1178. Result Put(const std::string &path, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1179. Result Put(const std::string &path, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1180. Result Put(const std::string &path, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1181. Result Put(const std::string &path, const Params &params);
  1182. Result Put(const std::string &path, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1183. Result Put(const std::string &path, const Headers &headers);
  1184. Result Put(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1185. Result Put(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1186. Result Put(const std::string &path, const Headers &headers, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1187. Result Put(const std::string &path, const Headers &headers, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1188. Result Put(const std::string &path, const Headers &headers, const Params &params);
  1189. Result Put(const std::string &path, const Headers &headers, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1190. Result Put(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const std::string &boundary, UploadProgress progress = nullptr);
  1191. Result Put(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const FormDataProviderItems &provider_items, UploadProgress progress = nullptr);
  1192. Result Put(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1193. Result Patch(const std::string &path);
  1194. Result Patch(const std::string &path, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1195. Result Patch(const std::string &path, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1196. Result Patch(const std::string &path, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1197. Result Patch(const std::string &path, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1198. Result Patch(const std::string &path, const Params &params);
  1199. Result Patch(const std::string &path, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1200. Result Patch(const std::string &path, const Headers &headers, UploadProgress progress = nullptr);
  1201. Result Patch(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1202. Result Patch(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1203. Result Patch(const std::string &path, const Headers &headers, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1204. Result Patch(const std::string &path, const Headers &headers, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1205. Result Patch(const std::string &path, const Headers &headers, const Params &params);
  1206. Result Patch(const std::string &path, const Headers &headers, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1207. Result Patch(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const std::string &boundary, UploadProgress progress = nullptr);
  1208. Result Patch(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const FormDataProviderItems &provider_items, UploadProgress progress = nullptr);
  1209. Result Patch(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1210. Result Delete(const std::string &path, DownloadProgress progress = nullptr);
  1211. Result Delete(const std::string &path, const char *body, size_t content_length, const std::string &content_type, DownloadProgress progress = nullptr);
  1212. Result Delete(const std::string &path, const std::string &body, const std::string &content_type, DownloadProgress progress = nullptr);
  1213. Result Delete(const std::string &path, const Params &params, DownloadProgress progress = nullptr);
  1214. Result Delete(const std::string &path, const Headers &headers, DownloadProgress progress = nullptr);
  1215. Result Delete(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, DownloadProgress progress = nullptr);
  1216. Result Delete(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, DownloadProgress progress = nullptr);
  1217. Result Delete(const std::string &path, const Headers &headers, const Params &params, DownloadProgress progress = nullptr);
  1218. Result Options(const std::string &path);
  1219. Result Options(const std::string &path, const Headers &headers);
  1220. // clang-format on
  1221. bool send(Request &req, Response &res, Error &error);
  1222. Result send(const Request &req);
  1223. void stop();
  1224. std::string host() const;
  1225. int port() const;
  1226. size_t is_socket_open() const;
  1227. socket_t socket() const;
  1228. void set_hostname_addr_map(std::map<std::string, std::string> addr_map);
  1229. void set_default_headers(Headers headers);
  1230. void
  1231. set_header_writer(std::function<ssize_t(Stream &, Headers &)> const &writer);
  1232. void set_address_family(int family);
  1233. void set_tcp_nodelay(bool on);
  1234. void set_ipv6_v6only(bool on);
  1235. void set_socket_options(SocketOptions socket_options);
  1236. void set_connection_timeout(time_t sec, time_t usec = 0);
  1237. template <class Rep, class Period>
  1238. void
  1239. set_connection_timeout(const std::chrono::duration<Rep, Period> &duration);
  1240. void set_read_timeout(time_t sec, time_t usec = 0);
  1241. template <class Rep, class Period>
  1242. void set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
  1243. void set_write_timeout(time_t sec, time_t usec = 0);
  1244. template <class Rep, class Period>
  1245. void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
  1246. void set_max_timeout(time_t msec);
  1247. template <class Rep, class Period>
  1248. void set_max_timeout(const std::chrono::duration<Rep, Period> &duration);
  1249. void set_basic_auth(const std::string &username, const std::string &password);
  1250. void set_bearer_token_auth(const std::string &token);
  1251. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1252. void set_digest_auth(const std::string &username,
  1253. const std::string &password);
  1254. #endif
  1255. void set_keep_alive(bool on);
  1256. void set_follow_location(bool on);
  1257. void set_path_encode(bool on);
  1258. void set_compress(bool on);
  1259. void set_decompress(bool on);
  1260. void set_interface(const std::string &intf);
  1261. void set_proxy(const std::string &host, int port);
  1262. void set_proxy_basic_auth(const std::string &username,
  1263. const std::string &password);
  1264. void set_proxy_bearer_token_auth(const std::string &token);
  1265. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1266. void set_proxy_digest_auth(const std::string &username,
  1267. const std::string &password);
  1268. #endif
  1269. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1270. void set_ca_cert_path(const std::string &ca_cert_file_path,
  1271. const std::string &ca_cert_dir_path = std::string());
  1272. void set_ca_cert_store(X509_STORE *ca_cert_store);
  1273. X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size) const;
  1274. #endif
  1275. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1276. void enable_server_certificate_verification(bool enabled);
  1277. void enable_server_hostname_verification(bool enabled);
  1278. void set_server_certificate_verifier(
  1279. std::function<SSLVerifierResponse(SSL *ssl)> verifier);
  1280. #endif
  1281. void set_logger(Logger logger);
  1282. void set_error_logger(ErrorLogger error_logger);
  1283. protected:
  1284. struct Socket {
  1285. socket_t sock = INVALID_SOCKET;
  1286. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1287. SSL *ssl = nullptr;
  1288. #endif
  1289. bool is_open() const { return sock != INVALID_SOCKET; }
  1290. };
  1291. virtual bool create_and_connect_socket(Socket &socket, Error &error);
  1292. // All of:
  1293. // shutdown_ssl
  1294. // shutdown_socket
  1295. // close_socket
  1296. // should ONLY be called when socket_mutex_ is locked.
  1297. // Also, shutdown_ssl and close_socket should also NOT be called concurrently
  1298. // with a DIFFERENT thread sending requests using that socket.
  1299. virtual void shutdown_ssl(Socket &socket, bool shutdown_gracefully);
  1300. void shutdown_socket(Socket &socket) const;
  1301. void close_socket(Socket &socket);
  1302. bool process_request(Stream &strm, Request &req, Response &res,
  1303. bool close_connection, Error &error);
  1304. bool write_content_with_provider(Stream &strm, const Request &req,
  1305. Error &error) const;
  1306. void copy_settings(const ClientImpl &rhs);
  1307. void output_log(const Request &req, const Response &res) const;
  1308. void output_error_log(const Error &err, const Request *req) const;
  1309. // Socket endpoint information
  1310. const std::string host_;
  1311. const int port_;
  1312. const std::string host_and_port_;
  1313. // Current open socket
  1314. Socket socket_;
  1315. mutable std::mutex socket_mutex_;
  1316. std::recursive_mutex request_mutex_;
  1317. // These are all protected under socket_mutex
  1318. size_t socket_requests_in_flight_ = 0;
  1319. std::thread::id socket_requests_are_from_thread_ = std::thread::id();
  1320. bool socket_should_be_closed_when_request_is_done_ = false;
  1321. // Hostname-IP map
  1322. std::map<std::string, std::string> addr_map_;
  1323. // Default headers
  1324. Headers default_headers_;
  1325. // Header writer
  1326. std::function<ssize_t(Stream &, Headers &)> header_writer_ =
  1327. detail::write_headers;
  1328. // Settings
  1329. std::string client_cert_path_;
  1330. std::string client_key_path_;
  1331. time_t connection_timeout_sec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND;
  1332. time_t connection_timeout_usec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND;
  1333. time_t read_timeout_sec_ = CPPHTTPLIB_CLIENT_READ_TIMEOUT_SECOND;
  1334. time_t read_timeout_usec_ = CPPHTTPLIB_CLIENT_READ_TIMEOUT_USECOND;
  1335. time_t write_timeout_sec_ = CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_SECOND;
  1336. time_t write_timeout_usec_ = CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_USECOND;
  1337. time_t max_timeout_msec_ = CPPHTTPLIB_CLIENT_MAX_TIMEOUT_MSECOND;
  1338. std::string basic_auth_username_;
  1339. std::string basic_auth_password_;
  1340. std::string bearer_token_auth_token_;
  1341. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1342. std::string digest_auth_username_;
  1343. std::string digest_auth_password_;
  1344. #endif
  1345. bool keep_alive_ = false;
  1346. bool follow_location_ = false;
  1347. bool path_encode_ = true;
  1348. int address_family_ = AF_UNSPEC;
  1349. bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
  1350. bool ipv6_v6only_ = CPPHTTPLIB_IPV6_V6ONLY;
  1351. SocketOptions socket_options_ = nullptr;
  1352. bool compress_ = false;
  1353. bool decompress_ = true;
  1354. std::string interface_;
  1355. std::string proxy_host_;
  1356. int proxy_port_ = -1;
  1357. std::string proxy_basic_auth_username_;
  1358. std::string proxy_basic_auth_password_;
  1359. std::string proxy_bearer_token_auth_token_;
  1360. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1361. std::string proxy_digest_auth_username_;
  1362. std::string proxy_digest_auth_password_;
  1363. #endif
  1364. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1365. std::string ca_cert_file_path_;
  1366. std::string ca_cert_dir_path_;
  1367. X509_STORE *ca_cert_store_ = nullptr;
  1368. #endif
  1369. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1370. bool server_certificate_verification_ = true;
  1371. bool server_hostname_verification_ = true;
  1372. std::function<SSLVerifierResponse(SSL *ssl)> server_certificate_verifier_;
  1373. #endif
  1374. mutable std::mutex logger_mutex_;
  1375. Logger logger_;
  1376. ErrorLogger error_logger_;
  1377. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1378. int last_ssl_error_ = 0;
  1379. unsigned long last_openssl_error_ = 0;
  1380. #endif
  1381. private:
  1382. bool send_(Request &req, Response &res, Error &error);
  1383. Result send_(Request &&req);
  1384. socket_t create_client_socket(Error &error) const;
  1385. bool read_response_line(Stream &strm, const Request &req,
  1386. Response &res) const;
  1387. bool write_request(Stream &strm, Request &req, bool close_connection,
  1388. Error &error);
  1389. bool redirect(Request &req, Response &res, Error &error);
  1390. bool create_redirect_client(const std::string &scheme,
  1391. const std::string &host, int port, Request &req,
  1392. Response &res, const std::string &path,
  1393. const std::string &location, Error &error);
  1394. template <typename ClientType> void setup_redirect_client(ClientType &client);
  1395. bool handle_request(Stream &strm, Request &req, Response &res,
  1396. bool close_connection, Error &error);
  1397. std::unique_ptr<Response> send_with_content_provider(
  1398. Request &req, const char *body, size_t content_length,
  1399. ContentProvider content_provider,
  1400. ContentProviderWithoutLength content_provider_without_length,
  1401. const std::string &content_type, Error &error);
  1402. Result send_with_content_provider(
  1403. const std::string &method, const std::string &path,
  1404. const Headers &headers, const char *body, size_t content_length,
  1405. ContentProvider content_provider,
  1406. ContentProviderWithoutLength content_provider_without_length,
  1407. const std::string &content_type, UploadProgress progress);
  1408. ContentProviderWithoutLength get_multipart_content_provider(
  1409. const std::string &boundary, const UploadFormDataItems &items,
  1410. const FormDataProviderItems &provider_items) const;
  1411. virtual bool
  1412. process_socket(const Socket &socket,
  1413. std::chrono::time_point<std::chrono::steady_clock> start_time,
  1414. std::function<bool(Stream &strm)> callback);
  1415. virtual bool is_ssl() const;
  1416. };
  1417. class Client {
  1418. public:
  1419. // Universal interface
  1420. explicit Client(const std::string &scheme_host_port);
  1421. explicit Client(const std::string &scheme_host_port,
  1422. const std::string &client_cert_path,
  1423. const std::string &client_key_path);
  1424. // HTTP only interface
  1425. explicit Client(const std::string &host, int port);
  1426. explicit Client(const std::string &host, int port,
  1427. const std::string &client_cert_path,
  1428. const std::string &client_key_path);
  1429. Client(Client &&) = default;
  1430. Client &operator=(Client &&) = default;
  1431. ~Client();
  1432. bool is_valid() const;
  1433. // clang-format off
  1434. Result Get(const std::string &path, DownloadProgress progress = nullptr);
  1435. Result Get(const std::string &path, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1436. Result Get(const std::string &path, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1437. Result Get(const std::string &path, const Headers &headers, DownloadProgress progress = nullptr);
  1438. Result Get(const std::string &path, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1439. Result Get(const std::string &path, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1440. Result Get(const std::string &path, const Params &params, const Headers &headers, DownloadProgress progress = nullptr);
  1441. Result Get(const std::string &path, const Params &params, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1442. Result Get(const std::string &path, const Params &params, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1443. Result Head(const std::string &path);
  1444. Result Head(const std::string &path, const Headers &headers);
  1445. Result Post(const std::string &path);
  1446. Result Post(const std::string &path, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1447. Result Post(const std::string &path, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1448. Result Post(const std::string &path, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1449. Result Post(const std::string &path, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1450. Result Post(const std::string &path, const Params &params);
  1451. Result Post(const std::string &path, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1452. Result Post(const std::string &path, const Headers &headers);
  1453. Result Post(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1454. Result Post(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1455. Result Post(const std::string &path, const Headers &headers, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1456. Result Post(const std::string &path, const Headers &headers, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1457. Result Post(const std::string &path, const Headers &headers, const Params &params);
  1458. Result Post(const std::string &path, const Headers &headers, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1459. Result Post(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const std::string &boundary, UploadProgress progress = nullptr);
  1460. Result Post(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const FormDataProviderItems &provider_items, UploadProgress progress = nullptr);
  1461. Result Post(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1462. Result Put(const std::string &path);
  1463. Result Put(const std::string &path, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1464. Result Put(const std::string &path, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1465. Result Put(const std::string &path, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1466. Result Put(const std::string &path, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1467. Result Put(const std::string &path, const Params &params);
  1468. Result Put(const std::string &path, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1469. Result Put(const std::string &path, const Headers &headers);
  1470. Result Put(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1471. Result Put(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1472. Result Put(const std::string &path, const Headers &headers, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1473. Result Put(const std::string &path, const Headers &headers, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1474. Result Put(const std::string &path, const Headers &headers, const Params &params);
  1475. Result Put(const std::string &path, const Headers &headers, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1476. Result Put(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const std::string &boundary, UploadProgress progress = nullptr);
  1477. Result Put(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const FormDataProviderItems &provider_items, UploadProgress progress = nullptr);
  1478. Result Put(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1479. Result Patch(const std::string &path);
  1480. Result Patch(const std::string &path, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1481. Result Patch(const std::string &path, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1482. Result Patch(const std::string &path, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1483. Result Patch(const std::string &path, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1484. Result Patch(const std::string &path, const Params &params);
  1485. Result Patch(const std::string &path, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1486. Result Patch(const std::string &path, const Headers &headers);
  1487. Result Patch(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, UploadProgress progress = nullptr);
  1488. Result Patch(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, UploadProgress progress = nullptr);
  1489. Result Patch(const std::string &path, const Headers &headers, size_t content_length, ContentProvider content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1490. Result Patch(const std::string &path, const Headers &headers, ContentProviderWithoutLength content_provider, const std::string &content_type, UploadProgress progress = nullptr);
  1491. Result Patch(const std::string &path, const Headers &headers, const Params &params);
  1492. Result Patch(const std::string &path, const Headers &headers, const UploadFormDataItems &items, UploadProgress progress = nullptr);
  1493. Result Patch(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const std::string &boundary, UploadProgress progress = nullptr);
  1494. Result Patch(const std::string &path, const Headers &headers, const UploadFormDataItems &items, const FormDataProviderItems &provider_items, UploadProgress progress = nullptr);
  1495. Result Patch(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, ContentReceiver content_receiver, DownloadProgress progress = nullptr);
  1496. Result Delete(const std::string &path, DownloadProgress progress = nullptr);
  1497. Result Delete(const std::string &path, const char *body, size_t content_length, const std::string &content_type, DownloadProgress progress = nullptr);
  1498. Result Delete(const std::string &path, const std::string &body, const std::string &content_type, DownloadProgress progress = nullptr);
  1499. Result Delete(const std::string &path, const Params &params, DownloadProgress progress = nullptr);
  1500. Result Delete(const std::string &path, const Headers &headers, DownloadProgress progress = nullptr);
  1501. Result Delete(const std::string &path, const Headers &headers, const char *body, size_t content_length, const std::string &content_type, DownloadProgress progress = nullptr);
  1502. Result Delete(const std::string &path, const Headers &headers, const std::string &body, const std::string &content_type, DownloadProgress progress = nullptr);
  1503. Result Delete(const std::string &path, const Headers &headers, const Params &params, DownloadProgress progress = nullptr);
  1504. Result Options(const std::string &path);
  1505. Result Options(const std::string &path, const Headers &headers);
  1506. // clang-format on
  1507. bool send(Request &req, Response &res, Error &error);
  1508. Result send(const Request &req);
  1509. void stop();
  1510. std::string host() const;
  1511. int port() const;
  1512. size_t is_socket_open() const;
  1513. socket_t socket() const;
  1514. void set_hostname_addr_map(std::map<std::string, std::string> addr_map);
  1515. void set_default_headers(Headers headers);
  1516. void
  1517. set_header_writer(std::function<ssize_t(Stream &, Headers &)> const &writer);
  1518. void set_address_family(int family);
  1519. void set_tcp_nodelay(bool on);
  1520. void set_socket_options(SocketOptions socket_options);
  1521. void set_connection_timeout(time_t sec, time_t usec = 0);
  1522. template <class Rep, class Period>
  1523. void
  1524. set_connection_timeout(const std::chrono::duration<Rep, Period> &duration);
  1525. void set_read_timeout(time_t sec, time_t usec = 0);
  1526. template <class Rep, class Period>
  1527. void set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
  1528. void set_write_timeout(time_t sec, time_t usec = 0);
  1529. template <class Rep, class Period>
  1530. void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
  1531. void set_max_timeout(time_t msec);
  1532. template <class Rep, class Period>
  1533. void set_max_timeout(const std::chrono::duration<Rep, Period> &duration);
  1534. void set_basic_auth(const std::string &username, const std::string &password);
  1535. void set_bearer_token_auth(const std::string &token);
  1536. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1537. void set_digest_auth(const std::string &username,
  1538. const std::string &password);
  1539. #endif
  1540. void set_keep_alive(bool on);
  1541. void set_follow_location(bool on);
  1542. void set_path_encode(bool on);
  1543. void set_url_encode(bool on);
  1544. void set_compress(bool on);
  1545. void set_decompress(bool on);
  1546. void set_interface(const std::string &intf);
  1547. void set_proxy(const std::string &host, int port);
  1548. void set_proxy_basic_auth(const std::string &username,
  1549. const std::string &password);
  1550. void set_proxy_bearer_token_auth(const std::string &token);
  1551. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1552. void set_proxy_digest_auth(const std::string &username,
  1553. const std::string &password);
  1554. #endif
  1555. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1556. void enable_server_certificate_verification(bool enabled);
  1557. void enable_server_hostname_verification(bool enabled);
  1558. void set_server_certificate_verifier(
  1559. std::function<SSLVerifierResponse(SSL *ssl)> verifier);
  1560. #endif
  1561. void set_logger(Logger logger);
  1562. void set_error_logger(ErrorLogger error_logger);
  1563. // SSL
  1564. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1565. void set_ca_cert_path(const std::string &ca_cert_file_path,
  1566. const std::string &ca_cert_dir_path = std::string());
  1567. void set_ca_cert_store(X509_STORE *ca_cert_store);
  1568. void load_ca_cert_store(const char *ca_cert, std::size_t size);
  1569. long get_openssl_verify_result() const;
  1570. SSL_CTX *ssl_context() const;
  1571. #endif
  1572. private:
  1573. std::unique_ptr<ClientImpl> cli_;
  1574. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1575. bool is_ssl_ = false;
  1576. #endif
  1577. };
  1578. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  1579. class SSLServer : public Server {
  1580. public:
  1581. SSLServer(const char *cert_path, const char *private_key_path,
  1582. const char *client_ca_cert_file_path = nullptr,
  1583. const char *client_ca_cert_dir_path = nullptr,
  1584. const char *private_key_password = nullptr);
  1585. SSLServer(X509 *cert, EVP_PKEY *private_key,
  1586. X509_STORE *client_ca_cert_store = nullptr);
  1587. SSLServer(
  1588. const std::function<bool(SSL_CTX &ssl_ctx)> &setup_ssl_ctx_callback);
  1589. ~SSLServer() override;
  1590. bool is_valid() const override;
  1591. SSL_CTX *ssl_context() const;
  1592. void update_certs(X509 *cert, EVP_PKEY *private_key,
  1593. X509_STORE *client_ca_cert_store = nullptr);
  1594. int ssl_last_error() const { return last_ssl_error_; }
  1595. private:
  1596. bool process_and_close_socket(socket_t sock) override;
  1597. STACK_OF(X509_NAME) * extract_ca_names_from_x509_store(X509_STORE *store);
  1598. SSL_CTX *ctx_;
  1599. std::mutex ctx_mutex_;
  1600. int last_ssl_error_ = 0;
  1601. };
  1602. class SSLClient final : public ClientImpl {
  1603. public:
  1604. explicit SSLClient(const std::string &host);
  1605. explicit SSLClient(const std::string &host, int port);
  1606. explicit SSLClient(const std::string &host, int port,
  1607. const std::string &client_cert_path,
  1608. const std::string &client_key_path,
  1609. const std::string &private_key_password = std::string());
  1610. explicit SSLClient(const std::string &host, int port, X509 *client_cert,
  1611. EVP_PKEY *client_key,
  1612. const std::string &private_key_password = std::string());
  1613. ~SSLClient() override;
  1614. bool is_valid() const override;
  1615. void set_ca_cert_store(X509_STORE *ca_cert_store);
  1616. void load_ca_cert_store(const char *ca_cert, std::size_t size);
  1617. long get_openssl_verify_result() const;
  1618. SSL_CTX *ssl_context() const;
  1619. private:
  1620. bool create_and_connect_socket(Socket &socket, Error &error) override;
  1621. void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override;
  1622. void shutdown_ssl_impl(Socket &socket, bool shutdown_gracefully);
  1623. bool
  1624. process_socket(const Socket &socket,
  1625. std::chrono::time_point<std::chrono::steady_clock> start_time,
  1626. std::function<bool(Stream &strm)> callback) override;
  1627. bool is_ssl() const override;
  1628. bool connect_with_proxy(
  1629. Socket &sock,
  1630. std::chrono::time_point<std::chrono::steady_clock> start_time,
  1631. Response &res, bool &success, Error &error);
  1632. bool initialize_ssl(Socket &socket, Error &error);
  1633. bool load_certs();
  1634. bool verify_host(X509 *server_cert) const;
  1635. bool verify_host_with_subject_alt_name(X509 *server_cert) const;
  1636. bool verify_host_with_common_name(X509 *server_cert) const;
  1637. bool check_host_name(const char *pattern, size_t pattern_len) const;
  1638. SSL_CTX *ctx_;
  1639. std::mutex ctx_mutex_;
  1640. std::once_flag initialize_cert_;
  1641. std::vector<std::string> host_components_;
  1642. long verify_result_ = 0;
  1643. friend class ClientImpl;
  1644. };
  1645. #endif
  1646. /*
  1647. * Implementation of template methods.
  1648. */
  1649. namespace detail {
  1650. template <typename T, typename U>
  1651. inline void duration_to_sec_and_usec(const T &duration, U callback) {
  1652. auto sec = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
  1653. auto usec = std::chrono::duration_cast<std::chrono::microseconds>(
  1654. duration - std::chrono::seconds(sec))
  1655. .count();
  1656. callback(static_cast<time_t>(sec), static_cast<time_t>(usec));
  1657. }
  1658. template <size_t N> inline constexpr size_t str_len(const char (&)[N]) {
  1659. return N - 1;
  1660. }
  1661. inline bool is_numeric(const std::string &str) {
  1662. return !str.empty() &&
  1663. std::all_of(str.cbegin(), str.cend(),
  1664. [](unsigned char c) { return std::isdigit(c); });
  1665. }
  1666. inline size_t get_header_value_u64(const Headers &headers,
  1667. const std::string &key, size_t def,
  1668. size_t id, bool &is_invalid_value) {
  1669. is_invalid_value = false;
  1670. auto rng = headers.equal_range(key);
  1671. auto it = rng.first;
  1672. std::advance(it, static_cast<ssize_t>(id));
  1673. if (it != rng.second) {
  1674. if (is_numeric(it->second)) {
  1675. return std::strtoull(it->second.data(), nullptr, 10);
  1676. } else {
  1677. is_invalid_value = true;
  1678. }
  1679. }
  1680. return def;
  1681. }
  1682. inline size_t get_header_value_u64(const Headers &headers,
  1683. const std::string &key, size_t def,
  1684. size_t id) {
  1685. auto dummy = false;
  1686. return get_header_value_u64(headers, key, def, id, dummy);
  1687. }
  1688. } // namespace detail
  1689. inline size_t Request::get_header_value_u64(const std::string &key, size_t def,
  1690. size_t id) const {
  1691. return detail::get_header_value_u64(headers, key, def, id);
  1692. }
  1693. inline size_t Response::get_header_value_u64(const std::string &key, size_t def,
  1694. size_t id) const {
  1695. return detail::get_header_value_u64(headers, key, def, id);
  1696. }
  1697. namespace detail {
  1698. inline bool set_socket_opt_impl(socket_t sock, int level, int optname,
  1699. const void *optval, socklen_t optlen) {
  1700. return setsockopt(sock, level, optname,
  1701. #ifdef _WIN32
  1702. reinterpret_cast<const char *>(optval),
  1703. #else
  1704. optval,
  1705. #endif
  1706. optlen) == 0;
  1707. }
  1708. inline bool set_socket_opt(socket_t sock, int level, int optname, int optval) {
  1709. return set_socket_opt_impl(sock, level, optname, &optval, sizeof(optval));
  1710. }
  1711. inline bool set_socket_opt_time(socket_t sock, int level, int optname,
  1712. time_t sec, time_t usec) {
  1713. #ifdef _WIN32
  1714. auto timeout = static_cast<uint32_t>(sec * 1000 + usec / 1000);
  1715. #else
  1716. timeval timeout;
  1717. timeout.tv_sec = static_cast<long>(sec);
  1718. timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(usec);
  1719. #endif
  1720. return set_socket_opt_impl(sock, level, optname, &timeout, sizeof(timeout));
  1721. }
  1722. } // namespace detail
  1723. inline void default_socket_options(socket_t sock) {
  1724. detail::set_socket_opt(sock, SOL_SOCKET,
  1725. #ifdef SO_REUSEPORT
  1726. SO_REUSEPORT,
  1727. #else
  1728. SO_REUSEADDR,
  1729. #endif
  1730. 1);
  1731. }
  1732. inline const char *status_message(int status) {
  1733. switch (status) {
  1734. case StatusCode::Continue_100: return "Continue";
  1735. case StatusCode::SwitchingProtocol_101: return "Switching Protocol";
  1736. case StatusCode::Processing_102: return "Processing";
  1737. case StatusCode::EarlyHints_103: return "Early Hints";
  1738. case StatusCode::OK_200: return "OK";
  1739. case StatusCode::Created_201: return "Created";
  1740. case StatusCode::Accepted_202: return "Accepted";
  1741. case StatusCode::NonAuthoritativeInformation_203:
  1742. return "Non-Authoritative Information";
  1743. case StatusCode::NoContent_204: return "No Content";
  1744. case StatusCode::ResetContent_205: return "Reset Content";
  1745. case StatusCode::PartialContent_206: return "Partial Content";
  1746. case StatusCode::MultiStatus_207: return "Multi-Status";
  1747. case StatusCode::AlreadyReported_208: return "Already Reported";
  1748. case StatusCode::IMUsed_226: return "IM Used";
  1749. case StatusCode::MultipleChoices_300: return "Multiple Choices";
  1750. case StatusCode::MovedPermanently_301: return "Moved Permanently";
  1751. case StatusCode::Found_302: return "Found";
  1752. case StatusCode::SeeOther_303: return "See Other";
  1753. case StatusCode::NotModified_304: return "Not Modified";
  1754. case StatusCode::UseProxy_305: return "Use Proxy";
  1755. case StatusCode::unused_306: return "unused";
  1756. case StatusCode::TemporaryRedirect_307: return "Temporary Redirect";
  1757. case StatusCode::PermanentRedirect_308: return "Permanent Redirect";
  1758. case StatusCode::BadRequest_400: return "Bad Request";
  1759. case StatusCode::Unauthorized_401: return "Unauthorized";
  1760. case StatusCode::PaymentRequired_402: return "Payment Required";
  1761. case StatusCode::Forbidden_403: return "Forbidden";
  1762. case StatusCode::NotFound_404: return "Not Found";
  1763. case StatusCode::MethodNotAllowed_405: return "Method Not Allowed";
  1764. case StatusCode::NotAcceptable_406: return "Not Acceptable";
  1765. case StatusCode::ProxyAuthenticationRequired_407:
  1766. return "Proxy Authentication Required";
  1767. case StatusCode::RequestTimeout_408: return "Request Timeout";
  1768. case StatusCode::Conflict_409: return "Conflict";
  1769. case StatusCode::Gone_410: return "Gone";
  1770. case StatusCode::LengthRequired_411: return "Length Required";
  1771. case StatusCode::PreconditionFailed_412: return "Precondition Failed";
  1772. case StatusCode::PayloadTooLarge_413: return "Payload Too Large";
  1773. case StatusCode::UriTooLong_414: return "URI Too Long";
  1774. case StatusCode::UnsupportedMediaType_415: return "Unsupported Media Type";
  1775. case StatusCode::RangeNotSatisfiable_416: return "Range Not Satisfiable";
  1776. case StatusCode::ExpectationFailed_417: return "Expectation Failed";
  1777. case StatusCode::ImATeapot_418: return "I'm a teapot";
  1778. case StatusCode::MisdirectedRequest_421: return "Misdirected Request";
  1779. case StatusCode::UnprocessableContent_422: return "Unprocessable Content";
  1780. case StatusCode::Locked_423: return "Locked";
  1781. case StatusCode::FailedDependency_424: return "Failed Dependency";
  1782. case StatusCode::TooEarly_425: return "Too Early";
  1783. case StatusCode::UpgradeRequired_426: return "Upgrade Required";
  1784. case StatusCode::PreconditionRequired_428: return "Precondition Required";
  1785. case StatusCode::TooManyRequests_429: return "Too Many Requests";
  1786. case StatusCode::RequestHeaderFieldsTooLarge_431:
  1787. return "Request Header Fields Too Large";
  1788. case StatusCode::UnavailableForLegalReasons_451:
  1789. return "Unavailable For Legal Reasons";
  1790. case StatusCode::NotImplemented_501: return "Not Implemented";
  1791. case StatusCode::BadGateway_502: return "Bad Gateway";
  1792. case StatusCode::ServiceUnavailable_503: return "Service Unavailable";
  1793. case StatusCode::GatewayTimeout_504: return "Gateway Timeout";
  1794. case StatusCode::HttpVersionNotSupported_505:
  1795. return "HTTP Version Not Supported";
  1796. case StatusCode::VariantAlsoNegotiates_506: return "Variant Also Negotiates";
  1797. case StatusCode::InsufficientStorage_507: return "Insufficient Storage";
  1798. case StatusCode::LoopDetected_508: return "Loop Detected";
  1799. case StatusCode::NotExtended_510: return "Not Extended";
  1800. case StatusCode::NetworkAuthenticationRequired_511:
  1801. return "Network Authentication Required";
  1802. default:
  1803. case StatusCode::InternalServerError_500: return "Internal Server Error";
  1804. }
  1805. }
  1806. inline std::string get_bearer_token_auth(const Request &req) {
  1807. if (req.has_header("Authorization")) {
  1808. constexpr auto bearer_header_prefix_len = detail::str_len("Bearer ");
  1809. return req.get_header_value("Authorization")
  1810. .substr(bearer_header_prefix_len);
  1811. }
  1812. return "";
  1813. }
  1814. template <class Rep, class Period>
  1815. inline Server &
  1816. Server::set_read_timeout(const std::chrono::duration<Rep, Period> &duration) {
  1817. detail::duration_to_sec_and_usec(
  1818. duration, [&](time_t sec, time_t usec) { set_read_timeout(sec, usec); });
  1819. return *this;
  1820. }
  1821. template <class Rep, class Period>
  1822. inline Server &
  1823. Server::set_write_timeout(const std::chrono::duration<Rep, Period> &duration) {
  1824. detail::duration_to_sec_and_usec(
  1825. duration, [&](time_t sec, time_t usec) { set_write_timeout(sec, usec); });
  1826. return *this;
  1827. }
  1828. template <class Rep, class Period>
  1829. inline Server &
  1830. Server::set_idle_interval(const std::chrono::duration<Rep, Period> &duration) {
  1831. detail::duration_to_sec_and_usec(
  1832. duration, [&](time_t sec, time_t usec) { set_idle_interval(sec, usec); });
  1833. return *this;
  1834. }
  1835. inline std::string to_string(const Error error) {
  1836. switch (error) {
  1837. case Error::Success: return "Success (no error)";
  1838. case Error::Unknown: return "Unknown";
  1839. case Error::Connection: return "Could not establish connection";
  1840. case Error::BindIPAddress: return "Failed to bind IP address";
  1841. case Error::Read: return "Failed to read connection";
  1842. case Error::Write: return "Failed to write connection";
  1843. case Error::ExceedRedirectCount: return "Maximum redirect count exceeded";
  1844. case Error::Canceled: return "Connection handling canceled";
  1845. case Error::SSLConnection: return "SSL connection failed";
  1846. case Error::SSLLoadingCerts: return "SSL certificate loading failed";
  1847. case Error::SSLServerVerification: return "SSL server verification failed";
  1848. case Error::SSLServerHostnameVerification:
  1849. return "SSL server hostname verification failed";
  1850. case Error::UnsupportedMultipartBoundaryChars:
  1851. return "Unsupported HTTP multipart boundary characters";
  1852. case Error::Compression: return "Compression failed";
  1853. case Error::ConnectionTimeout: return "Connection timed out";
  1854. case Error::ProxyConnection: return "Proxy connection failed";
  1855. case Error::ResourceExhaustion: return "Resource exhaustion";
  1856. case Error::TooManyFormDataFiles: return "Too many form data files";
  1857. case Error::ExceedMaxPayloadSize: return "Exceeded maximum payload size";
  1858. case Error::ExceedUriMaxLength: return "Exceeded maximum URI length";
  1859. case Error::ExceedMaxSocketDescriptorCount:
  1860. return "Exceeded maximum socket descriptor count";
  1861. case Error::InvalidRequestLine: return "Invalid request line";
  1862. case Error::InvalidHTTPMethod: return "Invalid HTTP method";
  1863. case Error::InvalidHTTPVersion: return "Invalid HTTP version";
  1864. case Error::InvalidHeaders: return "Invalid headers";
  1865. case Error::MultipartParsing: return "Multipart parsing failed";
  1866. case Error::OpenFile: return "Failed to open file";
  1867. case Error::Listen: return "Failed to listen on socket";
  1868. case Error::GetSockName: return "Failed to get socket name";
  1869. case Error::UnsupportedAddressFamily: return "Unsupported address family";
  1870. case Error::HTTPParsing: return "HTTP parsing failed";
  1871. case Error::InvalidRangeHeader: return "Invalid Range header";
  1872. default: break;
  1873. }
  1874. return "Invalid";
  1875. }
  1876. inline std::ostream &operator<<(std::ostream &os, const Error &obj) {
  1877. os << to_string(obj);
  1878. os << " (" << static_cast<std::underlying_type<Error>::type>(obj) << ')';
  1879. return os;
  1880. }
  1881. inline size_t Result::get_request_header_value_u64(const std::string &key,
  1882. size_t def,
  1883. size_t id) const {
  1884. return detail::get_header_value_u64(request_headers_, key, def, id);
  1885. }
  1886. template <class Rep, class Period>
  1887. inline void ClientImpl::set_connection_timeout(
  1888. const std::chrono::duration<Rep, Period> &duration) {
  1889. detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
  1890. set_connection_timeout(sec, usec);
  1891. });
  1892. }
  1893. template <class Rep, class Period>
  1894. inline void ClientImpl::set_read_timeout(
  1895. const std::chrono::duration<Rep, Period> &duration) {
  1896. detail::duration_to_sec_and_usec(
  1897. duration, [&](time_t sec, time_t usec) { set_read_timeout(sec, usec); });
  1898. }
  1899. template <class Rep, class Period>
  1900. inline void ClientImpl::set_write_timeout(
  1901. const std::chrono::duration<Rep, Period> &duration) {
  1902. detail::duration_to_sec_and_usec(
  1903. duration, [&](time_t sec, time_t usec) { set_write_timeout(sec, usec); });
  1904. }
  1905. template <class Rep, class Period>
  1906. inline void ClientImpl::set_max_timeout(
  1907. const std::chrono::duration<Rep, Period> &duration) {
  1908. auto msec =
  1909. std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
  1910. set_max_timeout(msec);
  1911. }
  1912. template <class Rep, class Period>
  1913. inline void Client::set_connection_timeout(
  1914. const std::chrono::duration<Rep, Period> &duration) {
  1915. cli_->set_connection_timeout(duration);
  1916. }
  1917. template <class Rep, class Period>
  1918. inline void
  1919. Client::set_read_timeout(const std::chrono::duration<Rep, Period> &duration) {
  1920. cli_->set_read_timeout(duration);
  1921. }
  1922. template <class Rep, class Period>
  1923. inline void
  1924. Client::set_write_timeout(const std::chrono::duration<Rep, Period> &duration) {
  1925. cli_->set_write_timeout(duration);
  1926. }
  1927. inline void Client::set_max_timeout(time_t msec) {
  1928. cli_->set_max_timeout(msec);
  1929. }
  1930. template <class Rep, class Period>
  1931. inline void
  1932. Client::set_max_timeout(const std::chrono::duration<Rep, Period> &duration) {
  1933. cli_->set_max_timeout(duration);
  1934. }
  1935. /*
  1936. * Forward declarations and types that will be part of the .h file if split into
  1937. * .h + .cc.
  1938. */
  1939. std::string hosted_at(const std::string &hostname);
  1940. void hosted_at(const std::string &hostname, std::vector<std::string> &addrs);
  1941. // JavaScript-style URL encoding/decoding functions
  1942. std::string encode_uri_component(const std::string &value);
  1943. std::string encode_uri(const std::string &value);
  1944. std::string decode_uri_component(const std::string &value);
  1945. std::string decode_uri(const std::string &value);
  1946. // RFC 3986 compliant URL component encoding/decoding functions
  1947. std::string encode_path_component(const std::string &component);
  1948. std::string decode_path_component(const std::string &component);
  1949. std::string encode_query_component(const std::string &component,
  1950. bool space_as_plus = true);
  1951. std::string decode_query_component(const std::string &component,
  1952. bool plus_as_space = true);
  1953. std::string append_query_params(const std::string &path, const Params &params);
  1954. std::pair<std::string, std::string> make_range_header(const Ranges &ranges);
  1955. std::pair<std::string, std::string>
  1956. make_basic_authentication_header(const std::string &username,
  1957. const std::string &password,
  1958. bool is_proxy = false);
  1959. namespace detail {
  1960. #if defined(_WIN32)
  1961. inline std::wstring u8string_to_wstring(const char *s) {
  1962. std::wstring ws;
  1963. auto len = static_cast<int>(strlen(s));
  1964. auto wlen = ::MultiByteToWideChar(CP_UTF8, 0, s, len, nullptr, 0);
  1965. if (wlen > 0) {
  1966. ws.resize(wlen);
  1967. wlen = ::MultiByteToWideChar(
  1968. CP_UTF8, 0, s, len,
  1969. const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(ws.data())), wlen);
  1970. if (wlen != static_cast<int>(ws.size())) { ws.clear(); }
  1971. }
  1972. return ws;
  1973. }
  1974. #endif
  1975. struct FileStat {
  1976. FileStat(const std::string &path);
  1977. bool is_file() const;
  1978. bool is_dir() const;
  1979. private:
  1980. #if defined(_WIN32)
  1981. struct _stat st_;
  1982. #else
  1983. struct stat st_;
  1984. #endif
  1985. int ret_ = -1;
  1986. };
  1987. std::string trim_copy(const std::string &s);
  1988. void divide(
  1989. const char *data, std::size_t size, char d,
  1990. std::function<void(const char *, std::size_t, const char *, std::size_t)>
  1991. fn);
  1992. void divide(
  1993. const std::string &str, char d,
  1994. std::function<void(const char *, std::size_t, const char *, std::size_t)>
  1995. fn);
  1996. void split(const char *b, const char *e, char d,
  1997. std::function<void(const char *, const char *)> fn);
  1998. void split(const char *b, const char *e, char d, size_t m,
  1999. std::function<void(const char *, const char *)> fn);
  2000. bool process_client_socket(
  2001. socket_t sock, time_t read_timeout_sec, time_t read_timeout_usec,
  2002. time_t write_timeout_sec, time_t write_timeout_usec,
  2003. time_t max_timeout_msec,
  2004. std::chrono::time_point<std::chrono::steady_clock> start_time,
  2005. std::function<bool(Stream &)> callback);
  2006. socket_t create_client_socket(const std::string &host, const std::string &ip,
  2007. int port, int address_family, bool tcp_nodelay,
  2008. bool ipv6_v6only, SocketOptions socket_options,
  2009. time_t connection_timeout_sec,
  2010. time_t connection_timeout_usec,
  2011. time_t read_timeout_sec, time_t read_timeout_usec,
  2012. time_t write_timeout_sec,
  2013. time_t write_timeout_usec,
  2014. const std::string &intf, Error &error);
  2015. const char *get_header_value(const Headers &headers, const std::string &key,
  2016. const char *def, size_t id);
  2017. std::string params_to_query_str(const Params &params);
  2018. void parse_query_text(const char *data, std::size_t size, Params &params);
  2019. void parse_query_text(const std::string &s, Params &params);
  2020. bool parse_multipart_boundary(const std::string &content_type,
  2021. std::string &boundary);
  2022. bool parse_range_header(const std::string &s, Ranges &ranges);
  2023. bool parse_accept_header(const std::string &s,
  2024. std::vector<std::string> &content_types);
  2025. int close_socket(socket_t sock);
  2026. ssize_t send_socket(socket_t sock, const void *ptr, size_t size, int flags);
  2027. ssize_t read_socket(socket_t sock, void *ptr, size_t size, int flags);
  2028. enum class EncodingType { None = 0, Gzip, Brotli, Zstd };
  2029. EncodingType encoding_type(const Request &req, const Response &res);
  2030. class BufferStream final : public Stream {
  2031. public:
  2032. BufferStream() = default;
  2033. ~BufferStream() override = default;
  2034. bool is_readable() const override;
  2035. bool wait_readable() const override;
  2036. bool wait_writable() const override;
  2037. ssize_t read(char *ptr, size_t size) override;
  2038. ssize_t write(const char *ptr, size_t size) override;
  2039. void get_remote_ip_and_port(std::string &ip, int &port) const override;
  2040. void get_local_ip_and_port(std::string &ip, int &port) const override;
  2041. socket_t socket() const override;
  2042. time_t duration() const override;
  2043. const std::string &get_buffer() const;
  2044. private:
  2045. std::string buffer;
  2046. size_t position = 0;
  2047. };
  2048. class compressor {
  2049. public:
  2050. virtual ~compressor() = default;
  2051. typedef std::function<bool(const char *data, size_t data_len)> Callback;
  2052. virtual bool compress(const char *data, size_t data_length, bool last,
  2053. Callback callback) = 0;
  2054. };
  2055. class decompressor {
  2056. public:
  2057. virtual ~decompressor() = default;
  2058. virtual bool is_valid() const = 0;
  2059. typedef std::function<bool(const char *data, size_t data_len)> Callback;
  2060. virtual bool decompress(const char *data, size_t data_length,
  2061. Callback callback) = 0;
  2062. };
  2063. class nocompressor final : public compressor {
  2064. public:
  2065. ~nocompressor() override = default;
  2066. bool compress(const char *data, size_t data_length, bool /*last*/,
  2067. Callback callback) override;
  2068. };
  2069. #ifdef CPPHTTPLIB_ZLIB_SUPPORT
  2070. class gzip_compressor final : public compressor {
  2071. public:
  2072. gzip_compressor();
  2073. ~gzip_compressor() override;
  2074. bool compress(const char *data, size_t data_length, bool last,
  2075. Callback callback) override;
  2076. private:
  2077. bool is_valid_ = false;
  2078. z_stream strm_;
  2079. };
  2080. class gzip_decompressor final : public decompressor {
  2081. public:
  2082. gzip_decompressor();
  2083. ~gzip_decompressor() override;
  2084. bool is_valid() const override;
  2085. bool decompress(const char *data, size_t data_length,
  2086. Callback callback) override;
  2087. private:
  2088. bool is_valid_ = false;
  2089. z_stream strm_;
  2090. };
  2091. #endif
  2092. #ifdef CPPHTTPLIB_BROTLI_SUPPORT
  2093. class brotli_compressor final : public compressor {
  2094. public:
  2095. brotli_compressor();
  2096. ~brotli_compressor();
  2097. bool compress(const char *data, size_t data_length, bool last,
  2098. Callback callback) override;
  2099. private:
  2100. BrotliEncoderState *state_ = nullptr;
  2101. };
  2102. class brotli_decompressor final : public decompressor {
  2103. public:
  2104. brotli_decompressor();
  2105. ~brotli_decompressor();
  2106. bool is_valid() const override;
  2107. bool decompress(const char *data, size_t data_length,
  2108. Callback callback) override;
  2109. private:
  2110. BrotliDecoderResult decoder_r;
  2111. BrotliDecoderState *decoder_s = nullptr;
  2112. };
  2113. #endif
  2114. #ifdef CPPHTTPLIB_ZSTD_SUPPORT
  2115. class zstd_compressor : public compressor {
  2116. public:
  2117. zstd_compressor();
  2118. ~zstd_compressor();
  2119. bool compress(const char *data, size_t data_length, bool last,
  2120. Callback callback) override;
  2121. private:
  2122. ZSTD_CCtx *ctx_ = nullptr;
  2123. };
  2124. class zstd_decompressor : public decompressor {
  2125. public:
  2126. zstd_decompressor();
  2127. ~zstd_decompressor();
  2128. bool is_valid() const override;
  2129. bool decompress(const char *data, size_t data_length,
  2130. Callback callback) override;
  2131. private:
  2132. ZSTD_DCtx *ctx_ = nullptr;
  2133. };
  2134. #endif
  2135. // NOTE: until the read size reaches `fixed_buffer_size`, use `fixed_buffer`
  2136. // to store data. The call can set memory on stack for performance.
  2137. class stream_line_reader {
  2138. public:
  2139. stream_line_reader(Stream &strm, char *fixed_buffer,
  2140. size_t fixed_buffer_size);
  2141. const char *ptr() const;
  2142. size_t size() const;
  2143. bool end_with_crlf() const;
  2144. bool getline();
  2145. private:
  2146. void append(char c);
  2147. Stream &strm_;
  2148. char *fixed_buffer_;
  2149. const size_t fixed_buffer_size_;
  2150. size_t fixed_buffer_used_size_ = 0;
  2151. std::string growable_buffer_;
  2152. };
  2153. class mmap {
  2154. public:
  2155. mmap(const char *path);
  2156. ~mmap();
  2157. bool open(const char *path);
  2158. void close();
  2159. bool is_open() const;
  2160. size_t size() const;
  2161. const char *data() const;
  2162. private:
  2163. #if defined(_WIN32)
  2164. HANDLE hFile_ = NULL;
  2165. HANDLE hMapping_ = NULL;
  2166. #else
  2167. int fd_ = -1;
  2168. #endif
  2169. size_t size_ = 0;
  2170. void *addr_ = nullptr;
  2171. bool is_open_empty_file = false;
  2172. };
  2173. // NOTE: https://www.rfc-editor.org/rfc/rfc9110#section-5
  2174. namespace fields {
  2175. inline bool is_token_char(char c) {
  2176. return std::isalnum(c) || c == '!' || c == '#' || c == '$' || c == '%' ||
  2177. c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' ||
  2178. c == '.' || c == '^' || c == '_' || c == '`' || c == '|' || c == '~';
  2179. }
  2180. inline bool is_token(const std::string &s) {
  2181. if (s.empty()) { return false; }
  2182. for (auto c : s) {
  2183. if (!is_token_char(c)) { return false; }
  2184. }
  2185. return true;
  2186. }
  2187. inline bool is_field_name(const std::string &s) { return is_token(s); }
  2188. inline bool is_vchar(char c) { return c >= 33 && c <= 126; }
  2189. inline bool is_obs_text(char c) { return 128 <= static_cast<unsigned char>(c); }
  2190. inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); }
  2191. inline bool is_field_content(const std::string &s) {
  2192. if (s.empty()) { return true; }
  2193. if (s.size() == 1) {
  2194. return is_field_vchar(s[0]);
  2195. } else if (s.size() == 2) {
  2196. return is_field_vchar(s[0]) && is_field_vchar(s[1]);
  2197. } else {
  2198. size_t i = 0;
  2199. if (!is_field_vchar(s[i])) { return false; }
  2200. i++;
  2201. while (i < s.size() - 1) {
  2202. auto c = s[i++];
  2203. if (c == ' ' || c == '\t' || is_field_vchar(c)) {
  2204. } else {
  2205. return false;
  2206. }
  2207. }
  2208. return is_field_vchar(s[i]);
  2209. }
  2210. }
  2211. inline bool is_field_value(const std::string &s) { return is_field_content(s); }
  2212. } // namespace fields
  2213. } // namespace detail
  2214. } // namespace httplib
  2215. #endif // CPPHTTPLIB_HTTPLIB_H