server.c 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation:
  9. * version 2.1 of the License.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301 USA
  20. */
  21. #include "private-libwebsockets.h"
  22. #if defined (LWS_WITH_ESP8266)
  23. #undef memcpy
  24. void *memcpy(void *dest, const void *src, size_t n)
  25. {
  26. return ets_memcpy(dest, src, n);
  27. }
  28. #endif
  29. int
  30. lws_context_init_server(struct lws_context_creation_info *info,
  31. struct lws_vhost *vhost)
  32. {
  33. #if LWS_POSIX
  34. int n, opt = 1, limit = 1;
  35. #endif
  36. lws_sockfd_type sockfd;
  37. struct lws_vhost *vh;
  38. struct lws *wsi;
  39. int m = 0;
  40. /* set up our external listening socket we serve on */
  41. if (info->port == CONTEXT_PORT_NO_LISTEN)
  42. return 0;
  43. vh = vhost->context->vhost_list;
  44. while (vh) {
  45. if (vh->listen_port == info->port) {
  46. if ((!info->iface && !vh->iface) ||
  47. (info->iface && vh->iface &&
  48. !strcmp(info->iface, vh->iface))) {
  49. vhost->listen_port = info->port;
  50. vhost->iface = info->iface;
  51. lwsl_notice(" using listen skt from vhost %s\n",
  52. vh->name);
  53. return 0;
  54. }
  55. }
  56. vh = vh->vhost_next;
  57. }
  58. #if LWS_POSIX
  59. #if defined(__linux__)
  60. limit = vhost->context->count_threads;
  61. #endif
  62. for (m = 0; m < limit; m++) {
  63. #ifdef LWS_USE_UNIX_SOCK
  64. if (LWS_UNIX_SOCK_ENABLED(vhost))
  65. sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  66. else
  67. #endif
  68. #ifdef LWS_USE_IPV6
  69. if (LWS_IPV6_ENABLED(vhost))
  70. sockfd = socket(AF_INET6, SOCK_STREAM, 0);
  71. else
  72. #endif
  73. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  74. if (sockfd == -1) {
  75. #else
  76. #if defined(LWS_WITH_ESP8266)
  77. sockfd = esp8266_create_tcp_listen_socket(vhost);
  78. if (!lws_sockfd_valid(sockfd)) {
  79. #else
  80. sockfd = mbed3_create_tcp_stream_socket();
  81. if (!lws_sockfd_valid(sockfd)) {
  82. #endif
  83. #endif
  84. lwsl_err("ERROR opening socket\n");
  85. return 1;
  86. }
  87. #if LWS_POSIX
  88. /*
  89. * allow us to restart even if old sockets in TIME_WAIT
  90. */
  91. if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
  92. (const void *)&opt, sizeof(opt)) < 0) {
  93. compatible_close(sockfd);
  94. return 1;
  95. }
  96. #if defined(LWS_USE_IPV6) && defined(IPV6_V6ONLY)
  97. if (LWS_IPV6_ENABLED(vhost)) {
  98. if (vhost->options & LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY) {
  99. int value = (vhost->options & LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE) ? 1 : 0;
  100. if (setsockopt(sockfd, SOL_IPV6, IPV6_V6ONLY,
  101. (const void*)&value, sizeof(value)) < 0) {
  102. compatible_close(sockfd);
  103. return 1;
  104. }
  105. }
  106. }
  107. #endif
  108. #if defined(__linux__) && defined(SO_REUSEPORT) && LWS_MAX_SMP > 1
  109. if (vhost->context->count_threads > 1)
  110. if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT,
  111. (const void *)&opt, sizeof(opt)) < 0) {
  112. compatible_close(sockfd);
  113. return 1;
  114. }
  115. #endif
  116. #endif
  117. lws_plat_set_socket_options(vhost, sockfd);
  118. #if LWS_POSIX
  119. n = lws_socket_bind(vhost, sockfd, info->port, info->iface);
  120. if (n < 0)
  121. goto bail;
  122. info->port = n;
  123. #endif
  124. vhost->listen_port = info->port;
  125. vhost->iface = info->iface;
  126. wsi = lws_zalloc(sizeof(struct lws));
  127. if (wsi == NULL) {
  128. lwsl_err("Out of mem\n");
  129. goto bail;
  130. }
  131. wsi->context = vhost->context;
  132. wsi->sock = sockfd;
  133. wsi->mode = LWSCM_SERVER_LISTENER;
  134. wsi->protocol = vhost->protocols;
  135. wsi->tsi = m;
  136. wsi->vhost = vhost;
  137. wsi->listener = 1;
  138. vhost->context->pt[m].wsi_listening = wsi;
  139. if (insert_wsi_socket_into_fds(vhost->context, wsi))
  140. goto bail;
  141. vhost->context->count_wsi_allocated++;
  142. vhost->lserv_wsi = wsi;
  143. #if LWS_POSIX
  144. listen(wsi->sock, LWS_SOMAXCONN);
  145. } /* for each thread able to independently listen */
  146. #else
  147. #if defined(LWS_WITH_ESP8266)
  148. esp8266_tcp_stream_bind(wsi->sock, info->port, wsi);
  149. #else
  150. mbed3_tcp_stream_bind(wsi->sock, info->port, wsi);
  151. #endif
  152. #endif
  153. if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) {
  154. #ifdef LWS_USE_UNIX_SOCK
  155. if (LWS_UNIX_SOCK_ENABLED(vhost))
  156. lwsl_notice(" Listening on \"%s\"\n", info->iface);
  157. else
  158. #endif
  159. lwsl_notice(" Listening on port %d\n", info->port);
  160. }
  161. return 0;
  162. bail:
  163. compatible_close(sockfd);
  164. return 1;
  165. }
  166. int
  167. _lws_server_listen_accept_flow_control(struct lws *twsi, int on)
  168. {
  169. struct lws_context_per_thread *pt = &twsi->context->pt[(int)twsi->tsi];
  170. struct lws *wsi = pt->wsi_listening;
  171. int n;
  172. if (!wsi || twsi->context->being_destroyed)
  173. return 0;
  174. lwsl_debug("%s: Thr %d: LISTEN wsi %p: state %d\n",
  175. __func__, twsi->tsi, (void *)wsi, on);
  176. if (on)
  177. n = lws_change_pollfd(wsi, 0, LWS_POLLIN);
  178. else
  179. n = lws_change_pollfd(wsi, LWS_POLLIN, 0);
  180. return n;
  181. }
  182. #if defined(LWS_WITH_ESP8266)
  183. #undef strchr
  184. #define strchr ets_strchr
  185. #endif
  186. struct lws_vhost *
  187. lws_select_vhost(struct lws_context *context, int port, const char *servername)
  188. {
  189. struct lws_vhost *vhost = context->vhost_list;
  190. const char *p;
  191. int n, m, colon;
  192. n = strlen(servername);
  193. colon = n;
  194. p = strchr(servername, ':');
  195. if (p)
  196. colon = p - servername;
  197. /* first try exact matches */
  198. while (vhost) {
  199. if (port == vhost->listen_port &&
  200. !strncmp(vhost->name, servername, colon)) {
  201. lwsl_info("SNI: Found: %s\n", servername);
  202. return vhost;
  203. }
  204. vhost = vhost->vhost_next;
  205. }
  206. /*
  207. * if no exact matches, try matching *.vhost-name
  208. * unintentional matches are possible but resolve to x.com for *.x.com
  209. * which is reasonable. If exact match exists we already chose it and
  210. * never reach here. SSL will still fail it if the cert doesn't allow
  211. * *.x.com.
  212. */
  213. vhost = context->vhost_list;
  214. while (vhost) {
  215. m = strlen(vhost->name);
  216. if (port == vhost->listen_port &&
  217. m <= (colon - 2) &&
  218. servername[colon - m - 1] == '.' &&
  219. !strncmp(vhost->name, servername + colon - m, m)) {
  220. lwsl_info("SNI: Found %s on wildcard: %s\n",
  221. servername, vhost->name);
  222. return vhost;
  223. }
  224. vhost = vhost->vhost_next;
  225. }
  226. return NULL;
  227. }
  228. LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
  229. lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name)
  230. {
  231. int n;
  232. for (n = 0; n < vh->count_protocols; n++)
  233. if (!strcmp(name, vh->protocols[n].name))
  234. return &vh->protocols[n];
  235. return NULL;
  236. }
  237. LWS_VISIBLE LWS_EXTERN const char *
  238. lws_get_mimetype(const char *file, const struct lws_http_mount *m)
  239. {
  240. int n = strlen(file);
  241. const struct lws_protocol_vhost_options *pvo = NULL;
  242. if (m)
  243. pvo = m->extra_mimetypes;
  244. if (n < 5)
  245. return NULL;
  246. if (!strcmp(&file[n - 4], ".ico"))
  247. return "image/x-icon";
  248. if (!strcmp(&file[n - 4], ".gif"))
  249. return "image/gif";
  250. if (!strcmp(&file[n - 3], ".js"))
  251. return "text/javascript";
  252. if (!strcmp(&file[n - 4], ".png"))
  253. return "image/png";
  254. if (!strcmp(&file[n - 4], ".jpg"))
  255. return "image/jpeg";
  256. if (!strcmp(&file[n - 3], ".gz"))
  257. return "application/gzip";
  258. if (!strcmp(&file[n - 4], ".JPG"))
  259. return "image/jpeg";
  260. if (!strcmp(&file[n - 5], ".html"))
  261. return "text/html";
  262. if (!strcmp(&file[n - 4], ".css"))
  263. return "text/css";
  264. if (!strcmp(&file[n - 4], ".txt"))
  265. return "text/plain";
  266. if (!strcmp(&file[n - 4], ".svg"))
  267. return "image/svg+xml";
  268. if (!strcmp(&file[n - 4], ".ttf"))
  269. return "application/x-font-ttf";
  270. if (!strcmp(&file[n - 5], ".woff"))
  271. return "application/font-woff";
  272. if (!strcmp(&file[n - 4], ".xml"))
  273. return "application/xml";
  274. while (pvo) {
  275. if (pvo->name[0] == '*') /* ie, match anything */
  276. return pvo->value;
  277. if (!strcmp(&file[n - strlen(pvo->name)], pvo->name))
  278. return pvo->value;
  279. pvo = pvo->next;
  280. }
  281. return NULL;
  282. }
  283. static int
  284. lws_http_serve(struct lws *wsi, char *uri, const char *origin,
  285. const struct lws_http_mount *m)
  286. {
  287. const struct lws_protocol_vhost_options *pvo = m->interpret;
  288. struct lws_process_html_args args;
  289. const char *mimetype;
  290. #if !defined(_WIN32_WCE) && !defined(LWS_WITH_ESP8266)
  291. struct stat st;
  292. int spin = 0;
  293. #endif
  294. char path[256], sym[512];
  295. unsigned char *p = (unsigned char *)sym + 32 + LWS_PRE, *start = p;
  296. unsigned char *end = p + sizeof(sym) - 32 - LWS_PRE;
  297. #if !defined(WIN32) && LWS_POSIX
  298. size_t len;
  299. #endif
  300. int n;
  301. lws_snprintf(path, sizeof(path) - 1, "%s/%s", origin, uri);
  302. #if !defined(_WIN32_WCE) && !defined(LWS_WITH_ESP8266)
  303. do {
  304. spin++;
  305. if (stat(path, &st)) {
  306. lwsl_info("unable to stat %s\n", path);
  307. goto bail;
  308. }
  309. lwsl_debug(" %s mode %d\n", path, S_IFMT & st.st_mode);
  310. #if !defined(WIN32) && LWS_POSIX
  311. if ((S_IFMT & st.st_mode) == S_IFLNK) {
  312. len = readlink(path, sym, sizeof(sym) - 1);
  313. if (len) {
  314. lwsl_err("Failed to read link %s\n", path);
  315. goto bail;
  316. }
  317. sym[len] = '\0';
  318. lwsl_debug("symlink %s -> %s\n", path, sym);
  319. lws_snprintf(path, sizeof(path) - 1, "%s", sym);
  320. }
  321. #endif
  322. if ((S_IFMT & st.st_mode) == S_IFDIR) {
  323. lwsl_debug("default filename append to dir\n");
  324. lws_snprintf(path, sizeof(path) - 1, "%s/%s/index.html",
  325. origin, uri);
  326. }
  327. } while ((S_IFMT & st.st_mode) != S_IFREG && spin < 5);
  328. if (spin == 5)
  329. lwsl_err("symlink loop %s \n", path);
  330. n = sprintf(sym, "%08lX%08lX", (unsigned long)st.st_size,
  331. (unsigned long)st.st_mtime);
  332. if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH)) {
  333. /*
  334. * he thinks he has some version of it already,
  335. * check if the tag matches
  336. */
  337. if (!strcmp(sym, lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH))) {
  338. lwsl_debug("%s: ETAG match %s %s\n", __func__,
  339. uri, origin);
  340. /* we don't need to send the payload */
  341. if (lws_add_http_header_status(wsi, 304, &p, end))
  342. return -1;
  343. if (lws_add_http_header_by_token(wsi,
  344. WSI_TOKEN_HTTP_ETAG,
  345. (unsigned char *)sym, n, &p, end))
  346. return -1;
  347. if (lws_finalize_http_header(wsi, &p, end))
  348. return -1;
  349. n = lws_write(wsi, start, p - start,
  350. LWS_WRITE_HTTP_HEADERS);
  351. if (n != (p - start)) {
  352. lwsl_err("_write returned %d from %d\n", n, p - start);
  353. return -1;
  354. }
  355. return lws_http_transaction_completed(wsi);
  356. }
  357. }
  358. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ETAG,
  359. (unsigned char *)sym, n, &p, end))
  360. return -1;
  361. #endif
  362. mimetype = lws_get_mimetype(path, m);
  363. if (!mimetype) {
  364. lwsl_err("unknown mimetype for %s\n", path);
  365. goto bail;
  366. }
  367. if (!mimetype[0])
  368. lwsl_debug("sending no mimetype for %s\n", path);
  369. wsi->sending_chunked = 0;
  370. /*
  371. * check if this is in the list of file suffixes to be interpreted by
  372. * a protocol
  373. */
  374. while (pvo) {
  375. n = strlen(path);
  376. if (n > (int)strlen(pvo->name) &&
  377. !strcmp(&path[n - strlen(pvo->name)], pvo->name)) {
  378. wsi->sending_chunked = 1;
  379. wsi->protocol_interpret_idx = (char)(long)pvo->value;
  380. lwsl_info("want %s interpreted by %s\n", path,
  381. wsi->vhost->protocols[(int)(long)(pvo->value)].name);
  382. wsi->protocol = &wsi->vhost->protocols[(int)(long)(pvo->value)];
  383. if (lws_ensure_user_space(wsi))
  384. return -1;
  385. break;
  386. }
  387. pvo = pvo->next;
  388. }
  389. if (m->protocol) {
  390. const struct lws_protocols *pp = lws_vhost_name_to_protocol(
  391. wsi->vhost, m->protocol);
  392. if (lws_bind_protocol(wsi, pp))
  393. return 1;
  394. args.p = (char *)p;
  395. args.max_len = end - p;
  396. if (pp->callback(wsi, LWS_CALLBACK_ADD_HEADERS,
  397. wsi->user_space, &args, 0))
  398. return -1;
  399. p = (unsigned char *)args.p;
  400. }
  401. n = lws_serve_http_file(wsi, path, mimetype, (char *)start, p - start);
  402. if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi)))
  403. return -1; /* error or can't reuse connection: close the socket */
  404. return 0;
  405. bail:
  406. return -1;
  407. }
  408. const struct lws_http_mount *
  409. lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len)
  410. {
  411. const struct lws_http_mount *hm, *hit = NULL;
  412. int best = 0;
  413. hm = wsi->vhost->mount_list;
  414. while (hm) {
  415. if (uri_len >= hm->mountpoint_len &&
  416. !strncmp(uri_ptr, hm->mountpoint, hm->mountpoint_len) &&
  417. (uri_ptr[hm->mountpoint_len] == '\0' ||
  418. uri_ptr[hm->mountpoint_len] == '/' ||
  419. hm->mountpoint_len == 1)
  420. ) {
  421. if (hm->origin_protocol == LWSMPRO_CALLBACK ||
  422. ((hm->origin_protocol == LWSMPRO_CGI ||
  423. lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) ||
  424. hm->protocol) &&
  425. hm->mountpoint_len > best)) {
  426. best = hm->mountpoint_len;
  427. hit = hm;
  428. }
  429. }
  430. hm = hm->mount_next;
  431. }
  432. return hit;
  433. }
  434. int
  435. lws_http_action(struct lws *wsi)
  436. {
  437. struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
  438. enum http_connection_type connection_type;
  439. enum http_version request_version;
  440. char content_length_str[32];
  441. struct lws_process_html_args args;
  442. const struct lws_http_mount *hit = NULL;
  443. unsigned int n, count = 0;
  444. char http_version_str[10];
  445. char http_conn_str[20];
  446. int http_version_len;
  447. char *uri_ptr = NULL, *s;
  448. int uri_len = 0;
  449. int meth = -1;
  450. static const unsigned char methods[] = {
  451. WSI_TOKEN_GET_URI,
  452. WSI_TOKEN_POST_URI,
  453. WSI_TOKEN_OPTIONS_URI,
  454. WSI_TOKEN_PUT_URI,
  455. WSI_TOKEN_PATCH_URI,
  456. WSI_TOKEN_DELETE_URI,
  457. #ifdef LWS_USE_HTTP2
  458. WSI_TOKEN_HTTP_COLON_PATH,
  459. #endif
  460. };
  461. #if defined(_DEBUG) || defined(LWS_WITH_ACCESS_LOG)
  462. static const char * const method_names[] = {
  463. "GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE",
  464. #ifdef LWS_USE_HTTP2
  465. ":path",
  466. #endif
  467. };
  468. #endif
  469. static const char * const oprot[] = {
  470. "http://", "https://"
  471. };
  472. /* it's not websocket.... shall we accept it as http? */
  473. for (n = 0; n < ARRAY_SIZE(methods); n++)
  474. if (lws_hdr_total_length(wsi, methods[n]))
  475. count++;
  476. if (!count) {
  477. lwsl_warn("Missing URI in HTTP request\n");
  478. goto bail_nuke_ah;
  479. }
  480. if (count != 1) {
  481. lwsl_warn("multiple methods?\n");
  482. goto bail_nuke_ah;
  483. }
  484. if (lws_ensure_user_space(wsi))
  485. goto bail_nuke_ah;
  486. for (n = 0; n < ARRAY_SIZE(methods); n++)
  487. if (lws_hdr_total_length(wsi, methods[n])) {
  488. uri_ptr = lws_hdr_simple_ptr(wsi, methods[n]);
  489. uri_len = lws_hdr_total_length(wsi, methods[n]);
  490. lwsl_info("Method: %s request for '%s'\n",
  491. method_names[n], uri_ptr);
  492. meth = n;
  493. break;
  494. }
  495. (void)meth;
  496. /* we insist on absolute paths */
  497. if (uri_ptr[0] != '/') {
  498. lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
  499. goto bail_nuke_ah;
  500. }
  501. /* HTTP header had a content length? */
  502. wsi->u.http.content_length = 0;
  503. if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) ||
  504. lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) ||
  505. lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI))
  506. wsi->u.http.content_length = 100 * 1024 * 1024;
  507. if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
  508. lws_hdr_copy(wsi, content_length_str,
  509. sizeof(content_length_str) - 1,
  510. WSI_TOKEN_HTTP_CONTENT_LENGTH);
  511. wsi->u.http.content_length = atoi(content_length_str);
  512. }
  513. if (wsi->http2_substream) {
  514. wsi->u.http.request_version = HTTP_VERSION_2;
  515. } else {
  516. /* http_version? Default to 1.0, override with token: */
  517. request_version = HTTP_VERSION_1_0;
  518. /* Works for single digit HTTP versions. : */
  519. http_version_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP);
  520. if (http_version_len > 7) {
  521. lws_hdr_copy(wsi, http_version_str,
  522. sizeof(http_version_str) - 1, WSI_TOKEN_HTTP);
  523. if (http_version_str[5] == '1' && http_version_str[7] == '1')
  524. request_version = HTTP_VERSION_1_1;
  525. }
  526. wsi->u.http.request_version = request_version;
  527. /* HTTP/1.1 defaults to "keep-alive", 1.0 to "close" */
  528. if (request_version == HTTP_VERSION_1_1)
  529. connection_type = HTTP_CONNECTION_KEEP_ALIVE;
  530. else
  531. connection_type = HTTP_CONNECTION_CLOSE;
  532. /* Override default if http "Connection:" header: */
  533. if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) {
  534. lws_hdr_copy(wsi, http_conn_str, sizeof(http_conn_str) - 1,
  535. WSI_TOKEN_CONNECTION);
  536. http_conn_str[sizeof(http_conn_str) - 1] = '\0';
  537. if (!strcasecmp(http_conn_str, "keep-alive"))
  538. connection_type = HTTP_CONNECTION_KEEP_ALIVE;
  539. else
  540. if (!strcasecmp(http_conn_str, "close"))
  541. connection_type = HTTP_CONNECTION_CLOSE;
  542. }
  543. wsi->u.http.connection_type = connection_type;
  544. }
  545. n = wsi->protocol->callback(wsi, LWS_CALLBACK_FILTER_HTTP_CONNECTION,
  546. wsi->user_space, uri_ptr, uri_len);
  547. if (n) {
  548. lwsl_info("LWS_CALLBACK_HTTP closing\n");
  549. return 1;
  550. }
  551. /*
  552. * if there is content supposed to be coming,
  553. * put a timeout on it having arrived
  554. */
  555. lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
  556. wsi->context->timeout_secs);
  557. #ifdef LWS_OPENSSL_SUPPORT
  558. if (wsi->redirect_to_https) {
  559. /*
  560. * we accepted http:// only so we could redirect to
  561. * https://, so issue the redirect. Create the redirection
  562. * URI from the host: header and ignore the path part
  563. */
  564. unsigned char *start = pt->serv_buf + LWS_PRE, *p = start,
  565. *end = p + 512;
  566. if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST))
  567. goto bail_nuke_ah;
  568. n = sprintf((char *)end, "https://%s/",
  569. lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
  570. n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY,
  571. end, n, &p, end);
  572. if ((int)n < 0)
  573. goto bail_nuke_ah;
  574. return lws_http_transaction_completed(wsi);
  575. }
  576. #endif
  577. #ifdef LWS_WITH_ACCESS_LOG
  578. /*
  579. * Produce Apache-compatible log string for wsi, like this:
  580. *
  581. * 2.31.234.19 - - [27/Mar/2016:03:22:44 +0800]
  582. * "GET /aep-screen.png HTTP/1.1"
  583. * 200 152987 "https://libwebsockets.org/index.html"
  584. * "Mozilla/5.0 (Macint... Chrome/49.0.2623.87 Safari/537.36"
  585. *
  586. */
  587. {
  588. static const char * const hver[] = {
  589. "http/1.0", "http/1.1", "http/2"
  590. };
  591. #ifdef LWS_USE_IPV6
  592. char ads[INET6_ADDRSTRLEN];
  593. #else
  594. char ads[INET_ADDRSTRLEN];
  595. #endif
  596. char da[64];
  597. const char *pa, *me;
  598. struct tm *tmp;
  599. time_t t = time(NULL);
  600. int l = 256;
  601. if (wsi->access_log_pending)
  602. lws_access_log(wsi);
  603. wsi->access_log.header_log = lws_malloc(l);
  604. if (wsi->access_log.header_log) {
  605. tmp = localtime(&t);
  606. if (tmp)
  607. strftime(da, sizeof(da), "%d/%b/%Y:%H:%M:%S %z", tmp);
  608. else
  609. strcpy(da, "01/Jan/1970:00:00:00 +0000");
  610. pa = lws_get_peer_simple(wsi, ads, sizeof(ads));
  611. if (!pa)
  612. pa = "(unknown)";
  613. if (meth >= 0)
  614. me = method_names[meth];
  615. else
  616. me = "unknown";
  617. lws_snprintf(wsi->access_log.header_log, l,
  618. "%s - - [%s] \"%s %s %s\"",
  619. pa, da, me, uri_ptr,
  620. hver[wsi->u.http.request_version]);
  621. l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT);
  622. if (l) {
  623. wsi->access_log.user_agent = lws_malloc(l + 2);
  624. if (wsi->access_log.user_agent)
  625. lws_hdr_copy(wsi, wsi->access_log.user_agent,
  626. l + 1, WSI_TOKEN_HTTP_USER_AGENT);
  627. else
  628. lwsl_err("OOM getting user agent\n");
  629. }
  630. wsi->access_log_pending = 1;
  631. }
  632. }
  633. #endif
  634. /* can we serve it from the mount list? */
  635. hit = lws_find_mount(wsi, uri_ptr, uri_len);
  636. if (!hit) {
  637. /* deferred cleanup and reset to protocols[0] */
  638. lwsl_info("no hit\n");
  639. if (lws_bind_protocol(wsi, &wsi->vhost->protocols[0]))
  640. return 1;
  641. n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP,
  642. wsi->user_space, uri_ptr, uri_len);
  643. goto after;
  644. }
  645. s = uri_ptr + hit->mountpoint_len;
  646. args.p = uri_ptr;
  647. args.len = uri_len;
  648. args.max_len = hit->auth_mask;
  649. args.final = 0; /* used to signal callback dealt with it */
  650. n = wsi->protocol->callback(wsi, LWS_CALLBACK_CHECK_ACCESS_RIGHTS,
  651. wsi->user_space, &args, 0);
  652. if (n) {
  653. lws_return_http_status(wsi, HTTP_STATUS_UNAUTHORIZED,
  654. NULL);
  655. goto bail_nuke_ah;
  656. }
  657. if (args.final) /* callback completely handled it well */
  658. return 0;
  659. /*
  660. * if we have a mountpoint like https://xxx.com/yyy
  661. * there is an implied / at the end for our purposes since
  662. * we can only mount on a "directory".
  663. *
  664. * But if we just go with that, the browser cannot understand
  665. * that he is actually looking down one "directory level", so
  666. * even though we give him /yyy/abc.html he acts like the
  667. * current directory level is /. So relative urls like "x.png"
  668. * wrongly look outside the mountpoint.
  669. *
  670. * Therefore if we didn't come in on a url with an explicit
  671. * / at the end, we must redirect to add it so the browser
  672. * understands he is one "directory level" down.
  673. */
  674. if ((hit->mountpoint_len > 1 ||
  675. (hit->origin_protocol == LWSMPRO_REDIR_HTTP ||
  676. hit->origin_protocol == LWSMPRO_REDIR_HTTPS)) &&
  677. (*s != '/' ||
  678. (hit->origin_protocol == LWSMPRO_REDIR_HTTP ||
  679. hit->origin_protocol == LWSMPRO_REDIR_HTTPS)) &&
  680. (hit->origin_protocol != LWSMPRO_CGI &&
  681. hit->origin_protocol != LWSMPRO_CALLBACK //&&
  682. //hit->protocol == NULL
  683. )) {
  684. unsigned char *start = pt->serv_buf + LWS_PRE,
  685. *p = start, *end = p + 512;
  686. lwsl_debug("Doing 301 '%s' org %s\n", s, hit->origin);
  687. if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST))
  688. goto bail_nuke_ah;
  689. /* > at start indicates deal with by redirect */
  690. if (hit->origin_protocol == LWSMPRO_REDIR_HTTP ||
  691. hit->origin_protocol == LWSMPRO_REDIR_HTTPS)
  692. n = lws_snprintf((char *)end, 256, "%s%s",
  693. oprot[hit->origin_protocol & 1],
  694. hit->origin);
  695. else
  696. n = lws_snprintf((char *)end, 256,
  697. "%s%s%s/", oprot[lws_is_ssl(wsi)],
  698. lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST),
  699. uri_ptr);
  700. n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY,
  701. end, n, &p, end);
  702. if ((int)n < 0)
  703. goto bail_nuke_ah;
  704. return lws_http_transaction_completed(wsi);
  705. }
  706. /*
  707. * A particular protocol callback is mounted here?
  708. *
  709. * For the duration of this http transaction, bind us to the
  710. * associated protocol
  711. */
  712. if (hit->origin_protocol == LWSMPRO_CALLBACK || hit->protocol) {
  713. const struct lws_protocols *pp;
  714. const char *name = hit->origin;
  715. if (hit->protocol)
  716. name = hit->protocol;
  717. pp = lws_vhost_name_to_protocol(wsi->vhost, name);
  718. if (!pp) {
  719. n = -1;
  720. lwsl_err("Unable to find plugin '%s'\n",
  721. hit->origin);
  722. return 1;
  723. }
  724. if (lws_bind_protocol(wsi, pp))
  725. return 1;
  726. if (hit->cgienv && wsi->protocol->callback(wsi,
  727. LWS_CALLBACK_HTTP_PMO,
  728. wsi->user_space, (void *)hit->cgienv, 0))
  729. return 1;
  730. if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
  731. n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP,
  732. wsi->user_space,
  733. uri_ptr + hit->mountpoint_len,
  734. uri_len - hit->mountpoint_len);
  735. goto after;
  736. }
  737. }
  738. #ifdef LWS_WITH_CGI
  739. /* did we hit something with a cgi:// origin? */
  740. if (hit->origin_protocol == LWSMPRO_CGI) {
  741. const char *cmd[] = {
  742. NULL, /* replace with cgi path */
  743. NULL
  744. };
  745. unsigned char *p, *end, buffer[1024];
  746. lwsl_debug("%s: cgi\n", __func__);
  747. cmd[0] = hit->origin;
  748. n = 5;
  749. if (hit->cgi_timeout)
  750. n = hit->cgi_timeout;
  751. n = lws_cgi(wsi, cmd, hit->mountpoint_len, n,
  752. hit->cgienv);
  753. if (n) {
  754. lwsl_err("%s: cgi failed\n");
  755. return -1;
  756. }
  757. p = buffer + LWS_PRE;
  758. end = p + sizeof(buffer) - LWS_PRE;
  759. if (lws_add_http_header_status(wsi, 200, &p, end))
  760. return 1;
  761. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION,
  762. (unsigned char *)"close", 5, &p, end))
  763. return 1;
  764. n = lws_write(wsi, buffer + LWS_PRE,
  765. p - (buffer + LWS_PRE),
  766. LWS_WRITE_HTTP_HEADERS);
  767. goto deal_body;
  768. }
  769. #endif
  770. n = strlen(s);
  771. if (s[0] == '\0' || (n == 1 && s[n - 1] == '/'))
  772. s = (char *)hit->def;
  773. if (!s)
  774. s = "index.html";
  775. wsi->cache_secs = hit->cache_max_age;
  776. wsi->cache_reuse = hit->cache_reusable;
  777. wsi->cache_revalidate = hit->cache_revalidate;
  778. wsi->cache_intermediaries = hit->cache_intermediaries;
  779. n = lws_http_serve(wsi, s, hit->origin, hit);
  780. if (n) {
  781. /*
  782. * lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
  783. */
  784. if (hit->protocol) {
  785. const struct lws_protocols *pp = lws_vhost_name_to_protocol(
  786. wsi->vhost, hit->protocol);
  787. if (lws_bind_protocol(wsi, pp))
  788. return 1;
  789. n = pp->callback(wsi, LWS_CALLBACK_HTTP,
  790. wsi->user_space,
  791. uri_ptr + hit->mountpoint_len,
  792. uri_len - hit->mountpoint_len);
  793. } else
  794. n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP,
  795. wsi->user_space, uri_ptr, uri_len);
  796. }
  797. after:
  798. if (n) {
  799. lwsl_info("LWS_CALLBACK_HTTP closing\n");
  800. return 1;
  801. }
  802. #ifdef LWS_WITH_CGI
  803. deal_body:
  804. #endif
  805. /*
  806. * If we're not issuing a file, check for content_length or
  807. * HTTP keep-alive. No keep-alive header allocation for
  808. * ISSUING_FILE, as this uses HTTP/1.0.
  809. *
  810. * In any case, return 0 and let lws_read decide how to
  811. * proceed based on state
  812. */
  813. if (wsi->state != LWSS_HTTP_ISSUING_FILE)
  814. /* Prepare to read body if we have a content length: */
  815. if (wsi->u.http.content_length > 0)
  816. wsi->state = LWSS_HTTP_BODY;
  817. return 0;
  818. bail_nuke_ah:
  819. /* we're closing, losing some rx is OK */
  820. wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
  821. // lwsl_notice("%s: drop1\n", __func__);
  822. lws_header_table_detach(wsi, 1);
  823. return 1;
  824. }
  825. int
  826. lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
  827. {
  828. // if (wsi->protocol == p)
  829. // return 0;
  830. if (wsi->protocol)
  831. wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,
  832. wsi->user_space, NULL, 0);
  833. if (!wsi->user_space_externally_allocated)
  834. lws_free_set_NULL(wsi->user_space);
  835. wsi->protocol = p;
  836. if (!p)
  837. return 0;
  838. if (lws_ensure_user_space(wsi))
  839. return 1;
  840. if (wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL,
  841. wsi->user_space, NULL, 0))
  842. return 1;
  843. return 0;
  844. }
  845. int
  846. lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
  847. {
  848. struct lws_context *context = lws_get_context(wsi);
  849. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  850. struct _lws_header_related hdr;
  851. struct allocated_headers *ah;
  852. int protocol_len, n = 0, hit;
  853. char protocol_list[128];
  854. char protocol_name[64];
  855. char *p;
  856. if (len >= 10000000) {
  857. lwsl_err("%s: assert: len %ld\n", __func__, (long)len);
  858. assert(0);
  859. }
  860. if (!wsi->u.hdr.ah) {
  861. lwsl_err("%s: assert: NULL ah\n", __func__);
  862. assert(0);
  863. }
  864. while (len--) {
  865. wsi->more_rx_waiting = !!len;
  866. if (wsi->mode != LWSCM_HTTP_SERVING &&
  867. wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED) {
  868. lwsl_err("%s: bad wsi mode %d\n", __func__, wsi->mode);
  869. goto bail_nuke_ah;
  870. }
  871. if (lws_parse(wsi, *(*buf)++)) {
  872. lwsl_info("lws_parse failed\n");
  873. goto bail_nuke_ah;
  874. }
  875. if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
  876. continue;
  877. lwsl_parser("%s: lws_parse sees parsing complete\n", __func__);
  878. lwsl_debug("%s: wsi->more_rx_waiting=%d\n", __func__,
  879. wsi->more_rx_waiting);
  880. /* select vhost */
  881. if (lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
  882. struct lws_vhost *vhost = lws_select_vhost(
  883. context, wsi->vhost->listen_port,
  884. lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
  885. if (vhost)
  886. wsi->vhost = vhost;
  887. } else
  888. lwsl_info("no host\n");
  889. wsi->vhost->trans++;
  890. if (!wsi->conn_stat_done) {
  891. wsi->vhost->conn++;
  892. wsi->conn_stat_done = 1;
  893. }
  894. wsi->mode = LWSCM_PRE_WS_SERVING_ACCEPT;
  895. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  896. /* is this websocket protocol or normal http 1.0? */
  897. if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
  898. if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
  899. "websocket")) {
  900. wsi->vhost->ws_upgrades++;
  901. lwsl_info("Upgrade to ws\n");
  902. goto upgrade_ws;
  903. }
  904. #ifdef LWS_USE_HTTP2
  905. if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
  906. "h2c")) {
  907. wsi->vhost->http2_upgrades++;
  908. lwsl_info("Upgrade to h2c\n");
  909. goto upgrade_h2c;
  910. }
  911. #endif
  912. lwsl_info("Unknown upgrade\n");
  913. /* dunno what he wanted to upgrade to */
  914. goto bail_nuke_ah;
  915. }
  916. /* no upgrade ack... he remained as HTTP */
  917. lwsl_info("No upgrade\n");
  918. ah = wsi->u.hdr.ah;
  919. lws_union_transition(wsi, LWSCM_HTTP_SERVING_ACCEPTED);
  920. wsi->state = LWSS_HTTP;
  921. wsi->u.http.fd = LWS_INVALID_FILE;
  922. /* expose it at the same offset as u.hdr */
  923. wsi->u.http.ah = ah;
  924. lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi,
  925. (void *)wsi->u.hdr.ah);
  926. n = lws_http_action(wsi);
  927. return n;
  928. #ifdef LWS_USE_HTTP2
  929. upgrade_h2c:
  930. if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP2_SETTINGS)) {
  931. lwsl_info("missing http2_settings\n");
  932. goto bail_nuke_ah;
  933. }
  934. lwsl_info("h2c upgrade...\n");
  935. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP2_SETTINGS);
  936. /* convert the peer's HTTP-Settings */
  937. n = lws_b64_decode_string(p, protocol_list,
  938. sizeof(protocol_list));
  939. if (n < 0) {
  940. lwsl_parser("HTTP2_SETTINGS too long\n");
  941. return 1;
  942. }
  943. /* adopt the header info */
  944. ah = wsi->u.hdr.ah;
  945. lws_union_transition(wsi, LWSCM_HTTP2_SERVING);
  946. /* http2 union member has http union struct at start */
  947. wsi->u.http.ah = ah;
  948. lws_http2_init(&wsi->u.http2.peer_settings);
  949. lws_http2_init(&wsi->u.http2.my_settings);
  950. /* HTTP2 union */
  951. lws_http2_interpret_settings_payload(&wsi->u.http2.peer_settings,
  952. (unsigned char *)protocol_list, n);
  953. strcpy(protocol_list,
  954. "HTTP/1.1 101 Switching Protocols\x0d\x0a"
  955. "Connection: Upgrade\x0d\x0a"
  956. "Upgrade: h2c\x0d\x0a\x0d\x0a");
  957. n = lws_issue_raw(wsi, (unsigned char *)protocol_list,
  958. strlen(protocol_list));
  959. if (n != strlen(protocol_list)) {
  960. lwsl_debug("http2 switch: ERROR writing to socket\n");
  961. return 1;
  962. }
  963. wsi->state = LWSS_HTTP2_AWAIT_CLIENT_PREFACE;
  964. return 0;
  965. #endif
  966. upgrade_ws:
  967. if (!wsi->protocol)
  968. lwsl_err("NULL protocol at lws_read\n");
  969. /*
  970. * It's websocket
  971. *
  972. * Select the first protocol we support from the list
  973. * the client sent us.
  974. *
  975. * Copy it to remove header fragmentation
  976. */
  977. if (lws_hdr_copy(wsi, protocol_list, sizeof(protocol_list) - 1,
  978. WSI_TOKEN_PROTOCOL) < 0) {
  979. lwsl_err("protocol list too long");
  980. goto bail_nuke_ah;
  981. }
  982. protocol_len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL);
  983. protocol_list[protocol_len] = '\0';
  984. p = protocol_list;
  985. hit = 0;
  986. while (*p && !hit) {
  987. n = 0;
  988. while (n < sizeof(protocol_name) - 1 && *p && *p !=',')
  989. protocol_name[n++] = *p++;
  990. protocol_name[n] = '\0';
  991. if (*p)
  992. p++;
  993. lwsl_info("checking %s\n", protocol_name);
  994. n = 0;
  995. while (wsi->vhost->protocols[n].callback) {
  996. if (wsi->vhost->protocols[n].name &&
  997. !strcmp(wsi->vhost->protocols[n].name,
  998. protocol_name)) {
  999. wsi->protocol = &wsi->vhost->protocols[n];
  1000. hit = 1;
  1001. break;
  1002. }
  1003. n++;
  1004. }
  1005. }
  1006. /* we didn't find a protocol he wanted? */
  1007. if (!hit) {
  1008. if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL)) {
  1009. lwsl_info("No protocol from \"%s\" supported\n",
  1010. protocol_list);
  1011. goto bail_nuke_ah;
  1012. }
  1013. /*
  1014. * some clients only have one protocol and
  1015. * do not send the protocol list header...
  1016. * allow it and match to the vhost's default
  1017. * protocol (which itself defaults to zero)
  1018. */
  1019. lwsl_info("defaulting to prot handler %d\n",
  1020. wsi->vhost->default_protocol_index);
  1021. n = 0;
  1022. wsi->protocol = &wsi->vhost->protocols[
  1023. (int)wsi->vhost->default_protocol_index];
  1024. }
  1025. /* allocate wsi->user storage */
  1026. if (lws_ensure_user_space(wsi))
  1027. goto bail_nuke_ah;
  1028. /*
  1029. * Give the user code a chance to study the request and
  1030. * have the opportunity to deny it
  1031. */
  1032. if ((wsi->protocol->callback)(wsi,
  1033. LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
  1034. wsi->user_space,
  1035. lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) {
  1036. lwsl_warn("User code denied connection\n");
  1037. goto bail_nuke_ah;
  1038. }
  1039. /*
  1040. * Perform the handshake according to the protocol version the
  1041. * client announced
  1042. */
  1043. switch (wsi->ietf_spec_revision) {
  1044. case 13:
  1045. lwsl_parser("lws_parse calling handshake_04\n");
  1046. if (handshake_0405(context, wsi)) {
  1047. lwsl_info("hs0405 has failed the connection\n");
  1048. goto bail_nuke_ah;
  1049. }
  1050. break;
  1051. default:
  1052. lwsl_info("Unknown client spec version %d\n",
  1053. wsi->ietf_spec_revision);
  1054. goto bail_nuke_ah;
  1055. }
  1056. /*
  1057. * stitch protocol choice into the vh protocol linked list
  1058. * We always insert ourselves at the start of the list
  1059. *
  1060. * X <-> B
  1061. * X <-> pAn <-> pB
  1062. */
  1063. //lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
  1064. // __func__,
  1065. // wsi->vhost->same_vh_protocol_list[n],
  1066. // wsi->same_vh_protocol_prev);
  1067. wsi->same_vh_protocol_prev = /* guy who points to us */
  1068. &wsi->vhost->same_vh_protocol_list[n];
  1069. wsi->same_vh_protocol_next = /* old first guy is our next */
  1070. wsi->vhost->same_vh_protocol_list[n];
  1071. /* we become the new first guy */
  1072. wsi->vhost->same_vh_protocol_list[n] = wsi;
  1073. if (wsi->same_vh_protocol_next)
  1074. /* old first guy points back to us now */
  1075. wsi->same_vh_protocol_next->same_vh_protocol_prev =
  1076. &wsi->same_vh_protocol_next;
  1077. /* we are upgrading to ws, so http/1.1 and keepalive +
  1078. * pipelined header considerations about keeping the ah around
  1079. * no longer apply. However it's common for the first ws
  1080. * protocol data to have been coalesced with the browser
  1081. * upgrade request and to already be in the ah rx buffer.
  1082. */
  1083. lwsl_info("%s: %p: inheriting ah in ws mode (rxpos:%d, rxlen:%d)\n",
  1084. __func__, wsi, wsi->u.hdr.ah->rxpos,
  1085. wsi->u.hdr.ah->rxlen);
  1086. lws_pt_lock(pt);
  1087. hdr = wsi->u.hdr;
  1088. lws_union_transition(wsi, LWSCM_WS_SERVING);
  1089. /*
  1090. * first service is WS mode will notice this, use the RX and
  1091. * then detach the ah (caution: we are not in u.hdr union
  1092. * mode any more then... ah_temp member is at start the same
  1093. * though)
  1094. *
  1095. * Because rxpos/rxlen shows something in the ah, we will get
  1096. * service guaranteed next time around the event loop
  1097. *
  1098. * All union members begin with hdr, so we can use it even
  1099. * though we transitioned to ws union mode (the ah detach
  1100. * code uses it anyway).
  1101. */
  1102. wsi->u.hdr = hdr;
  1103. lws_pt_unlock(pt);
  1104. lws_restart_ws_ping_pong_timer(wsi);
  1105. /*
  1106. * create the frame buffer for this connection according to the
  1107. * size mentioned in the protocol definition. If 0 there, use
  1108. * a big default for compatibility
  1109. */
  1110. n = wsi->protocol->rx_buffer_size;
  1111. if (!n)
  1112. n = context->pt_serv_buf_size;
  1113. n += LWS_PRE;
  1114. wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */);
  1115. if (!wsi->u.ws.rx_ubuf) {
  1116. lwsl_err("Out of Mem allocating rx buffer %d\n", n);
  1117. return 1;
  1118. }
  1119. wsi->u.ws.rx_ubuf_alloc = n;
  1120. lwsl_debug("Allocating RX buffer %d\n", n);
  1121. #if LWS_POSIX
  1122. if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF,
  1123. (const char *)&n, sizeof n)) {
  1124. lwsl_warn("Failed to set SNDBUF to %d", n);
  1125. return 1;
  1126. }
  1127. #endif
  1128. lwsl_parser("accepted v%02d connection\n",
  1129. wsi->ietf_spec_revision);
  1130. /* notify user code that we're ready to roll */
  1131. if (wsi->protocol->callback)
  1132. if (wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED,
  1133. wsi->user_space,
  1134. #ifdef LWS_OPENSSL_SUPPORT
  1135. wsi->ssl,
  1136. #else
  1137. NULL,
  1138. #endif
  1139. 0))
  1140. return 1;
  1141. /* !!! drop ah unreservedly after ESTABLISHED */
  1142. if (!wsi->more_rx_waiting) {
  1143. wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
  1144. //lwsl_notice("%p: dropping ah EST\n", wsi);
  1145. lws_header_table_detach(wsi, 1);
  1146. }
  1147. return 0;
  1148. } /* while all chars are handled */
  1149. return 0;
  1150. bail_nuke_ah:
  1151. /* drop the header info */
  1152. /* we're closing, losing some rx is OK */
  1153. wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
  1154. //lwsl_notice("%s: drop2\n", __func__);
  1155. lws_header_table_detach(wsi, 1);
  1156. return 1;
  1157. }
  1158. static int
  1159. lws_get_idlest_tsi(struct lws_context *context)
  1160. {
  1161. unsigned int lowest = ~0;
  1162. int n = 0, hit = -1;
  1163. for (; n < context->count_threads; n++) {
  1164. if ((unsigned int)context->pt[n].fds_count !=
  1165. context->fd_limit_per_thread - 1 &&
  1166. (unsigned int)context->pt[n].fds_count < lowest) {
  1167. lowest = context->pt[n].fds_count;
  1168. hit = n;
  1169. }
  1170. }
  1171. return hit;
  1172. }
  1173. struct lws *
  1174. lws_create_new_server_wsi(struct lws_vhost *vhost)
  1175. {
  1176. struct lws *new_wsi;
  1177. int n = lws_get_idlest_tsi(vhost->context);
  1178. if (n < 0) {
  1179. lwsl_err("no space for new conn\n");
  1180. return NULL;
  1181. }
  1182. new_wsi = lws_zalloc(sizeof(struct lws));
  1183. if (new_wsi == NULL) {
  1184. lwsl_err("Out of memory for new connection\n");
  1185. return NULL;
  1186. }
  1187. new_wsi->tsi = n;
  1188. lwsl_info("Accepted %p to tsi %d\n", new_wsi, new_wsi->tsi);
  1189. new_wsi->vhost = vhost;
  1190. new_wsi->context = vhost->context;
  1191. new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
  1192. new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
  1193. /* initialize the instance struct */
  1194. new_wsi->state = LWSS_HTTP;
  1195. new_wsi->mode = LWSCM_HTTP_SERVING;
  1196. new_wsi->hdr_parsing_completed = 0;
  1197. #ifdef LWS_OPENSSL_SUPPORT
  1198. new_wsi->use_ssl = LWS_SSL_ENABLED(vhost);
  1199. #endif
  1200. /*
  1201. * these can only be set once the protocol is known
  1202. * we set an unestablished connection's protocol pointer
  1203. * to the start of the supported list, so it can look
  1204. * for matching ones during the handshake
  1205. */
  1206. new_wsi->protocol = vhost->protocols;
  1207. new_wsi->user_space = NULL;
  1208. new_wsi->ietf_spec_revision = 0;
  1209. new_wsi->sock = LWS_SOCK_INVALID;
  1210. vhost->context->count_wsi_allocated++;
  1211. /*
  1212. * outermost create notification for wsi
  1213. * no user_space because no protocol selection
  1214. */
  1215. vhost->protocols[0].callback(new_wsi, LWS_CALLBACK_WSI_CREATE,
  1216. NULL, NULL, 0);
  1217. return new_wsi;
  1218. }
  1219. LWS_VISIBLE int LWS_WARN_UNUSED_RESULT
  1220. lws_http_transaction_completed(struct lws *wsi)
  1221. {
  1222. int n = NO_PENDING_TIMEOUT;
  1223. lws_access_log(wsi);
  1224. lwsl_info("%s: wsi %p\n", __func__, wsi);
  1225. /* if we can't go back to accept new headers, drop the connection */
  1226. if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
  1227. lwsl_info("%s: %p: close connection\n", __func__, wsi);
  1228. return 1;
  1229. }
  1230. if (lws_bind_protocol(wsi, &wsi->vhost->protocols[0]))
  1231. return 1;
  1232. /* otherwise set ourselves up ready to go again */
  1233. wsi->state = LWSS_HTTP;
  1234. wsi->mode = LWSCM_HTTP_SERVING;
  1235. wsi->u.http.content_length = 0;
  1236. wsi->u.http.content_remain = 0;
  1237. wsi->hdr_parsing_completed = 0;
  1238. #ifdef LWS_WITH_ACCESS_LOG
  1239. wsi->access_log.sent = 0;
  1240. #endif
  1241. if (wsi->vhost->keepalive_timeout)
  1242. n = PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE;
  1243. lws_set_timeout(wsi, n, wsi->vhost->keepalive_timeout);
  1244. /*
  1245. * We already know we are on http1.1 / keepalive and the next thing
  1246. * coming will be another header set.
  1247. *
  1248. * If there is no pending rx and we still have the ah, drop it and
  1249. * reacquire a new ah when the new headers start to arrive. (Otherwise
  1250. * we needlessly hog an ah indefinitely.)
  1251. *
  1252. * However if there is pending rx and we know from the keepalive state
  1253. * that is already at least the start of another header set, simply
  1254. * reset the existing header table and keep it.
  1255. */
  1256. if (wsi->u.hdr.ah) {
  1257. lwsl_info("%s: wsi->more_rx_waiting=%d\n", __func__,
  1258. wsi->more_rx_waiting);
  1259. if (!wsi->more_rx_waiting) {
  1260. wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
  1261. lws_header_table_detach(wsi, 1);
  1262. } else
  1263. lws_header_table_reset(wsi, 1);
  1264. }
  1265. /* If we're (re)starting on headers, need other implied init */
  1266. wsi->u.hdr.ues = URIES_IDLE;
  1267. lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi);
  1268. return 0;
  1269. }
  1270. struct lws *
  1271. lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd)
  1272. {
  1273. struct lws_context *context = vh->context;
  1274. struct lws *new_wsi = lws_create_new_server_wsi(vh);
  1275. if (!new_wsi) {
  1276. compatible_close(accept_fd);
  1277. return NULL;
  1278. }
  1279. //lwsl_notice("%s: new wsi %p, sockfd %d, cb %p\n", __func__, new_wsi, accept_fd, context->vhost_list->protocols[0].callback);
  1280. new_wsi->sock = accept_fd;
  1281. /* the transport is accepted... give him time to negotiate */
  1282. lws_set_timeout(new_wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
  1283. context->timeout_secs);
  1284. #if LWS_POSIX == 0
  1285. #if defined(LWS_WITH_ESP8266)
  1286. esp8266_tcp_stream_accept(accept_fd, new_wsi);
  1287. #else
  1288. mbed3_tcp_stream_accept(accept_fd, new_wsi);
  1289. #endif
  1290. #endif
  1291. /*
  1292. * A new connection was accepted. Give the user a chance to
  1293. * set properties of the newly created wsi. There's no protocol
  1294. * selected yet so we issue this to protocols[0]
  1295. */
  1296. if ((context->vhost_list->protocols[0].callback)(new_wsi,
  1297. LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, NULL, NULL, 0)) {
  1298. /* force us off the timeout list by hand */
  1299. lws_set_timeout(new_wsi, NO_PENDING_TIMEOUT, 0);
  1300. compatible_close(new_wsi->sock);
  1301. lws_free(new_wsi);
  1302. return NULL;
  1303. }
  1304. lws_libev_accept(new_wsi, new_wsi->sock);
  1305. lws_libuv_accept(new_wsi, new_wsi->sock);
  1306. if (!LWS_SSL_ENABLED(new_wsi->vhost)) {
  1307. if (insert_wsi_socket_into_fds(context, new_wsi)) {
  1308. lwsl_err("%s: fail inserting socket\n", __func__);
  1309. goto fail;
  1310. }
  1311. } else {
  1312. new_wsi->mode = LWSCM_SSL_INIT;
  1313. if (lws_server_socket_service_ssl(new_wsi, accept_fd)) {
  1314. lwsl_err("%s: fail ssl negotiation\n", __func__);
  1315. goto fail;
  1316. }
  1317. }
  1318. if (!lws_header_table_attach(new_wsi, 0))
  1319. lwsl_debug("Attached ah immediately\n");
  1320. return new_wsi;
  1321. fail:
  1322. lws_close_free_wsi(new_wsi, LWS_CLOSE_STATUS_NOSTATUS);
  1323. return NULL;
  1324. }
  1325. LWS_VISIBLE struct lws *
  1326. lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd)
  1327. {
  1328. return lws_adopt_socket_vhost(context->vhost_list, accept_fd);
  1329. }
  1330. LWS_VISIBLE LWS_EXTERN struct lws *
  1331. lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
  1332. const char *readbuf, size_t len)
  1333. {
  1334. struct lws *wsi = lws_adopt_socket(context, accept_fd);
  1335. struct lws_context_per_thread *pt;
  1336. struct allocated_headers *ah;
  1337. struct lws_pollfd *pfd;
  1338. if (!wsi)
  1339. return NULL;
  1340. if (!readbuf)
  1341. return wsi;
  1342. if (len > sizeof(ah->rx)) {
  1343. lwsl_err("%s: rx in too big\n", __func__);
  1344. goto bail;
  1345. }
  1346. /*
  1347. * we can't process the initial read data until we can attach an ah.
  1348. *
  1349. * if one is available, get it and place the data in his ah rxbuf...
  1350. * wsi with ah that have pending rxbuf get auto-POLLIN service.
  1351. *
  1352. * no autoservice because we didn't get a chance to attach the
  1353. * readbuf data to wsi or ah yet, and we will do it next if we get
  1354. * the ah.
  1355. */
  1356. if (wsi->u.hdr.ah || !lws_header_table_attach(wsi, 0)) {
  1357. ah = wsi->u.hdr.ah;
  1358. memcpy(ah->rx, readbuf, len);
  1359. ah->rxpos = 0;
  1360. ah->rxlen = len;
  1361. lwsl_notice("%s: calling service on readbuf ah\n", __func__);
  1362. pt = &context->pt[(int)wsi->tsi];
  1363. /* unlike a normal connect, we have the headers already
  1364. * (or the first part of them anyway).
  1365. * libuv won't come back and service us without a network
  1366. * event, so we need to do the header service right here.
  1367. */
  1368. pfd = &pt->fds[wsi->position_in_fds_table];
  1369. pfd->revents |= LWS_POLLIN;
  1370. lwsl_err("%s: calling service\n", __func__);
  1371. if (lws_service_fd_tsi(context, pfd, wsi->tsi))
  1372. /* service closed us */
  1373. return NULL;
  1374. return wsi;
  1375. }
  1376. lwsl_err("%s: deferring handling ah\n", __func__);
  1377. /*
  1378. * hum if no ah came, we are on the wait list and must defer
  1379. * dealing with this until the ah arrives.
  1380. *
  1381. * later successful lws_header_table_attach() will apply the
  1382. * below to the rx buffer (via lws_header_table_reset()).
  1383. */
  1384. wsi->u.hdr.preamble_rx = lws_malloc(len);
  1385. if (!wsi->u.hdr.preamble_rx) {
  1386. lwsl_err("OOM\n");
  1387. goto bail;
  1388. }
  1389. memcpy(wsi->u.hdr.preamble_rx, readbuf, len);
  1390. wsi->u.hdr.preamble_rx_len = len;
  1391. return wsi;
  1392. bail:
  1393. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  1394. return NULL;
  1395. }
  1396. LWS_VISIBLE int
  1397. lws_server_socket_service(struct lws_context *context, struct lws *wsi,
  1398. struct lws_pollfd *pollfd)
  1399. {
  1400. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  1401. lws_sockfd_type accept_fd = LWS_SOCK_INVALID;
  1402. struct allocated_headers *ah;
  1403. #if LWS_POSIX
  1404. struct sockaddr_in cli_addr;
  1405. socklen_t clilen;
  1406. #endif
  1407. int n, len;
  1408. // lwsl_notice("%s: mode %d\n", __func__, wsi->mode);
  1409. switch (wsi->mode) {
  1410. case LWSCM_HTTP_SERVING:
  1411. case LWSCM_HTTP_SERVING_ACCEPTED:
  1412. case LWSCM_HTTP2_SERVING:
  1413. /* handle http headers coming in */
  1414. /* pending truncated sends have uber priority */
  1415. if (wsi->trunc_len) {
  1416. if (!(pollfd->revents & LWS_POLLOUT))
  1417. break;
  1418. if (lws_issue_raw(wsi, wsi->trunc_alloc +
  1419. wsi->trunc_offset,
  1420. wsi->trunc_len) < 0)
  1421. goto fail;
  1422. /*
  1423. * we can't afford to allow input processing to send
  1424. * something new, so spin around he event loop until
  1425. * he doesn't have any partials
  1426. */
  1427. break;
  1428. }
  1429. /* any incoming data ready? */
  1430. if (!(pollfd->revents & pollfd->events & LWS_POLLIN))
  1431. goto try_pollout;
  1432. /*
  1433. * If we previously just did POLLIN when IN and OUT were
  1434. * signalled (because POLLIN processing may have used up
  1435. * the POLLOUT), don't let that happen twice in a row...
  1436. * next time we see the situation favour POLLOUT
  1437. */
  1438. #if !defined(LWS_WITH_ESP8266)
  1439. if (wsi->favoured_pollin &&
  1440. (pollfd->revents & pollfd->events & LWS_POLLOUT)) {
  1441. wsi->favoured_pollin = 0;
  1442. goto try_pollout;
  1443. }
  1444. #endif
  1445. /* these states imply we MUST have an ah attached */
  1446. if (wsi->state == LWSS_HTTP ||
  1447. wsi->state == LWSS_HTTP_ISSUING_FILE ||
  1448. wsi->state == LWSS_HTTP_HEADERS) {
  1449. if (!wsi->u.hdr.ah) {
  1450. //lwsl_err("wsi %p: missing ah\n", wsi);
  1451. /* no autoservice beacuse we will do it next */
  1452. if (lws_header_table_attach(wsi, 0)) {
  1453. lwsl_err("wsi %p: failed to acquire ah\n", wsi);
  1454. goto try_pollout;
  1455. }
  1456. }
  1457. ah = wsi->u.hdr.ah;
  1458. //lwsl_notice("%s: %p: rxpos:%d rxlen:%d\n", __func__, wsi,
  1459. // ah->rxpos, ah->rxlen);
  1460. /* if nothing in ah rx buffer, get some fresh rx */
  1461. if (ah->rxpos == ah->rxlen) {
  1462. ah->rxlen = lws_ssl_capable_read(wsi, ah->rx,
  1463. sizeof(ah->rx));
  1464. ah->rxpos = 0;
  1465. //lwsl_notice("%s: wsi %p, ah->rxlen = %d\r\n",
  1466. // __func__, wsi, ah->rxlen);
  1467. switch (ah->rxlen) {
  1468. case 0:
  1469. lwsl_info("%s: read 0 len\n", __func__);
  1470. /* lwsl_info(" state=%d\n", wsi->state); */
  1471. // if (!wsi->hdr_parsing_completed)
  1472. // lws_header_table_detach(wsi);
  1473. /* fallthru */
  1474. case LWS_SSL_CAPABLE_ERROR:
  1475. goto fail;
  1476. case LWS_SSL_CAPABLE_MORE_SERVICE:
  1477. ah->rxlen = ah->rxpos = 0;
  1478. goto try_pollout;
  1479. }
  1480. }
  1481. if (!(ah->rxpos != ah->rxlen && ah->rxlen)) {
  1482. lwsl_err("%s: assert: rxpos %d, rxlen %d\n",
  1483. __func__, ah->rxpos, ah->rxlen);
  1484. assert(0);
  1485. }
  1486. /* just ignore incoming if waiting for close */
  1487. if (wsi->state != LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
  1488. n = lws_read(wsi, ah->rx + ah->rxpos,
  1489. ah->rxlen - ah->rxpos);
  1490. if (n < 0) /* we closed wsi */
  1491. return 1;
  1492. if (wsi->u.hdr.ah) {
  1493. if ( wsi->u.hdr.ah->rxlen)
  1494. wsi->u.hdr.ah->rxpos += n;
  1495. lwsl_debug("%s: wsi %p: ah read rxpos %d, rxlen %d\n", __func__, wsi, wsi->u.hdr.ah->rxpos, wsi->u.hdr.ah->rxlen);
  1496. if (wsi->u.hdr.ah->rxpos == wsi->u.hdr.ah->rxlen &&
  1497. (wsi->mode != LWSCM_HTTP_SERVING &&
  1498. wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
  1499. wsi->mode != LWSCM_HTTP2_SERVING))
  1500. lws_header_table_detach(wsi, 1);
  1501. }
  1502. break;
  1503. }
  1504. goto try_pollout;
  1505. }
  1506. len = lws_ssl_capable_read(wsi, pt->serv_buf,
  1507. context->pt_serv_buf_size);
  1508. lwsl_notice("%s: wsi %p read %d\r\n", __func__, wsi, len);
  1509. switch (len) {
  1510. case 0:
  1511. lwsl_info("%s: read 0 len\n", __func__);
  1512. /* lwsl_info(" state=%d\n", wsi->state); */
  1513. // if (!wsi->hdr_parsing_completed)
  1514. // lws_header_table_detach(wsi);
  1515. /* fallthru */
  1516. case LWS_SSL_CAPABLE_ERROR:
  1517. goto fail;
  1518. case LWS_SSL_CAPABLE_MORE_SERVICE:
  1519. goto try_pollout;
  1520. }
  1521. /* just ignore incoming if waiting for close */
  1522. if (wsi->state != LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
  1523. /*
  1524. * this may want to send
  1525. * (via HTTP callback for example)
  1526. */
  1527. n = lws_read(wsi, pt->serv_buf, len);
  1528. if (n < 0) /* we closed wsi */
  1529. return 1;
  1530. /*
  1531. * he may have used up the
  1532. * writability above, if we will defer POLLOUT
  1533. * processing in favour of POLLIN, note it
  1534. */
  1535. if (pollfd->revents & LWS_POLLOUT)
  1536. wsi->favoured_pollin = 1;
  1537. break;
  1538. }
  1539. try_pollout:
  1540. /* this handles POLLOUT for http serving fragments */
  1541. if (!(pollfd->revents & LWS_POLLOUT))
  1542. break;
  1543. /* one shot */
  1544. if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
  1545. lwsl_notice("%s a\n", __func__);
  1546. goto fail;
  1547. }
  1548. if (!wsi->hdr_parsing_completed)
  1549. break;
  1550. if (wsi->state != LWSS_HTTP_ISSUING_FILE) {
  1551. n = user_callback_handle_rxflow(wsi->protocol->callback,
  1552. wsi, LWS_CALLBACK_HTTP_WRITEABLE,
  1553. wsi->user_space, NULL, 0);
  1554. if (n < 0) {
  1555. lwsl_info("writeable_fail\n");
  1556. goto fail;
  1557. }
  1558. break;
  1559. }
  1560. /* >0 == completion, <0 == error */
  1561. n = lws_serve_http_file_fragment(wsi);
  1562. if (n < 0 || (n > 0 && lws_http_transaction_completed(wsi))) {
  1563. lwsl_info("completed\n");
  1564. goto fail;
  1565. }
  1566. break;
  1567. case LWSCM_SERVER_LISTENER:
  1568. #if LWS_POSIX
  1569. /* pollin means a client has connected to us then */
  1570. do {
  1571. if (!(pollfd->revents & LWS_POLLIN) || !(pollfd->events & LWS_POLLIN))
  1572. break;
  1573. /* listen socket got an unencrypted connection... */
  1574. clilen = sizeof(cli_addr);
  1575. lws_latency_pre(context, wsi);
  1576. accept_fd = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
  1577. &clilen);
  1578. lws_latency(context, wsi, "listener accept", accept_fd,
  1579. accept_fd >= 0);
  1580. if (accept_fd < 0) {
  1581. if (LWS_ERRNO == LWS_EAGAIN ||
  1582. LWS_ERRNO == LWS_EWOULDBLOCK) {
  1583. lwsl_err("accept asks to try again\n");
  1584. break;
  1585. }
  1586. lwsl_err("ERROR on accept: %s\n", strerror(LWS_ERRNO));
  1587. break;
  1588. }
  1589. lws_plat_set_socket_options(wsi->vhost, accept_fd);
  1590. lwsl_debug("accepted new conn port %u on fd=%d\n",
  1591. ntohs(cli_addr.sin_port), accept_fd);
  1592. #else
  1593. /* not very beautiful... */
  1594. accept_fd = (lws_sockfd_type)pollfd;
  1595. #endif
  1596. /*
  1597. * look at who we connected to and give user code a chance
  1598. * to reject based on client IP. There's no protocol selected
  1599. * yet so we issue this to protocols[0]
  1600. */
  1601. if ((wsi->vhost->protocols[0].callback)(wsi,
  1602. LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
  1603. NULL, (void *)(long)accept_fd, 0)) {
  1604. lwsl_debug("Callback denied network connection\n");
  1605. compatible_close(accept_fd);
  1606. break;
  1607. }
  1608. if (!lws_adopt_socket_vhost(wsi->vhost, accept_fd))
  1609. /* already closed cleanly as necessary */
  1610. return 1;
  1611. #if LWS_POSIX
  1612. } while (pt->fds_count < context->fd_limit_per_thread - 1 &&
  1613. lws_poll_listen_fd(&pt->fds[wsi->position_in_fds_table]) > 0);
  1614. #endif
  1615. return 0;
  1616. default:
  1617. break;
  1618. }
  1619. if (!lws_server_socket_service_ssl(wsi, accept_fd))
  1620. return 0;
  1621. fail:
  1622. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  1623. return 1;
  1624. }
  1625. LWS_VISIBLE int
  1626. lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
  1627. const char *other_headers, int other_headers_len)
  1628. {
  1629. static const char * const intermediates[] = { "private", "public" };
  1630. struct lws_context *context = lws_get_context(wsi);
  1631. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  1632. char cache_control[50], *cc = "no-store";
  1633. unsigned char *response = pt->serv_buf + LWS_PRE;
  1634. unsigned char *p = response;
  1635. unsigned char *end = p + context->pt_serv_buf_size - LWS_PRE;
  1636. int ret = 0, cclen = 8;
  1637. wsi->u.http.fd = lws_plat_file_open(wsi, file, &wsi->u.http.filelen,
  1638. O_RDONLY);
  1639. if (wsi->u.http.fd == LWS_INVALID_FILE) {
  1640. lwsl_err("Unable to open '%s'\n", file);
  1641. return -1;
  1642. }
  1643. if (lws_add_http_header_status(wsi, 200, &p, end))
  1644. return -1;
  1645. if (content_type && content_type[0]) {
  1646. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
  1647. (unsigned char *)content_type,
  1648. strlen(content_type), &p, end))
  1649. return -1;
  1650. }
  1651. if (!wsi->sending_chunked) {
  1652. if (lws_add_http_header_content_length(wsi, wsi->u.http.filelen, &p, end))
  1653. return -1;
  1654. } else {
  1655. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_TRANSFER_ENCODING,
  1656. (unsigned char *)"chunked",
  1657. 7, &p, end))
  1658. return -1;
  1659. }
  1660. if (wsi->cache_secs && wsi->cache_reuse) {
  1661. if (wsi->cache_revalidate) {
  1662. cc = cache_control;
  1663. cclen = sprintf(cache_control, "%s max-age: %u",
  1664. intermediates[wsi->cache_intermediaries],
  1665. wsi->cache_secs);
  1666. } else {
  1667. cc = "no-cache";
  1668. cclen = 8;
  1669. }
  1670. }
  1671. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CACHE_CONTROL,
  1672. (unsigned char *)cc, cclen, &p, end))
  1673. return -1;
  1674. if (wsi->u.http.connection_type == HTTP_CONNECTION_KEEP_ALIVE)
  1675. if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION,
  1676. (unsigned char *)"keep-alive", 10, &p, end))
  1677. return -1;
  1678. if (other_headers) {
  1679. if ((end - p) < other_headers_len)
  1680. return -1;
  1681. memcpy(p, other_headers, other_headers_len);
  1682. p += other_headers_len;
  1683. }
  1684. if (lws_finalize_http_header(wsi, &p, end))
  1685. return -1;
  1686. ret = lws_write(wsi, response, p - response, LWS_WRITE_HTTP_HEADERS);
  1687. if (ret != (p - response)) {
  1688. lwsl_err("_write returned %d from %d\n", ret, (p - response));
  1689. return -1;
  1690. }
  1691. wsi->u.http.filepos = 0;
  1692. wsi->state = LWSS_HTTP_ISSUING_FILE;
  1693. return lws_serve_http_file_fragment(wsi);
  1694. }
  1695. int
  1696. lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
  1697. {
  1698. int m;
  1699. lwsl_parser("%s: received %d byte packet\n", __func__, (int)len);
  1700. #if 0
  1701. lwsl_hexdump(*buf, len);
  1702. #endif
  1703. /* let the rx protocol state machine have as much as it needs */
  1704. while (len) {
  1705. /*
  1706. * we were accepting input but now we stopped doing so
  1707. */
  1708. if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) {
  1709. lws_rxflow_cache(wsi, *buf, 0, len);
  1710. lwsl_parser("%s: cached %d\n", __func__, len);
  1711. return 1;
  1712. }
  1713. if (wsi->u.ws.rx_draining_ext) {
  1714. m = lws_rx_sm(wsi, 0);
  1715. if (m < 0)
  1716. return -1;
  1717. continue;
  1718. }
  1719. /* account for what we're using in rxflow buffer */
  1720. if (wsi->rxflow_buffer)
  1721. wsi->rxflow_pos++;
  1722. /* consume payload bytes efficiently */
  1723. if (wsi->lws_rx_parse_state ==
  1724. LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED) {
  1725. m = lws_payload_until_length_exhausted(wsi, buf, &len);
  1726. if (wsi->rxflow_buffer)
  1727. wsi->rxflow_pos += m;
  1728. }
  1729. /* process the byte */
  1730. m = lws_rx_sm(wsi, *(*buf)++);
  1731. if (m < 0)
  1732. return -1;
  1733. len--;
  1734. }
  1735. lwsl_parser("%s: exit with %d unused\n", __func__, (int)len);
  1736. return 0;
  1737. }
  1738. LWS_VISIBLE void
  1739. lws_server_get_canonical_hostname(struct lws_context *context,
  1740. struct lws_context_creation_info *info)
  1741. {
  1742. if (lws_check_opt(info->options, LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME))
  1743. return;
  1744. #if LWS_POSIX
  1745. /* find canonical hostname */
  1746. gethostname((char *)context->canonical_hostname,
  1747. sizeof(context->canonical_hostname) - 1);
  1748. lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname);
  1749. #else
  1750. (void)context;
  1751. #endif
  1752. }
  1753. #define LWS_MAX_ELEM_NAME 32
  1754. enum urldecode_stateful {
  1755. US_NAME,
  1756. US_IDLE,
  1757. US_PC1,
  1758. US_PC2,
  1759. MT_LOOK_BOUND_IN,
  1760. MT_HNAME,
  1761. MT_DISP,
  1762. MT_TYPE,
  1763. MT_IGNORE1,
  1764. MT_IGNORE2,
  1765. };
  1766. static const char * const mp_hdr[] = {
  1767. "content-disposition: ",
  1768. "content-type: ",
  1769. "\x0d\x0a"
  1770. };
  1771. typedef int (*lws_urldecode_stateful_cb)(void *data,
  1772. const char *name, char **buf, int len, int final);
  1773. struct lws_urldecode_stateful {
  1774. char *out;
  1775. void *data;
  1776. char name[LWS_MAX_ELEM_NAME];
  1777. char temp[LWS_MAX_ELEM_NAME];
  1778. char content_type[32];
  1779. char content_disp[32];
  1780. char content_disp_filename[256];
  1781. char mime_boundary[128];
  1782. int out_len;
  1783. int pos;
  1784. int hdr_idx;
  1785. int mp;
  1786. unsigned int multipart_form_data:1;
  1787. unsigned int inside_quote:1;
  1788. unsigned int subname:1;
  1789. unsigned int boundary_real_crlf:1;
  1790. enum urldecode_stateful state;
  1791. lws_urldecode_stateful_cb output;
  1792. };
  1793. static struct lws_urldecode_stateful *
  1794. lws_urldecode_s_create(struct lws *wsi, char *out, int out_len, void *data,
  1795. lws_urldecode_stateful_cb output)
  1796. {
  1797. struct lws_urldecode_stateful *s = lws_zalloc(sizeof(*s));
  1798. char buf[200], *p;
  1799. int m = 0;
  1800. if (!s)
  1801. return NULL;
  1802. s->out = out;
  1803. s->out_len = out_len;
  1804. s->output = output;
  1805. s->pos = 0;
  1806. s->mp = 0;
  1807. s->state = US_NAME;
  1808. s->name[0] = '\0';
  1809. s->data = data;
  1810. if (lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_CONTENT_TYPE) > 0) {
  1811. /* multipart/form-data; boundary=----WebKitFormBoundarycc7YgAPEIHvgE9Bf */
  1812. if (!strncmp(buf, "multipart/form-data", 19)) {
  1813. s->multipart_form_data = 1;
  1814. s->state = MT_LOOK_BOUND_IN;
  1815. s->mp = 2;
  1816. p = strstr(buf, "boundary=");
  1817. if (p) {
  1818. p += 9;
  1819. s->mime_boundary[m++] = '\x0d';
  1820. s->mime_boundary[m++] = '\x0a';
  1821. s->mime_boundary[m++] = '-';
  1822. s->mime_boundary[m++] = '-';
  1823. while (m < sizeof(s->mime_boundary) - 1 &&
  1824. *p && *p != ' ')
  1825. s->mime_boundary[m++] = *p++;
  1826. s->mime_boundary[m] = '\0';
  1827. lwsl_notice("boundary '%s'\n", s->mime_boundary);
  1828. }
  1829. }
  1830. }
  1831. return s;
  1832. }
  1833. static int
  1834. lws_urldecode_s_process(struct lws_urldecode_stateful *s, const char *in, int len)
  1835. {
  1836. int n, m, hit = 0;
  1837. char sum = 0, c;
  1838. while (len--) {
  1839. if (s->pos == s->out_len - s->mp - 1) {
  1840. if (s->output(s->data, s->name, &s->out, s->pos, 0))
  1841. return -1;
  1842. s->pos = 0;
  1843. }
  1844. switch (s->state) {
  1845. /* states for url arg style */
  1846. case US_NAME:
  1847. s->inside_quote = 0;
  1848. if (*in == '=') {
  1849. s->name[s->pos] = '\0';
  1850. s->pos = 0;
  1851. s->state = US_IDLE;
  1852. in++;
  1853. continue;
  1854. }
  1855. if (*in == '&') {
  1856. s->name[s->pos] = '\0';
  1857. if (s->output(s->data, s->name, &s->out, s->pos, 1))
  1858. return -1;
  1859. s->pos = 0;
  1860. s->state = US_IDLE;
  1861. in++;
  1862. continue;
  1863. }
  1864. if (s->pos >= sizeof(s->name) - 1) {
  1865. lwsl_notice("Name too long\n");
  1866. return -1;
  1867. }
  1868. s->name[s->pos++] = *in++;
  1869. break;
  1870. case US_IDLE:
  1871. if (*in == '%') {
  1872. s->state++;
  1873. in++;
  1874. continue;
  1875. }
  1876. if (*in == '&') {
  1877. s->out[s->pos] = '\0';
  1878. if (s->output(s->data, s->name, &s->out, s->pos, 1))
  1879. return -1;
  1880. s->pos = 0;
  1881. s->state = US_NAME;
  1882. in++;
  1883. continue;
  1884. }
  1885. if (*in == '+') {
  1886. in++;
  1887. s->out[s->pos++] = ' ';
  1888. continue;
  1889. }
  1890. s->out[s->pos++] = *in++;
  1891. break;
  1892. case US_PC1:
  1893. n = char_to_hex(*in);
  1894. if (n < 0)
  1895. return -1;
  1896. in++;
  1897. sum = n << 4;
  1898. s->state++;
  1899. break;
  1900. case US_PC2:
  1901. n = char_to_hex(*in);
  1902. if (n < 0)
  1903. return -1;
  1904. in++;
  1905. s->out[s->pos++] = sum | n;
  1906. s->state = US_IDLE;
  1907. break;
  1908. /* states for multipart / mime style */
  1909. case MT_LOOK_BOUND_IN:
  1910. retry_as_first:
  1911. if (*in == s->mime_boundary[s->mp] &&
  1912. s->mime_boundary[s->mp]) {
  1913. in++;
  1914. s->mp++;
  1915. if (!s->mime_boundary[s->mp]) {
  1916. s->mp = 0;
  1917. s->state = MT_IGNORE1;
  1918. if (s->pos)
  1919. if (s->output(s->data, s->name,
  1920. &s->out, s->pos, 1))
  1921. return -1;
  1922. s->pos = 0;
  1923. s->content_disp[0] = '\0';
  1924. s->name[0] = '\0';
  1925. s->content_disp_filename[0] = '\0';
  1926. s->boundary_real_crlf = 1;
  1927. }
  1928. continue;
  1929. }
  1930. if (s->mp) {
  1931. n = 0;
  1932. if (!s->boundary_real_crlf)
  1933. n = 2;
  1934. memcpy(s->out + s->pos, s->mime_boundary + n, s->mp - n);
  1935. s->pos += s->mp;
  1936. s->mp = 0;
  1937. goto retry_as_first;
  1938. }
  1939. s->out[s->pos++] = *in;
  1940. in++;
  1941. s->mp = 0;
  1942. break;
  1943. case MT_HNAME:
  1944. m = 0;
  1945. c =*in;
  1946. if (c >= 'A' && c <= 'Z')
  1947. c += 'a' - 'A';
  1948. for (n = 0; n < ARRAY_SIZE(mp_hdr); n++)
  1949. if (c == mp_hdr[n][s->mp]) {
  1950. m++;
  1951. hit = n;
  1952. }
  1953. in++;
  1954. if (!m) {
  1955. s->mp = 0;
  1956. continue;
  1957. }
  1958. s->mp++;
  1959. if (m != 1)
  1960. continue;
  1961. if (mp_hdr[hit][s->mp])
  1962. continue;
  1963. s->mp = 0;
  1964. s->temp[0] = '\0';
  1965. s->subname = 0;
  1966. if (hit == 2)
  1967. s->state = MT_LOOK_BOUND_IN;
  1968. else
  1969. s->state += hit + 1;
  1970. break;
  1971. case MT_DISP:
  1972. /* form-data; name="file"; filename="t.txt" */
  1973. if (*in == '\x0d') {
  1974. // lwsl_notice("disp: '%s', '%s', '%s'\n",
  1975. // s->content_disp, s->name,
  1976. // s->content_disp_filename);
  1977. if (s->content_disp_filename[0])
  1978. if (s->output(s->data, s->name,
  1979. &s->out, s->pos, LWS_UFS_OPEN))
  1980. return -1;
  1981. s->state = MT_IGNORE2;
  1982. goto done;
  1983. }
  1984. if (*in == ';') {
  1985. s->subname = 1;
  1986. s->temp[0] = '\0';
  1987. s->mp = 0;
  1988. goto done;
  1989. }
  1990. if (*in == '\"') {
  1991. s->inside_quote ^= 1;
  1992. goto done;
  1993. }
  1994. if (s->subname) {
  1995. if (*in == '=') {
  1996. s->temp[s->mp] = '\0';
  1997. s->subname = 0;
  1998. s->mp = 0;
  1999. goto done;
  2000. }
  2001. if (s->mp < sizeof(s->temp) - 1 &&
  2002. (*in != ' ' || s->inside_quote))
  2003. s->temp[s->mp++] = *in;
  2004. goto done;
  2005. }
  2006. if (!s->temp[0]) {
  2007. if (s->mp < sizeof(s->content_disp) - 1)
  2008. s->content_disp[s->mp++] = *in;
  2009. s->content_disp[s->mp] = '\0';
  2010. goto done;
  2011. }
  2012. if (!strcmp(s->temp, "name")) {
  2013. if (s->mp < sizeof(s->name) - 1)
  2014. s->name[s->mp++] = *in;
  2015. s->name[s->mp] = '\0';
  2016. goto done;
  2017. }
  2018. if (!strcmp(s->temp, "filename")) {
  2019. if (s->mp < sizeof(s->content_disp_filename) - 1)
  2020. s->content_disp_filename[s->mp++] = *in;
  2021. s->content_disp_filename[s->mp] = '\0';
  2022. goto done;
  2023. }
  2024. done:
  2025. in++;
  2026. break;
  2027. case MT_TYPE:
  2028. if (*in == '\x0d')
  2029. s->state = MT_IGNORE2;
  2030. else {
  2031. if (s->mp < sizeof(s->content_type) - 1)
  2032. s->content_type[s->mp++] = *in;
  2033. s->content_type[s->mp] = '\0';
  2034. }
  2035. in++;
  2036. break;
  2037. case MT_IGNORE1:
  2038. if (*in == '\x0d')
  2039. s->state = MT_IGNORE2;
  2040. in++;
  2041. break;
  2042. case MT_IGNORE2:
  2043. s->mp = 0;
  2044. if (*in == '\x0a')
  2045. s->state = MT_HNAME;
  2046. in++;
  2047. break;
  2048. }
  2049. }
  2050. return 0;
  2051. }
  2052. static int
  2053. lws_urldecode_s_destroy(struct lws_urldecode_stateful *s)
  2054. {
  2055. int ret = 0;
  2056. if (s->state != US_IDLE)
  2057. ret = -1;
  2058. if (!ret)
  2059. if (s->output(s->data, s->name, &s->out, s->pos, 1))
  2060. ret = -1;
  2061. lws_free(s);
  2062. return ret;
  2063. }
  2064. struct lws_spa {
  2065. struct lws_urldecode_stateful *s;
  2066. lws_spa_fileupload_cb opt_cb;
  2067. const char * const *param_names;
  2068. int count_params;
  2069. char **params;
  2070. int *param_length;
  2071. void *opt_data;
  2072. char *storage;
  2073. char *end;
  2074. int max_storage;
  2075. };
  2076. static int
  2077. lws_urldecode_spa_lookup(struct lws_spa *spa,
  2078. const char *name)
  2079. {
  2080. int n;
  2081. for (n = 0; n < spa->count_params; n++)
  2082. if (!strcmp(spa->param_names[n], name))
  2083. return n;
  2084. return -1;
  2085. }
  2086. static int
  2087. lws_urldecode_spa_cb(void *data, const char *name, char **buf, int len,
  2088. int final)
  2089. {
  2090. struct lws_spa *spa =
  2091. (struct lws_spa *)data;
  2092. int n;
  2093. if (spa->s->content_disp_filename[0]) {
  2094. if (spa->opt_cb) {
  2095. n = spa->opt_cb(spa->opt_data, name,
  2096. spa->s->content_disp_filename,
  2097. *buf, len, final);
  2098. if (n < 0)
  2099. return -1;
  2100. }
  2101. return 0;
  2102. }
  2103. n = lws_urldecode_spa_lookup(spa, name);
  2104. if (n == -1 || !len) /* unrecognized */
  2105. return 0;
  2106. if (!spa->params[n])
  2107. spa->params[n] = *buf;
  2108. if ((*buf) + len >= spa->end) {
  2109. lwsl_notice("%s: exceeded storage\n", __func__);
  2110. return -1;
  2111. }
  2112. spa->param_length[n] += len;
  2113. /* move it on inside storage */
  2114. (*buf) += len;
  2115. *((*buf)++) = '\0';
  2116. spa->s->out_len -= len + 1;
  2117. return 0;
  2118. }
  2119. LWS_VISIBLE LWS_EXTERN struct lws_spa *
  2120. lws_spa_create(struct lws *wsi, const char * const *param_names,
  2121. int count_params, int max_storage,
  2122. lws_spa_fileupload_cb opt_cb, void *opt_data)
  2123. {
  2124. struct lws_spa *spa = lws_zalloc(sizeof(*spa));
  2125. if (!spa)
  2126. return NULL;
  2127. spa->param_names = param_names;
  2128. spa->count_params = count_params;
  2129. spa->max_storage = max_storage;
  2130. spa->opt_cb = opt_cb;
  2131. spa->opt_data = opt_data;
  2132. spa->storage = lws_malloc(max_storage);
  2133. if (!spa->storage)
  2134. goto bail2;
  2135. spa->end = spa->storage + max_storage - 1;
  2136. spa->params = lws_zalloc(sizeof(char *) * count_params);
  2137. if (!spa->params)
  2138. goto bail3;
  2139. spa->s = lws_urldecode_s_create(wsi, spa->storage, max_storage, spa,
  2140. lws_urldecode_spa_cb);
  2141. if (!spa->s)
  2142. goto bail4;
  2143. spa->param_length = lws_zalloc(sizeof(int) * count_params);
  2144. if (!spa->param_length)
  2145. goto bail5;
  2146. lwsl_notice("%s: Created SPA %p\n", __func__, spa);
  2147. return spa;
  2148. bail5:
  2149. lws_urldecode_s_destroy(spa->s);
  2150. bail4:
  2151. lws_free(spa->params);
  2152. bail3:
  2153. lws_free(spa->storage);
  2154. bail2:
  2155. lws_free(spa);
  2156. return NULL;
  2157. }
  2158. LWS_VISIBLE LWS_EXTERN int
  2159. lws_spa_process(struct lws_spa *ludspa, const char *in, int len)
  2160. {
  2161. if (!ludspa) {
  2162. lwsl_err("%s: NULL spa\n");
  2163. return -1;
  2164. }
  2165. return lws_urldecode_s_process(ludspa->s, in, len);
  2166. }
  2167. LWS_VISIBLE LWS_EXTERN int
  2168. lws_spa_get_length(struct lws_spa *ludspa, int n)
  2169. {
  2170. if (n >= ludspa->count_params)
  2171. return 0;
  2172. return ludspa->param_length[n];
  2173. }
  2174. LWS_VISIBLE LWS_EXTERN const char *
  2175. lws_spa_get_string(struct lws_spa *ludspa, int n)
  2176. {
  2177. if (n >= ludspa->count_params)
  2178. return NULL;
  2179. return ludspa->params[n];
  2180. }
  2181. LWS_VISIBLE LWS_EXTERN int
  2182. lws_spa_finalize(struct lws_spa *spa)
  2183. {
  2184. if (spa->s) {
  2185. lws_urldecode_s_destroy(spa->s);
  2186. spa->s = NULL;
  2187. }
  2188. return 0;
  2189. }
  2190. LWS_VISIBLE LWS_EXTERN int
  2191. lws_spa_destroy(struct lws_spa *spa)
  2192. {
  2193. int n = 0;
  2194. lwsl_notice("%s: destroy spa %p\n", __func__, spa);
  2195. if (spa->s)
  2196. lws_urldecode_s_destroy(spa->s);
  2197. lwsl_debug("%s\n", __func__);
  2198. lws_free(spa->param_length);
  2199. lws_free(spa->params);
  2200. lws_free(spa->storage);
  2201. lws_free(spa);
  2202. return n;
  2203. }
  2204. LWS_VISIBLE LWS_EXTERN int
  2205. lws_chunked_html_process(struct lws_process_html_args *args,
  2206. struct lws_process_html_state *s)
  2207. {
  2208. char *sp, buffer[32];
  2209. const char *pc;
  2210. int old_len, n;
  2211. /* do replacements */
  2212. sp = args->p;
  2213. old_len = args->len;
  2214. args->len = 0;
  2215. s->start = sp;
  2216. while (sp < args->p + old_len) {
  2217. if (args->len + 7 >= args->max_len) {
  2218. lwsl_err("Used up interpret padding\n");
  2219. return -1;
  2220. }
  2221. if ((!s->pos && *sp == '$') || s->pos) {
  2222. int hits = 0, hit = 0;
  2223. if (!s->pos)
  2224. s->start = sp;
  2225. s->swallow[s->pos++] = *sp;
  2226. if (s->pos == sizeof(s->swallow) - 1)
  2227. goto skip;
  2228. for (n = 0; n < s->count_vars; n++)
  2229. if (!strncmp(s->swallow, s->vars[n], s->pos)) {
  2230. hits++;
  2231. hit = n;
  2232. }
  2233. if (!hits) {
  2234. skip:
  2235. s->swallow[s->pos] = '\0';
  2236. memcpy(s->start, s->swallow, s->pos);
  2237. args->len++;
  2238. s->pos = 0;
  2239. sp = s->start + 1;
  2240. continue;
  2241. }
  2242. if (hits == 1 && s->pos == strlen(s->vars[hit])) {
  2243. pc = s->replace(s->data, hit);
  2244. if (!pc)
  2245. pc = "NULL";
  2246. n = strlen(pc);
  2247. s->swallow[s->pos] = '\0';
  2248. if (n != s->pos) {
  2249. memmove(s->start + n,
  2250. s->start + s->pos,
  2251. old_len - (sp - args->p));
  2252. old_len += (n - s->pos) + 1;
  2253. }
  2254. memcpy(s->start, pc, n);
  2255. args->len++;
  2256. sp = s->start + 1;
  2257. s->pos = 0;
  2258. }
  2259. sp++;
  2260. continue;
  2261. }
  2262. args->len++;
  2263. sp++;
  2264. }
  2265. /* no space left for final chunk trailer */
  2266. if (args->final && args->len + 7 >= args->max_len)
  2267. return -1;
  2268. n = sprintf(buffer, "%X\x0d\x0a", args->len);
  2269. args->p -= n;
  2270. memcpy(args->p, buffer, n);
  2271. args->len += n;
  2272. if (args->final) {
  2273. sp = args->p + args->len;
  2274. *sp++ = '\x0d';
  2275. *sp++ = '\x0a';
  2276. *sp++ = '0';
  2277. *sp++ = '\x0d';
  2278. *sp++ = '\x0a';
  2279. *sp++ = '\x0d';
  2280. *sp++ = '\x0a';
  2281. args->len += 7;
  2282. } else {
  2283. sp = args->p + args->len;
  2284. *sp++ = '\x0d';
  2285. *sp++ = '\x0a';
  2286. args->len += 2;
  2287. }
  2288. return 0;
  2289. }