1
0

httplib.h 103 KB

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