verb.ipp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_HTTP_IMPL_VERB_IPP
  10. #define BOOST_BEAST_HTTP_IMPL_VERB_IPP
  11. #include <boost/beast/http/verb.hpp>
  12. #include <boost/throw_exception.hpp>
  13. #include <stdexcept>
  14. namespace boost {
  15. namespace beast {
  16. namespace http {
  17. string_view
  18. to_string(verb v)
  19. {
  20. switch(v)
  21. {
  22. case verb::delete_: return "DELETE";
  23. case verb::get: return "GET";
  24. case verb::head: return "HEAD";
  25. case verb::post: return "POST";
  26. case verb::put: return "PUT";
  27. case verb::connect: return "CONNECT";
  28. case verb::options: return "OPTIONS";
  29. case verb::trace: return "TRACE";
  30. case verb::copy: return "COPY";
  31. case verb::lock: return "LOCK";
  32. case verb::mkcol: return "MKCOL";
  33. case verb::move: return "MOVE";
  34. case verb::propfind: return "PROPFIND";
  35. case verb::proppatch: return "PROPPATCH";
  36. case verb::search: return "SEARCH";
  37. case verb::unlock: return "UNLOCK";
  38. case verb::bind: return "BIND";
  39. case verb::rebind: return "REBIND";
  40. case verb::unbind: return "UNBIND";
  41. case verb::acl: return "ACL";
  42. case verb::report: return "REPORT";
  43. case verb::mkactivity: return "MKACTIVITY";
  44. case verb::checkout: return "CHECKOUT";
  45. case verb::merge: return "MERGE";
  46. case verb::msearch: return "M-SEARCH";
  47. case verb::notify: return "NOTIFY";
  48. case verb::subscribe: return "SUBSCRIBE";
  49. case verb::unsubscribe: return "UNSUBSCRIBE";
  50. case verb::patch: return "PATCH";
  51. case verb::purge: return "PURGE";
  52. case verb::mkcalendar: return "MKCALENDAR";
  53. case verb::link: return "LINK";
  54. case verb::unlink: return "UNLINK";
  55. case verb::unknown:
  56. return "<unknown>";
  57. }
  58. BOOST_THROW_EXCEPTION(std::invalid_argument{"unknown verb"});
  59. }
  60. verb
  61. string_to_verb(string_view v)
  62. {
  63. /*
  64. ACL
  65. BIND
  66. CHECKOUT
  67. CONNECT
  68. COPY
  69. DELETE
  70. GET
  71. HEAD
  72. LINK
  73. LOCK
  74. M-SEARCH
  75. MERGE
  76. MKACTIVITY
  77. MKCALENDAR
  78. MKCOL
  79. MOVE
  80. NOTIFY
  81. OPTIONS
  82. PATCH
  83. POST
  84. PROPFIND
  85. PROPPATCH
  86. PURGE
  87. PUT
  88. REBIND
  89. REPORT
  90. SEARCH
  91. SUBSCRIBE
  92. TRACE
  93. UNBIND
  94. UNLINK
  95. UNLOCK
  96. UNSUBSCRIBE
  97. */
  98. if(v.size() < 3)
  99. return verb::unknown;
  100. // s must be null terminated
  101. auto const eq =
  102. [](string_view sv, char const* s)
  103. {
  104. auto p = sv.data();
  105. for(;;)
  106. {
  107. if(*s != *p)
  108. return false;
  109. ++s;
  110. ++p;
  111. if(! *s)
  112. return p == (sv.data() + sv.size());
  113. }
  114. };
  115. auto c = v[0];
  116. v.remove_prefix(1);
  117. switch(c)
  118. {
  119. case 'A':
  120. if(v == "CL")
  121. return verb::acl;
  122. break;
  123. case 'B':
  124. if(v == "IND")
  125. return verb::bind;
  126. break;
  127. case 'C':
  128. c = v[0];
  129. v.remove_prefix(1);
  130. switch(c)
  131. {
  132. case 'H':
  133. if(eq(v, "ECKOUT"))
  134. return verb::checkout;
  135. break;
  136. case 'O':
  137. if(eq(v, "NNECT"))
  138. return verb::connect;
  139. if(eq(v, "PY"))
  140. return verb::copy;
  141. BOOST_FALLTHROUGH;
  142. default:
  143. break;
  144. }
  145. break;
  146. case 'D':
  147. if(eq(v, "ELETE"))
  148. return verb::delete_;
  149. break;
  150. case 'G':
  151. if(eq(v, "ET"))
  152. return verb::get;
  153. break;
  154. case 'H':
  155. if(eq(v, "EAD"))
  156. return verb::head;
  157. break;
  158. case 'L':
  159. if(eq(v, "INK"))
  160. return verb::link;
  161. if(eq(v, "OCK"))
  162. return verb::lock;
  163. break;
  164. case 'M':
  165. c = v[0];
  166. v.remove_prefix(1);
  167. switch(c)
  168. {
  169. case '-':
  170. if(eq(v, "SEARCH"))
  171. return verb::msearch;
  172. break;
  173. case 'E':
  174. if(eq(v, "RGE"))
  175. return verb::merge;
  176. break;
  177. case 'K':
  178. if(eq(v, "ACTIVITY"))
  179. return verb::mkactivity;
  180. if(v[0] == 'C')
  181. {
  182. v.remove_prefix(1);
  183. if(eq(v, "ALENDAR"))
  184. return verb::mkcalendar;
  185. if(eq(v, "OL"))
  186. return verb::mkcol;
  187. break;
  188. }
  189. break;
  190. case 'O':
  191. if(eq(v, "VE"))
  192. return verb::move;
  193. BOOST_FALLTHROUGH;
  194. default:
  195. break;
  196. }
  197. break;
  198. case 'N':
  199. if(eq(v, "OTIFY"))
  200. return verb::notify;
  201. break;
  202. case 'O':
  203. if(eq(v, "PTIONS"))
  204. return verb::options;
  205. break;
  206. case 'P':
  207. c = v[0];
  208. v.remove_prefix(1);
  209. switch(c)
  210. {
  211. case 'A':
  212. if(eq(v, "TCH"))
  213. return verb::patch;
  214. break;
  215. case 'O':
  216. if(eq(v, "ST"))
  217. return verb::post;
  218. break;
  219. case 'R':
  220. if(eq(v, "OPFIND"))
  221. return verb::propfind;
  222. if(eq(v, "OPPATCH"))
  223. return verb::proppatch;
  224. break;
  225. case 'U':
  226. if(eq(v, "RGE"))
  227. return verb::purge;
  228. if(eq(v, "T"))
  229. return verb::put;
  230. BOOST_FALLTHROUGH;
  231. default:
  232. break;
  233. }
  234. break;
  235. case 'R':
  236. if(v[0] != 'E')
  237. break;
  238. v.remove_prefix(1);
  239. if(eq(v, "BIND"))
  240. return verb::rebind;
  241. if(eq(v, "PORT"))
  242. return verb::report;
  243. break;
  244. case 'S':
  245. if(eq(v, "EARCH"))
  246. return verb::search;
  247. if(eq(v, "UBSCRIBE"))
  248. return verb::subscribe;
  249. break;
  250. case 'T':
  251. if(eq(v, "RACE"))
  252. return verb::trace;
  253. break;
  254. case 'U':
  255. if(v[0] != 'N')
  256. break;
  257. v.remove_prefix(1);
  258. if(eq(v, "BIND"))
  259. return verb::unbind;
  260. if(eq(v, "LINK"))
  261. return verb::unlink;
  262. if(eq(v, "LOCK"))
  263. return verb::unlock;
  264. if(eq(v, "SUBSCRIBE"))
  265. return verb::unsubscribe;
  266. break;
  267. default:
  268. break;
  269. }
  270. return verb::unknown;
  271. }
  272. } // http
  273. } // beast
  274. } // boost
  275. #endif