PageRenderTime 5377ms CodeModel.GetById 43ms RepoModel.GetById 3ms app.codeStats 1ms

/meinheld/server/server.c

http://github.com/mopemope/meinheld
C | 2612 lines | 2058 code | 352 blank | 202 comment | 415 complexity | 0158c09a4b0bbe1625830134c228a98e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. #include "server.h"
  2. #include <arpa/inet.h>
  3. #include <signal.h>
  4. #ifdef linux
  5. #include <sys/prctl.h>
  6. #include <sys/socket.h>
  7. #endif
  8. #include <sys/un.h>
  9. #include <sys/stat.h>
  10. #include "http_request_parser.h"
  11. #include "response.h"
  12. #include "log.h"
  13. #include "client.h"
  14. #include "util.h"
  15. #include "input.h"
  16. #include "timer.h"
  17. #include "heapq.h"
  18. #ifdef WITH_GREENLET
  19. #include "greensupport.h"
  20. #endif
  21. #define ACCEPT_TIMEOUT_SECS 1
  22. #define READ_TIMEOUT_SECS 30
  23. #define READ_BUF_SIZE 1024 * 64
  24. typedef struct {
  25. TimerObject **q;
  26. uint32_t size;
  27. uint32_t max;
  28. } pending_queue_t;
  29. static char *server_name = "127.0.0.1";
  30. static uint16_t server_port = 8000;
  31. /* static int listen_sock; // listen socket */
  32. static PyObject *listen_socks = NULL; // listen socket
  33. static volatile sig_atomic_t loop_done;
  34. static volatile sig_atomic_t call_shutdown = 0;
  35. static volatile sig_atomic_t catch_signal = 0;
  36. static picoev_loop* main_loop = NULL; //main loop
  37. static heapq_t *g_timers;
  38. static pending_queue_t *g_pendings = NULL;
  39. // active event cnt
  40. static int activecnt = 0;
  41. static PyObject *wsgi_app = NULL; //wsgi app
  42. static uint8_t watch_loop = 0;
  43. static PyObject *watchdog = NULL; //watchdog
  44. static char is_write_access_log = 0;
  45. static int is_keep_alive = 0; //keep alive support
  46. static int keep_alive_timeout = 5;
  47. uint64_t max_content_length = 1024 * 1024 * 16; //max_content_length
  48. int client_body_buffer_size = 1024 * 500; //client_body_buffer_size
  49. static char *unix_sock_name = NULL;
  50. static int backlog = 1024 * 4; // backlog size
  51. static int max_fd = 1024 * 4; // picoev max_fd
  52. // greenlet hub switch value
  53. static PyObject *hub_switch_value;
  54. PyObject* current_client;
  55. PyObject* timeout_error;
  56. /* reuse object */
  57. static PyObject *client_key = NULL; //meinheld.client
  58. static PyObject *wsgi_input_key = NULL; //wsgi.input key
  59. // https://gist.github.com/mitsuhiko/5721107
  60. static PyObject *wsgi_input_terminated_key = NULL; //wsgi.input_terminated key
  61. static PyObject *status_code_key = NULL; //STATUS_CODE
  62. static PyObject *bytes_sent_key = NULL; // SEND_BYTES
  63. static PyObject *request_time_key = NULL; // REQUEST_TIME
  64. static PyObject *local_time_key = NULL; // LOCAL_TIME
  65. static PyObject *empty_string = NULL; //""
  66. static PyObject *app_handler_func = NULL;
  67. /* gunicorn */
  68. static time_t watchdog_lasttime;
  69. static int spinner = 0;
  70. static int tempfile_fd = 0;
  71. static int gtimeout = 0;
  72. static int ppid = 0;
  73. #define CLIENT_MAXFREELIST 1024
  74. static client_t *client_free_list[CLIENT_MAXFREELIST];
  75. static int client_numfree = 0;
  76. static void
  77. read_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
  78. #ifndef WITH_GREENLET
  79. static void
  80. write_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
  81. #endif
  82. static void
  83. kill_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
  84. static void
  85. trampoline_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
  86. static PyObject*
  87. internal_schedule_call(int seconds, PyObject *cb, PyObject *args, PyObject *kwargs, PyObject *greenlet);
  88. static int
  89. prepare_call_wsgi(client_t *client);
  90. static void
  91. call_wsgi_handler(client_t *client);
  92. static int
  93. check_status_code(client_t *client);
  94. static pending_queue_t*
  95. init_pendings(void)
  96. {
  97. pending_queue_t *pendings = NULL;
  98. pendings = PyMem_Malloc(sizeof(pending_queue_t));
  99. if (pendings == NULL) {
  100. return NULL;
  101. }
  102. pendings->size = 0;
  103. pendings->max= 1024;
  104. pendings->q = (TimerObject**)malloc(sizeof(TimerObject*) * pendings->max);
  105. if (pendings->q == NULL) {
  106. PyMem_Free(pendings);
  107. return NULL;
  108. }
  109. return pendings;
  110. }
  111. static int
  112. realloc_pendings(void)
  113. {
  114. TimerObject **new_heap;
  115. uint32_t max;
  116. pending_queue_t *pendings = g_pendings;
  117. if (pendings->size >= pendings->max) {
  118. //realloc
  119. max = pendings->max * 2;
  120. new_heap = (TimerObject**)realloc(pendings->q, sizeof(TimerObject*) * max);
  121. if (new_heap == NULL) {
  122. PyErr_SetString(PyExc_Exception, "size over timer queue");
  123. return -1;
  124. }
  125. pendings->max = max;
  126. pendings->q = new_heap;
  127. RDEBUG("realloc max:%d", pendings->max);
  128. }
  129. return 1;
  130. }
  131. static void
  132. destroy_pendings(void)
  133. {
  134. int i = 0, len;
  135. TimerObject *timer = NULL;
  136. TimerObject **t = g_pendings->q;
  137. if (g_pendings == NULL) {
  138. return;
  139. }
  140. len = g_pendings->size;
  141. t += i;
  142. while(len--) {
  143. timer = *t;
  144. Py_DECREF(timer);
  145. t++;
  146. }
  147. free(g_pendings->q);
  148. PyMem_Free(g_pendings);
  149. g_pendings = NULL;
  150. }
  151. static void
  152. client_t_list_fill(void)
  153. {
  154. client_t *client;
  155. while (client_numfree < CLIENT_MAXFREELIST) {
  156. client = (client_t *)PyMem_Malloc(sizeof(client_t));
  157. client_free_list[client_numfree++] = client;
  158. }
  159. }
  160. static void
  161. client_t_list_clear(void)
  162. {
  163. client_t *op;
  164. while (client_numfree) {
  165. op = client_free_list[--client_numfree];
  166. PyMem_Free(op);
  167. }
  168. }
  169. static client_t*
  170. alloc_client_t(void)
  171. {
  172. client_t *client;
  173. if (client_numfree) {
  174. client = client_free_list[--client_numfree];
  175. GDEBUG("use pooled %p", client);
  176. } else {
  177. client = (client_t *)PyMem_Malloc(sizeof(client_t));
  178. GDEBUG("alloc %p", client);
  179. }
  180. memset(client, 0, sizeof(client_t));
  181. return client;
  182. }
  183. static void
  184. dealloc_client(client_t *client)
  185. {
  186. if (client_numfree < CLIENT_MAXFREELIST) {
  187. client_free_list[client_numfree++] = client;
  188. GDEBUG("back to pool %p", client);
  189. } else {
  190. PyMem_Free(client);
  191. }
  192. }
  193. static client_t *
  194. new_client_t(int client_fd, char *remote_addr, uint32_t remote_port)
  195. {
  196. client_t *client;
  197. client = alloc_client_t();
  198. //client = PyMem_Malloc(sizeof(client_t));
  199. //memset(client, 0, sizeof(client_t));
  200. client->fd = client_fd;
  201. client->complete = 1;
  202. client->request_queue = new_request_queue();
  203. client->remote_addr = remote_addr;
  204. client->remote_port = remote_port;
  205. /* client->body_type = BODY_TYPE_NONE; */
  206. GDEBUG("client alloc %p", client);
  207. return client;
  208. }
  209. static void
  210. set_log_value(client_t *client, PyObject *environ, uintptr_t delta_msec)
  211. {
  212. PyObject *status_code = NULL, *bytes = NULL, *request_time = NULL, *local_time = NULL;
  213. status_code = PyLong_FromLong(client->status_code);
  214. bytes = PyLong_FromLong(client->write_bytes);
  215. request_time = PyLong_FromLong(delta_msec);
  216. local_time = NATIVE_FROMSTRING((char*)http_log_time);
  217. if (status_code) {
  218. PyDict_SetItem(environ, status_code_key, status_code);
  219. Py_DECREF(status_code);
  220. }
  221. if (bytes) {
  222. PyDict_SetItem(environ, bytes_sent_key, bytes);
  223. Py_DECREF(bytes);
  224. }
  225. if (request_time) {
  226. PyDict_SetItem(environ, request_time_key, request_time);
  227. Py_DECREF(request_time);
  228. }
  229. if (local_time) {
  230. PyDict_SetItem(environ, local_time_key, local_time);
  231. Py_DECREF(local_time);
  232. }
  233. }
  234. static void
  235. clean_client(client_t *client)
  236. {
  237. PyObject *environ = NULL;
  238. uintptr_t end, delta_msec = 0;
  239. request *req = client->current_req;
  240. if (is_write_access_log) {
  241. DEBUG("write access log");
  242. cache_time_update();
  243. if (req) {
  244. environ = req->environ;
  245. end = current_msec;
  246. if (req->start_msec > 0){
  247. delta_msec = end - req->start_msec;
  248. }
  249. set_log_value(client, environ, delta_msec);
  250. call_access_logger(environ);
  251. } else {
  252. if (client->status_code != 408) {
  253. environ = new_environ(client);
  254. set_log_value(client, environ, delta_msec);
  255. call_access_logger(environ);
  256. }
  257. }
  258. }
  259. Py_CLEAR(client->http_status);
  260. Py_CLEAR(client->headers);
  261. Py_CLEAR(client->response_iter);
  262. Py_CLEAR(client->response);
  263. if (req == NULL) {
  264. goto init;
  265. }
  266. DEBUG("status_code:%d env:%p", client->status_code, req->environ);
  267. if (req->environ) {
  268. /* PyDict_Clear(client->environ); */
  269. /* DEBUG("CLEAR environ"); */
  270. Py_CLEAR(req->environ);
  271. }
  272. if (req->body) {
  273. if (req->body_type == BODY_TYPE_TMPFILE) {
  274. fclose(req->body);
  275. } else {
  276. free_buffer(req->body);
  277. }
  278. req->body = NULL;
  279. }
  280. free_request(req);
  281. init:
  282. client->current_req = NULL;
  283. client->header_done = 0;
  284. client->response_closed = 0;
  285. client->chunked_response = 0;
  286. client->content_length_set = 0;
  287. client->content_length = 0;
  288. client->write_bytes = 0;
  289. }
  290. static void
  291. close_client(client_t *client)
  292. {
  293. client_t *new_client = NULL;
  294. int ret;
  295. if (!client->response_closed) {
  296. close_response(client);
  297. }
  298. DEBUG("start close client:%p fd:%d status_code %d", client, client->fd, client->status_code);
  299. if (picoev_is_active(main_loop, client->fd)) {
  300. if (!picoev_del(main_loop, client->fd)) {
  301. activecnt--;
  302. DEBUG("activecnt:%d", activecnt);
  303. }
  304. DEBUG("picoev_del client:%p fd:%d", client, client->fd);
  305. }
  306. clean_client(client);
  307. DEBUG("remain http pipeline size :%d", client->request_queue->size);
  308. if (client->request_queue->size > 0) {
  309. if (check_status_code(client) > 0) {
  310. //process pipeline
  311. if (prepare_call_wsgi(client) > 0) {
  312. call_wsgi_handler(client);
  313. }
  314. }
  315. return ;
  316. }
  317. if (client->http_parser != NULL) {
  318. /* PyMem_Free(client->http_parser); */
  319. dealloc_parser(client->http_parser);
  320. }
  321. free_request_queue(client->request_queue);
  322. if (!client->keep_alive) {
  323. close(client->fd);
  324. BDEBUG("close client:%p fd:%d", client, client->fd);
  325. } else {
  326. BDEBUG("keep alive client:%p fd:%d", client, client->fd);
  327. new_client = new_client_t(client->fd, client->remote_addr, client->remote_port);
  328. new_client->keep_alive = 1;
  329. init_parser(new_client, server_name, server_port);
  330. ret = picoev_add(main_loop, new_client->fd, PICOEV_READ, keep_alive_timeout, read_callback, (void *)new_client);
  331. if (ret == 0) {
  332. activecnt++;
  333. }
  334. }
  335. //clear old client
  336. dealloc_client(client);
  337. }
  338. static void init_main_loop(void)
  339. {
  340. if (main_loop == NULL) {
  341. /* init picoev */
  342. picoev_init(max_fd);
  343. /* create loop */
  344. main_loop = picoev_create_loop(60);
  345. }
  346. }
  347. static void
  348. kill_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  349. {
  350. picoev_del(loop, fd);
  351. if ((events & PICOEV_TIMEOUT) != 0) {
  352. DEBUG("force shutdown...");
  353. loop_done = 0;
  354. }
  355. }
  356. static inline void
  357. kill_server(int timeout)
  358. {
  359. int listen_sock = 0;
  360. PyObject *iter = NULL, *item;
  361. int set_callback = 0;
  362. if (main_loop == NULL) {
  363. return;
  364. }
  365. iter = PyObject_GetIter(listen_socks);
  366. if (PyErr_Occurred()){
  367. call_error_logger();
  368. return;
  369. }
  370. while((item = PyIter_Next(iter))){
  371. #ifdef PY3
  372. if (PyLong_Check(item)) {
  373. listen_sock = (int)PyLong_AsLong(item);
  374. #else
  375. if (PyInt_Check(item)) {
  376. listen_sock = (int)PyInt_AsLong(item);
  377. #endif
  378. //stop accepting
  379. if (!picoev_del(main_loop, listen_sock)) {
  380. activecnt--;
  381. DEBUG("activecnt:%d", activecnt);
  382. }
  383. if (!set_callback) {
  384. //shutdown timeout
  385. if (timeout > 0) {
  386. //set timeout
  387. (void)picoev_add(main_loop, listen_sock, PICOEV_TIMEOUT, timeout, kill_callback, NULL);
  388. } else {
  389. (void)picoev_add(main_loop, listen_sock, PICOEV_TIMEOUT, 1, kill_callback, NULL);
  390. }
  391. set_callback = 1;
  392. }
  393. } else {
  394. //TODO WARN???
  395. }
  396. Py_DECREF(item);
  397. }
  398. Py_DECREF(iter);
  399. }
  400. static inline void
  401. set_current_request(client_t *client)
  402. {
  403. request *req;
  404. req = shift_request(client->request_queue);
  405. client->current_req = req;
  406. }
  407. static void
  408. set_bad_request_code(client_t *client, int status_code)
  409. {
  410. request *req;
  411. req = client->request_queue->tail;
  412. req->bad_request_code = status_code;
  413. DEBUG("set bad request code %d", status_code);
  414. }
  415. static int
  416. check_status_code(client_t *client)
  417. {
  418. request *req;
  419. req = client->request_queue->head;
  420. if (req && req->bad_request_code > 200) {
  421. //error
  422. //shift
  423. DEBUG("bad status code %d", req->bad_request_code);
  424. set_current_request(client);
  425. client->status_code = req->bad_request_code;
  426. send_error_page(client);
  427. close_client(client);
  428. return -1;
  429. }
  430. return 1;
  431. }
  432. static PyObject *
  433. app_handler(PyObject *self, PyObject *args)
  434. {
  435. int ret, active;
  436. PyObject *wsgi_args = NULL, *start = NULL, *current = NULL, *parent = NULL, *res = NULL;
  437. PyObject *env = NULL;
  438. ClientObject *pyclient;
  439. client_t *client;
  440. request *req;
  441. response_status status;
  442. if (!PyArg_ParseTuple(args, "O:app_handler", &env)) {
  443. return NULL;
  444. }
  445. pyclient = (ClientObject*)PyDict_GetItem(env, client_key);
  446. client = pyclient->client;
  447. req = client->current_req;
  448. start = create_start_response(client);
  449. if (!start) {
  450. return NULL;
  451. }
  452. DEBUG("call wsgi app");
  453. wsgi_args = PyTuple_Pack(2, env, start);
  454. res = PyObject_CallObject(wsgi_app, wsgi_args);
  455. Py_DECREF(wsgi_args);
  456. DEBUG("called wsgi app");
  457. //check response & PyErr_Occurred
  458. if (res && res == Py_None) {
  459. PyErr_SetString(PyExc_Exception, "response must be a iter or sequence object");
  460. goto error;
  461. }
  462. //Check wsgi_app error
  463. if (PyErr_Occurred()) {
  464. goto error;
  465. }
  466. client->response = res;
  467. if (client->response_closed) {
  468. //closed
  469. close_client(client);
  470. Py_RETURN_NONE;
  471. }
  472. status = response_start(client);
  473. #ifdef WITH_GREENLET
  474. while(status != STATUS_OK) {
  475. if (status == STATUS_ERROR) {
  476. // Internal Server Error
  477. req->bad_request_code = 500;
  478. goto error;
  479. } else {
  480. active = picoev_is_active(main_loop, client->fd);
  481. ret = picoev_add(main_loop, client->fd, PICOEV_WRITE, 300, trampoline_callback, (void *)pyclient);
  482. if ((ret == 0 && !active)) {
  483. activecnt++;
  484. }
  485. // switch to hub
  486. current = pyclient->greenlet;
  487. parent = greenlet_getparent(current);
  488. /* Py_INCREF(hub_switch_value); */
  489. res = greenlet_switch(parent, hub_switch_value, NULL);
  490. Py_XDECREF(res);
  491. // try again after event switch
  492. status = process_body(client);
  493. }
  494. }
  495. status = close_response(client);
  496. if (status == STATUS_ERROR) {
  497. //TODO logging error
  498. }
  499. // send OK
  500. close_client(client);
  501. #else
  502. switch(status) {
  503. case STATUS_ERROR:
  504. // Internal Server Error
  505. req->bad_request_code = 500;
  506. goto error;
  507. case STATUS_SUSPEND:
  508. // continue
  509. // set callback
  510. active = picoev_is_active(main_loop, client->fd);
  511. ret = picoev_add(main_loop, client->fd, PICOEV_WRITE, 300, write_callback, (void *)pyclient);
  512. if ((ret == 0 && !active)) {
  513. activecnt++;
  514. }
  515. default:
  516. // send OK
  517. close_client(client);
  518. }
  519. #endif
  520. Py_RETURN_NONE;
  521. error:
  522. client->status_code = 500;
  523. status = close_response(client);
  524. if (status == STATUS_ERROR) {
  525. //TODO logging error
  526. }
  527. /* write_error_log(__FILE__, __LINE__); */
  528. call_error_logger();
  529. send_error_page(client);
  530. close_client(client);
  531. Py_RETURN_NONE;
  532. }
  533. static PyMethodDef app_handler_def = {"_app_handler", (PyCFunction)app_handler, METH_VARARGS, 0};
  534. static PyObject*
  535. get_app_handler(void)
  536. {
  537. if (app_handler_func == NULL) {
  538. app_handler_func = PyCFunction_NewEx(&app_handler_def, (PyObject *)NULL, NULL);
  539. }
  540. //Py_INCREF(app_handler_func);
  541. return app_handler_func;
  542. }
  543. #ifdef WITH_GREENLET
  544. static void
  545. resume_greenlet(PyObject *greenlet)
  546. {
  547. PyObject *res = NULL;
  548. PyObject *err_type, *err_val, *err_tb;
  549. if (PyErr_Occurred()) {
  550. PyErr_Fetch(&err_type, &err_val, &err_tb);
  551. PyErr_Clear();
  552. //set error
  553. res = greenlet_throw(greenlet, err_type, err_val, err_tb);
  554. } else {
  555. /* Py_INCREF(hub_switch_value); */
  556. res = greenlet_switch(greenlet, hub_switch_value, NULL);
  557. if (res == NULL) {
  558. call_error_logger();
  559. /* PyErr_Fetch(&err_type, &err_val, &err_tb); */
  560. /* PyErr_Clear(); */
  561. //set error
  562. /* res = greenlet_throw(greenlet, err_type, err_val, err_tb); */
  563. }
  564. }
  565. Py_XDECREF(res);
  566. if (greenlet_dead(greenlet)) {
  567. Py_DECREF(greenlet);
  568. }
  569. }
  570. static void
  571. resume_wsgi_handler(ClientObject *pyclient)
  572. {
  573. PyObject *res = NULL;
  574. PyObject *err_type, *err_val, *err_tb;
  575. client_t *old_client;
  576. client_t *client = pyclient->client;
  577. //swap bind client_t
  578. old_client = start_response->cli;
  579. start_response->cli = client;
  580. current_client = (PyObject *)pyclient;
  581. if (PyErr_Occurred()) {
  582. PyErr_Fetch(&err_type, &err_val, &err_tb);
  583. PyErr_Clear();
  584. //set error
  585. res = greenlet_throw(pyclient->greenlet, err_type, err_val, err_tb);
  586. } else {
  587. res = greenlet_switch(pyclient->greenlet, pyclient->args, pyclient->kwargs);
  588. }
  589. start_response->cli = old_client;
  590. Py_CLEAR(pyclient->args);
  591. Py_CLEAR(pyclient->kwargs);
  592. Py_XDECREF(res);
  593. }
  594. #endif
  595. static void
  596. call_wsgi_handler(client_t *client)
  597. {
  598. PyObject *handler, *greenlet, *args, *res;
  599. ClientObject *pyclient;
  600. request *req = NULL;
  601. handler = get_app_handler();
  602. req = client->current_req;
  603. current_client = PyDict_GetItem(req->environ, client_key);
  604. pyclient = (ClientObject *)current_client;
  605. args = PyTuple_Pack(1, req->environ);
  606. #ifdef WITH_GREENLET
  607. //new greenlet
  608. greenlet = greenlet_new(handler, NULL);
  609. // set_greenlet
  610. pyclient->greenlet = greenlet;
  611. Py_INCREF(pyclient->greenlet);
  612. res = greenlet_switch(greenlet, args, NULL);
  613. //res = PyObject_CallObject(wsgi_app, args);
  614. Py_DECREF(args);
  615. Py_DECREF(greenlet);
  616. #else
  617. pyclient->greenlet = NULL;
  618. res = PyObject_CallObject(handler, args);
  619. Py_DECREF(args);
  620. #endif
  621. Py_XDECREF(res);
  622. }
  623. #ifdef WITH_GREENLET
  624. static void
  625. timeout_error_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  626. {
  627. ClientObject *pyclient = (ClientObject *)(cb_arg);
  628. client_t *client = pyclient->client;
  629. if ((events & PICOEV_TIMEOUT) != 0) {
  630. DEBUG("timeout_error_callback pyclient:%p client:%p fd:%d", pyclient, pyclient->client, pyclient->client->fd);
  631. if (!picoev_del(loop, fd)) {
  632. activecnt--;
  633. DEBUG("activecnt:%d", activecnt);
  634. }
  635. pyclient->suspended = 0;
  636. /* pyclient->resumed = 1; */
  637. PyErr_SetString(timeout_error, "timeout");
  638. set_so_keepalive(client->fd, 0);
  639. resume_wsgi_handler(pyclient);
  640. }
  641. }
  642. static void
  643. timeout_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  644. {
  645. ClientObject *pyclient = (ClientObject *)(cb_arg);
  646. client_t *client = pyclient->client;
  647. if ((events & PICOEV_TIMEOUT) != 0) {
  648. DEBUG("timeout_callback pyclient:%p client:%p fd:%d", pyclient, pyclient->client, pyclient->client->fd);
  649. //next intval 30sec
  650. picoev_set_timeout(loop, client->fd, 30);
  651. // is_active ??
  652. if (write(client->fd, "", 0) < 0) {
  653. if (!picoev_del(loop, fd)) {
  654. activecnt--;
  655. DEBUG("activecnt:%d", activecnt);
  656. }
  657. //resume
  658. pyclient->suspended = 0;
  659. /* pyclient->resumed = 1; */
  660. PyErr_SetFromErrno(PyExc_IOError);
  661. DEBUG("closed");
  662. set_so_keepalive(client->fd, 0);
  663. resume_wsgi_handler(pyclient);
  664. }
  665. }
  666. }
  667. static void
  668. trampoline_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  669. {
  670. PyObject *o = NULL;
  671. ClientObject *pyclient = NULL;
  672. client_t *client = NULL;
  673. if (!picoev_del(loop, fd)) {
  674. activecnt--;
  675. DEBUG("activecnt:%d", activecnt);
  676. }
  677. YDEBUG("call trampoline_callback fd:%d event:%d cb_arg:%p", fd, events, cb_arg);
  678. o = (PyObject*)cb_arg;
  679. if (CheckClientObject(o)) {
  680. pyclient = (ClientObject*)cb_arg;
  681. client = pyclient->client;
  682. if ((events & PICOEV_TIMEOUT) != 0) {
  683. RDEBUG("** trampoline_callback timeout **");
  684. //timeout
  685. client->keep_alive = 0;
  686. PyErr_SetString(timeout_error, "timeout");
  687. }
  688. YDEBUG("resume_wsgi_handler");
  689. resume_wsgi_handler(pyclient);
  690. } else if (greenlet_check(o)) {
  691. YDEBUG("resume_greenlet");
  692. resume_greenlet(o);
  693. }
  694. }
  695. #endif
  696. #ifndef WITH_GREENLET
  697. static void
  698. write_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  699. {
  700. ClientObject *pyclient = (ClientObject*)cb_arg;
  701. client_t *client = pyclient->client;
  702. int ret;
  703. DEBUG("call write_callback");
  704. current_client = (PyObject*)pyclient;
  705. if ((events & PICOEV_TIMEOUT) != 0) {
  706. DEBUG("** write_callback timeout **");
  707. //timeout
  708. client->keep_alive = 0;
  709. close_client(client);
  710. } else if ((events & PICOEV_WRITE) != 0) {
  711. ret = process_body(client);
  712. DEBUG("process_body ret %d", ret);
  713. if (ret != 0) {
  714. //ok or die
  715. close_client(client);
  716. }
  717. }
  718. }
  719. #endif
  720. static int
  721. check_http_expect(client_t *client)
  722. {
  723. PyObject *c = NULL;
  724. char *val = NULL;
  725. int ret;
  726. request *req = client->current_req;
  727. if (client->http_parser->http_minor == 1) {
  728. ///TODO CHECK
  729. c = PyDict_GetItemString(req->environ, "HTTP_EXPECT");
  730. if (c) {
  731. #ifdef PY3
  732. val = PyUnicode_AsUTF8(c);
  733. #else
  734. val = PyBytes_AS_STRING(c);
  735. #endif
  736. if (!strncasecmp(val, "100-continue", 12)) {
  737. ret = write(client->fd, "HTTP/1.1 100 Continue\r\n\r\n", 25);
  738. if (ret < 0) {
  739. //fail
  740. PyErr_SetFromErrno(PyExc_IOError);
  741. /* write_error_log(__FILE__, __LINE__); */
  742. call_error_logger();
  743. client->keep_alive = 0;
  744. client->status_code = 500;
  745. send_error_page(client);
  746. close_client(client);
  747. return -1;
  748. }
  749. } else {
  750. //417
  751. client->keep_alive = 0;
  752. client->status_code = 417;
  753. send_error_page(client);
  754. close_client(client);
  755. return -1;
  756. }
  757. }
  758. return 1;
  759. }
  760. return 0;
  761. }
  762. #ifdef PY3
  763. static int
  764. set_input_file(client_t *client)
  765. {
  766. PyObject *input;
  767. int fd;
  768. request *req = client->current_req;
  769. FILE *tmp = (FILE *)req->body;
  770. fflush(tmp);
  771. rewind(tmp);
  772. fd = fileno(tmp);
  773. input = PyFile_FromFd(fd, "<tmpfile>", "rb", -1, NULL, NULL, NULL, 1);
  774. if (input == NULL) {
  775. fclose(tmp);
  776. req->body = NULL;
  777. return -1;
  778. }
  779. //env["wsgi.input"] = tmpfile
  780. //
  781. PyDict_SetItem((PyObject *)req->environ, wsgi_input_key, input);
  782. Py_DECREF(input);
  783. req->body = NULL;
  784. return 1;
  785. }
  786. #else
  787. static int
  788. set_input_file(client_t *client)
  789. {
  790. PyObject *input;
  791. request *req = client->current_req;
  792. FILE *tmp = (FILE *)req->body;
  793. fflush(tmp);
  794. rewind(tmp);
  795. input = PyFile_FromFile(tmp, "<tmpfile>", "r", fclose);
  796. if (input == NULL) {
  797. fclose(tmp);
  798. req->body = NULL;
  799. return -1;
  800. }
  801. //env["wsgi.input"] = tmpfile
  802. //
  803. PyDict_SetItem((PyObject *)req->environ, wsgi_input_key, input);
  804. Py_DECREF(input);
  805. req->body = NULL;
  806. return 0;
  807. }
  808. #endif
  809. static int
  810. set_input_object(client_t *client)
  811. {
  812. PyObject *input = NULL;
  813. request *req = client->current_req;
  814. if (req->body_type == BODY_TYPE_BUFFER) {
  815. input = InputObject_New((buffer_t*)req->body);
  816. } else {
  817. if (req->body) {
  818. input = InputObject_New((buffer_t*)req->body);
  819. } else {
  820. input = InputObject_New(new_buffer(0, 0));
  821. }
  822. }
  823. if (input == NULL) {
  824. return -1;
  825. }
  826. PyDict_SetItem((PyObject *)req->environ, wsgi_input_key, input);
  827. Py_DECREF(input);
  828. req->body = NULL;
  829. return 1;
  830. }
  831. /*
  832. static void
  833. setting_keepalive(client_t *client)
  834. {
  835. PyObject *c;
  836. char *val;
  837. if (is_keep_alive) {
  838. //support keep-alive
  839. c = PyDict_GetItemString(client->environ, "HTTP_CONNECTION");
  840. if (client->http_parser->http_minor == 1) {
  841. //HTTP 1.1
  842. if (c) {
  843. val = PyBytes_AS_STRING(c);
  844. if (!strcasecmp(val, "close")) {
  845. client->keep_alive = 0;
  846. } else {
  847. client->keep_alive = 1;
  848. }
  849. } else {
  850. client->keep_alive = 1;
  851. }
  852. } else {
  853. //HTTP 1.0
  854. if (c) {
  855. val = PyBytes_AS_STRING(c);
  856. if (!strcasecmp(val, "keep-alive")) {
  857. client->keep_alive = 1;
  858. } else {
  859. client->keep_alive = 0;
  860. }
  861. } else {
  862. client->keep_alive = 0;
  863. }
  864. }
  865. }
  866. }
  867. */
  868. static int
  869. prepare_call_wsgi(client_t *client)
  870. {
  871. request *req = NULL;
  872. set_current_request(client);
  873. req = client->current_req;
  874. //check Expect
  875. if (check_http_expect(client) < 0) {
  876. return -1;
  877. }
  878. if (req->body_type == BODY_TYPE_TMPFILE) {
  879. if (set_input_file(client) == -1) {
  880. return -1;
  881. }
  882. } else {
  883. if (set_input_object(client) == -1) {
  884. return -1;
  885. }
  886. }
  887. PyDict_SetItem((PyObject *)req->environ, wsgi_input_terminated_key, Py_True);
  888. if (!is_keep_alive) {
  889. client->keep_alive = 0;
  890. }
  891. /* setting_keepalive(client); */
  892. return 1;
  893. }
  894. static int
  895. set_read_error(client_t *client, int status_code)
  896. {
  897. client->keep_alive = 0;
  898. if (status_code == 0) {
  899. // bad request
  900. status_code = 400;
  901. }
  902. if (client->request_queue->size > 0) {
  903. //piplining
  904. set_bad_request_code(client, status_code);
  905. //finish = 1
  906. return 1;
  907. } else {
  908. if (!client->complete) {
  909. // read error while reading request.
  910. client->status_code = status_code;
  911. send_error_page(client);
  912. } // else keepalive timeout. should not send any data.
  913. close_client(client);
  914. return -1;
  915. }
  916. }
  917. static int
  918. read_timeout(int fd, client_t *client)
  919. {
  920. RDEBUG("** read timeout fd:%d", fd);
  921. //timeout
  922. return set_read_error(client, 408);
  923. }
  924. static int
  925. compare_key(PyObject *env, char *key, char *compare)
  926. {
  927. int ret = -1;
  928. char *val = NULL;
  929. PyObject *c = PyDict_GetItemString(env, key);
  930. if (c) {
  931. #ifdef PY3
  932. c = PyUnicode_AsLatin1String(c);
  933. val = PyBytes_AS_STRING(c);
  934. #else
  935. val = PyBytes_AS_STRING(c);
  936. Py_INCREF(c);
  937. #endif
  938. ret = strcasecmp(val, compare);
  939. }
  940. Py_XDECREF(c);
  941. return ret;
  942. }
  943. static int
  944. check_websocket(PyObject *env)
  945. {
  946. //Support only RFC6455
  947. if (PyMapping_HasKeyString(env, "HTTP_SEC_WEBSOCKET_KEY") == 1) {
  948. if (compare_key(env, "HTTP_SEC_WEBSOCKET_VERSION", "13") == 0) {
  949. return 1;
  950. }
  951. }
  952. return -1;
  953. }
  954. static int
  955. parse_new_protocol(request *req, char *buf, ssize_t readed, int nread)
  956. {
  957. PyObject *env, *c;
  958. char *val = NULL;
  959. env = req->environ;
  960. c = PyDict_GetItemString(env, "HTTP_UPGRADE");
  961. if (c) {
  962. #ifdef PY3
  963. c = PyUnicode_AsLatin1String(c);
  964. val = PyBytes_AS_STRING(c);
  965. #else
  966. val = PyBytes_AS_STRING(c);
  967. Py_INCREF(c);
  968. #endif
  969. DEBUG("Upgrade protocol %s", val);
  970. if (!strcasecmp(val, "websocket")) {
  971. Py_DECREF(c);
  972. //Support only RFC6455
  973. return check_websocket(env);
  974. }
  975. }
  976. // protocol not found error
  977. PyErr_SetString(PyExc_IOError,"unknow protocol");
  978. return -1;
  979. }
  980. static int
  981. parse_http_request(int fd, client_t *client, char *buf, ssize_t r)
  982. {
  983. int nread = 0;
  984. request *req = NULL;
  985. BDEBUG("fd:%d \n%.*s", fd, (int)r, buf);
  986. nread = execute_parse(client, buf, r);
  987. BDEBUG("read request fd %d readed %d nread %d", fd, (int)r, nread);
  988. req = client->current_req;
  989. if (client->upgrade) {
  990. //TODO New protocol
  991. if (parse_new_protocol(req, buf, r, nread) == -1) {
  992. return set_read_error(client, req->bad_request_code);
  993. }
  994. } else if (req == NULL) {
  995. DEBUG("fd %d bad_request code 400", fd);
  996. return set_read_error(client, 400);
  997. } else if (nread != r || req->bad_request_code > 0) {
  998. DEBUG("fd %d bad_request code %d", fd, req->bad_request_code);
  999. return set_read_error(client, req->bad_request_code);
  1000. }
  1001. if (parser_finish(client) > 0) {
  1002. return 1;
  1003. }
  1004. return 0;
  1005. }
  1006. static int
  1007. read_request(picoev_loop *loop, int fd, client_t *client, char call_time_update)
  1008. {
  1009. char buf[READ_BUF_SIZE];
  1010. ssize_t r;
  1011. if (!client->keep_alive) {
  1012. picoev_set_timeout(loop, fd, READ_TIMEOUT_SECS);
  1013. }
  1014. Py_BEGIN_ALLOW_THREADS
  1015. r = read(client->fd, buf, sizeof(buf));
  1016. Py_END_ALLOW_THREADS
  1017. switch (r) {
  1018. case 0:
  1019. return set_read_error(client, 503);
  1020. case -1:
  1021. // Error
  1022. if (errno == EAGAIN || errno == EWOULDBLOCK) {
  1023. // try again later
  1024. return 0;
  1025. } else {
  1026. // Fatal error
  1027. client->keep_alive = 0;
  1028. if (errno == ECONNRESET) {
  1029. client->header_done = 1;
  1030. client->response_closed = 1;
  1031. } else {
  1032. PyErr_SetFromErrno(PyExc_IOError);
  1033. /* write_error_log(__FILE__, __LINE__); */
  1034. call_error_logger();
  1035. }
  1036. return set_read_error(client, 500);
  1037. }
  1038. default:
  1039. if (call_time_update) {
  1040. cache_time_update();
  1041. }
  1042. return parse_http_request(fd, client, buf, r);
  1043. }
  1044. }
  1045. static void
  1046. read_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  1047. {
  1048. client_t *client = ( client_t *)(cb_arg);
  1049. int finish = 0;
  1050. if ((events & PICOEV_TIMEOUT) != 0) {
  1051. finish = read_timeout(fd, client);
  1052. } else if ((events & PICOEV_READ) != 0) {
  1053. finish = read_request(loop, fd, client, 0);
  1054. }
  1055. if (finish == 1) {
  1056. if (!picoev_del(main_loop, client->fd)) {
  1057. activecnt--;
  1058. DEBUG("activecnt:%d", activecnt);
  1059. }
  1060. if (check_status_code(client) > 0) {
  1061. //current request ok
  1062. if (prepare_call_wsgi(client) > 0) {
  1063. call_wsgi_handler(client);
  1064. }
  1065. }
  1066. return;
  1067. }
  1068. }
  1069. static void
  1070. accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
  1071. {
  1072. int client_fd, ret;
  1073. client_t *client;
  1074. struct sockaddr_in client_addr;
  1075. char *remote_addr;
  1076. uint32_t remote_port;
  1077. int finish = 0;
  1078. if ((events & PICOEV_TIMEOUT) != 0) {
  1079. // time out
  1080. // next turn or other process
  1081. return;
  1082. } else if ((events & PICOEV_READ) != 0) {
  1083. int i;
  1084. socklen_t client_len = sizeof(client_addr);
  1085. for (i=0; i<8; ++i) {
  1086. #if linux && defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
  1087. client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
  1088. #else
  1089. client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
  1090. #endif
  1091. if (client_fd != -1) {
  1092. DEBUG("accept fd %d", client_fd);
  1093. //printf("connected: %d\n", client_fd);
  1094. if (setup_sock(client_fd) == -1) {
  1095. PyErr_SetFromErrno(PyExc_IOError);
  1096. /* write_error_log(__FILE__, __LINE__); */
  1097. call_error_logger();
  1098. // die
  1099. loop_done = 0;
  1100. return;
  1101. }
  1102. remote_addr = inet_ntoa (client_addr.sin_addr);
  1103. remote_port = ntohs(client_addr.sin_port);
  1104. client = new_client_t(client_fd, remote_addr, remote_port);
  1105. init_parser(client, server_name, server_port);
  1106. finish = read_request(loop, fd, client, 1);
  1107. if (finish == 1) {
  1108. if (check_status_code(client) > 0) {
  1109. //current request ok
  1110. if (prepare_call_wsgi(client) > 0) {
  1111. call_wsgi_handler(client);
  1112. }
  1113. }
  1114. } else if (finish == 0) {
  1115. ret = picoev_add(loop, client_fd, PICOEV_READ, keep_alive_timeout, read_callback, (void *)client);
  1116. if (ret == 0) {
  1117. activecnt++;
  1118. }
  1119. }
  1120. } else {
  1121. if (errno != EAGAIN && errno != EWOULDBLOCK) {
  1122. PyErr_SetFromErrno(PyExc_IOError);
  1123. /* write_error_log(__FILE__, __LINE__); */
  1124. call_error_logger();
  1125. // die
  1126. kill_server(0);
  1127. }
  1128. break;
  1129. }
  1130. }
  1131. }
  1132. }
  1133. static void
  1134. setup_server_env(void)
  1135. {
  1136. /* setup_listen_sock(listen_sock); */
  1137. cache_time_init();
  1138. setup_static_env(server_name, server_port);
  1139. setup_start_response();
  1140. ClientObject_list_fill();
  1141. client_t_list_fill();
  1142. parser_list_fill();
  1143. request_list_fill();
  1144. buffer_list_fill();
  1145. InputObject_list_fill();
  1146. client_key = NATIVE_FROMSTRING("meinheld.client");
  1147. wsgi_input_key = NATIVE_FROMSTRING("wsgi.input");
  1148. wsgi_input_terminated_key = NATIVE_FROMSTRING("wsgi.input_terminated");
  1149. status_code_key = NATIVE_FROMSTRING("STATUS_CODE");
  1150. bytes_sent_key = NATIVE_FROMSTRING("SEND_BYTES");
  1151. request_time_key = NATIVE_FROMSTRING("REQUEST_TIME");
  1152. local_time_key = NATIVE_FROMSTRING("LOCAL_TIME");
  1153. empty_string = NATIVE_FROMSTRING("");
  1154. }
  1155. static void
  1156. clear_server_env(void)
  1157. {
  1158. //clean
  1159. clear_start_response();
  1160. clear_static_env();
  1161. client_t_list_clear();
  1162. parser_list_clear();
  1163. ClientObject_list_clear();
  1164. request_list_clear();
  1165. buffer_list_clear();
  1166. InputObject_list_clear();
  1167. Py_DECREF(client_key);
  1168. Py_DECREF(wsgi_input_key);
  1169. Py_DECREF(wsgi_input_terminated_key);
  1170. Py_DECREF(status_code_key);
  1171. Py_DECREF(bytes_sent_key);
  1172. Py_DECREF(request_time_key);
  1173. Py_DECREF(local_time_key);
  1174. Py_DECREF(empty_string);
  1175. }
  1176. static int
  1177. inet_listen(void)
  1178. {
  1179. struct addrinfo hints, *servinfo, *p;
  1180. int flag = 1;
  1181. int res;
  1182. char strport[7];
  1183. int listen_sock = 0;
  1184. PyObject *fd = NULL;
  1185. memset(&hints, 0, sizeof hints);
  1186. hints.ai_family = AF_UNSPEC;
  1187. hints.ai_socktype = SOCK_STREAM;
  1188. hints.ai_flags = AI_PASSIVE;
  1189. snprintf(strport, sizeof (strport), "%d", server_port);
  1190. if ((res = getaddrinfo(server_name, strport, &hints, &servinfo)) == -1) {
  1191. PyErr_SetFromErrno(PyExc_IOError);
  1192. return -1;
  1193. }
  1194. // loop through all the results and bind to the first we can
  1195. for(p = servinfo; p != NULL; p = p->ai_next) {
  1196. if ((listen_sock = socket(p->ai_family, p->ai_socktype,
  1197. p->ai_protocol)) == -1) {
  1198. //perror("server: socket");
  1199. continue;
  1200. }
  1201. if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
  1202. sizeof(int)) == -1) {
  1203. close(listen_sock);
  1204. PyErr_SetFromErrno(PyExc_IOError);
  1205. return -1;
  1206. }
  1207. Py_BEGIN_ALLOW_THREADS
  1208. res = bind(listen_sock, p->ai_addr, p->ai_addrlen);
  1209. Py_END_ALLOW_THREADS
  1210. if (res == -1) {
  1211. close(listen_sock);
  1212. PyErr_SetFromErrno(PyExc_IOError);
  1213. return -1;
  1214. }
  1215. break;
  1216. }
  1217. if (p == NULL) {
  1218. close(listen_sock);
  1219. PyErr_SetString(PyExc_IOError,"server: failed to bind\n");
  1220. return -1;
  1221. }
  1222. freeaddrinfo(servinfo); // all done with this structure
  1223. // BACKLOG
  1224. Py_BEGIN_ALLOW_THREADS
  1225. res = listen(listen_sock, backlog);
  1226. Py_END_ALLOW_THREADS
  1227. if (res == -1) {
  1228. close(listen_sock);
  1229. PyErr_SetFromErrno(PyExc_IOError);
  1230. return -1;
  1231. }
  1232. #ifdef PY3
  1233. fd = PyLong_FromLong((long) listen_sock);
  1234. #else
  1235. fd = PyInt_FromLong((long) listen_sock);
  1236. #endif
  1237. listen_socks = PyList_New(0);
  1238. if (PyList_Append(listen_socks, fd) == -1) {
  1239. return -1;
  1240. }
  1241. Py_DECREF(fd);
  1242. return 1;
  1243. }
  1244. static int
  1245. check_unix_sockpath(char *sock_name)
  1246. {
  1247. if (!access(sock_name, F_OK)) {
  1248. if (unlink(sock_name) < 0) {
  1249. PyErr_SetFromErrno(PyExc_IOError);
  1250. return -1;
  1251. }
  1252. }
  1253. return 1;
  1254. }
  1255. static int
  1256. unix_listen(char *sock_name, int len)
  1257. {
  1258. int listen_sock = 0;
  1259. int flag = 1;
  1260. int res;
  1261. struct sockaddr_un saddr;
  1262. mode_t old_umask;
  1263. PyObject *fd;
  1264. DEBUG("unix domain socket %s", sock_name);
  1265. if (len >= sizeof(saddr.sun_path)) {
  1266. PyErr_SetString(PyExc_OSError, "AF_UNIX path too long");
  1267. return -1;
  1268. }
  1269. memset(&saddr, 0, sizeof(saddr));
  1270. if (check_unix_sockpath(sock_name) == -1) {
  1271. return -1;
  1272. }
  1273. if ((listen_sock = socket(AF_UNIX, SOCK_STREAM,0)) == -1) {
  1274. PyErr_SetFromErrno(PyExc_IOError);
  1275. return -1;
  1276. }
  1277. if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
  1278. sizeof(int)) == -1) {
  1279. close(listen_sock);
  1280. PyErr_SetFromErrno(PyExc_IOError);
  1281. return -1;
  1282. }
  1283. saddr.sun_family = PF_UNIX;
  1284. strncpy(saddr.sun_path, sock_name, len);
  1285. old_umask = umask(0);
  1286. Py_BEGIN_ALLOW_THREADS
  1287. res = bind(listen_sock, (struct sockaddr *)&saddr, sizeof(saddr));
  1288. Py_END_ALLOW_THREADS
  1289. if (res == -1) {
  1290. close(listen_sock);
  1291. PyErr_SetFromErrno(PyExc_IOError);
  1292. return -1;
  1293. }
  1294. umask(old_umask);
  1295. // BACKLOG 1024
  1296. Py_BEGIN_ALLOW_THREADS
  1297. res = listen(listen_sock, backlog);
  1298. Py_END_ALLOW_THREADS
  1299. if (res == -1) {
  1300. close(listen_sock);
  1301. PyErr_SetFromErrno(PyExc_IOError);
  1302. return -1;
  1303. }
  1304. unix_sock_name = sock_name;
  1305. #ifdef PY3
  1306. fd = PyLong_FromLong((long) listen_sock);
  1307. #else
  1308. fd = PyInt_FromLong((long) listen_sock);
  1309. #endif
  1310. listen_socks = PyList_New(0);
  1311. if (PyList_Append(listen_socks, fd) == -1) {
  1312. return -1;
  1313. }
  1314. Py_DECREF(fd);
  1315. return 1;
  1316. }
  1317. static void
  1318. fast_notify(void)
  1319. {
  1320. spinner = (spinner + 1) % 2;
  1321. fchmod(tempfile_fd, spinner);
  1322. if (ppid != getppid()) {
  1323. kill_server(gtimeout);
  1324. tempfile_fd = 0;
  1325. }
  1326. }
  1327. static PyObject*
  1328. set_listen_socket(PyObject *temp)
  1329. {
  1330. if (listen_socks != NULL) {
  1331. PyErr_SetString(PyExc_Exception, "already set listen socket");
  1332. return NULL;
  1333. }
  1334. #ifdef PY3
  1335. if (PyLong_Check(temp)) {
  1336. #else
  1337. if (PyInt_Check(temp)) {
  1338. #endif
  1339. listen_socks = PyList_New(0);
  1340. if (PyList_Append(listen_socks, temp) == -1) {
  1341. return NULL;
  1342. }
  1343. Py_DECREF(temp);
  1344. } else if (PyList_Check(temp)) {
  1345. listen_socks = temp;
  1346. Py_INCREF(listen_socks);
  1347. } else {
  1348. PyErr_SetString(PyExc_TypeError, "must be list or int");
  1349. return NULL;
  1350. }
  1351. Py_RETURN_NONE;
  1352. }
  1353. static PyObject *
  1354. meinheld_listen(PyObject *self, PyObject *args, PyObject *kwds)
  1355. {
  1356. PyObject *o = NULL;
  1357. PyObject *sock_fd = NULL;
  1358. char *path;
  1359. int ret, len;
  1360. static char *kwlist[] = {"address", "socket_fd", 0};
  1361. if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:listen",
  1362. kwlist, &o, &sock_fd)) {
  1363. return NULL;
  1364. }
  1365. if (listen_socks != NULL) {
  1366. PyErr_SetString(PyExc_Exception, "already set listen socket");
  1367. return NULL;
  1368. }
  1369. if (o == NULL && sock_fd != NULL) {
  1370. return set_listen_socket(sock_fd);
  1371. } else if (PyTuple_Check(o)) {
  1372. //inet
  1373. if (!PyArg_ParseTuple(o, "si:listen", &server_name, &server_port)) {
  1374. return NULL;
  1375. }
  1376. ret = inet_listen();
  1377. } else if (PyBytes_Check(o)) {
  1378. // unix domain
  1379. if (!PyArg_Parse(o, "s#", &path, &len)) {
  1380. return NULL;
  1381. }
  1382. ret = unix_listen(path, len);
  1383. } else {
  1384. PyErr_SetString(PyExc_TypeError, "args tuple or string(path)");
  1385. return NULL;
  1386. }
  1387. if (ret < 0) {
  1388. //error
  1389. return NULL;
  1390. }
  1391. Py_RETURN_NONE;
  1392. }
  1393. static void
  1394. sigint_cb(int signum)
  1395. {
  1396. DEBUG("call SIGINT");
  1397. if (!catch_signal) {
  1398. catch_signal = signum;
  1399. }
  1400. }
  1401. static void
  1402. sigpipe_cb(int signum)
  1403. {
  1404. DEBUG("call SIGPIPE");
  1405. }
  1406. static PyObject *
  1407. meinheld_access_log(PyObject *self, PyObject *args)
  1408. {
  1409. PyObject *o = NULL;
  1410. PyObject *func = NULL;
  1411. if (!PyArg_ParseTuple(args, "O:access_logger", &o)) {
  1412. return NULL;
  1413. }
  1414. if (o == Py_None) {
  1415. is_write_access_log = 0;
  1416. set_access_logger(NULL);
  1417. Py_RETURN_NONE;
  1418. }
  1419. func = PyObject_GetAttrString(o, "access");
  1420. if (func == NULL) {
  1421. return NULL;
  1422. }
  1423. if (!PyCallable_Check(func)) {
  1424. PyErr_SetString(PyExc_TypeError, "must be callable");
  1425. return NULL;
  1426. }
  1427. set_access_logger(func);
  1428. is_write_access_log = 1;
  1429. Py_RETURN_NONE;
  1430. }
  1431. static PyObject *
  1432. meinheld_error_log(PyObject *self, PyObject *args)
  1433. {
  1434. PyObject *o = NULL;
  1435. PyObject *func = NULL;
  1436. if (!PyArg_ParseTuple(args, "O:error_logger", &o)) {
  1437. return NULL;
  1438. }
  1439. if (o == Py_None) {
  1440. set_err_logger(NULL);
  1441. Py_RETURN_NONE;
  1442. }
  1443. func = PyObject_GetAttrString(o, "error");
  1444. if (func == NULL) {
  1445. return NULL;
  1446. }
  1447. if (!PyCallable_Check(func)) {
  1448. PyErr_SetString(PyExc_TypeError, "must be callable");
  1449. return NULL;
  1450. }
  1451. set_err_logger(func);
  1452. Py_RETURN_NONE;
  1453. }
  1454. static PyObject *
  1455. meinheld_stop(PyObject *self, PyObject *args, PyObject *kwds)
  1456. {
  1457. int timeout = 0;
  1458. static char *kwlist[] = {"timeout", 0};
  1459. if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:timeout",
  1460. kwlist, &timeout)) {
  1461. return NULL;
  1462. }
  1463. kill_server(timeout);
  1464. Py_RETURN_NONE;
  1465. }
  1466. static inline int
  1467. fire_pendings(void)
  1468. {
  1469. int ret = 1;
  1470. TimerObject *timer = NULL;
  1471. pending_queue_t *pendings = g_pendings;
  1472. while(pendings->size && loop_done && activecnt > 0) {
  1473. timer = *(pendings->q + --pendings->size);
  1474. DEBUG("start timer:%p activecnt:%d", timer, activecnt);
  1475. fire_timer(timer);
  1476. Py_DECREF(timer);
  1477. activecnt--;
  1478. DEBUG("fin timer:%p activecnt:%d", timer, activecnt);
  1479. if (PyErr_Occurred()) {
  1480. RDEBUG("pending call raise exception");
  1481. call_error_logger();
  1482. ret = -1;
  1483. break;
  1484. }
  1485. }
  1486. return ret;
  1487. }
  1488. static inline int
  1489. fire_timers(void)
  1490. {
  1491. TimerObject *timer;
  1492. int ret = 1;
  1493. heapq_t *q = g_timers;
  1494. time_t now = current_msec / 1000;
  1495. while(q->size > 0 && loop_done && activecnt > 0) {
  1496. timer = q->heap[0];
  1497. DEBUG("seconds:%d", timer->seconds);
  1498. DEBUG("now:%d", now);
  1499. if (timer->seconds <= now) {
  1500. //call
  1501. timer = heappop(q);
  1502. fire_timer(timer);
  1503. Py_DECREF(timer);
  1504. activecnt--;
  1505. DEBUG("fin timer:%p activecnt:%d", timer, activecnt);
  1506. if (PyErr_Occurred()) {
  1507. RDEBUG("scheduled call raise exception");
  1508. call_error_logger();
  1509. ret = -1;
  1510. break;
  1511. }
  1512. /* timer = q->heap[0]; */
  1513. } else {
  1514. break;
  1515. }
  1516. }
  1517. return ret;
  1518. }
  1519. static int
  1520. listen_all_sockets(void)
  1521. {
  1522. PyObject *iter = NULL, *item = NULL;
  1523. int listen_sock = 0;
  1524. int ret = 0;
  1525. iter = PyObject_GetIter(listen_socks);
  1526. if (PyErr_Occurred()){
  1527. call_error_logger();
  1528. return -1;
  1529. }
  1530. DEBUG("socks iter %p", iter);
  1531. DEBUG("socks size %d", PyList_Size(listen_socks));
  1532. while((item = PyIter_Next(iter))){
  1533. #ifdef PY3
  1534. if (PyLong_Check(item)) {
  1535. listen_sock = (int)PyLong_AsLong(item);
  1536. #else
  1537. if (PyInt_Check(item)) {
  1538. listen_sock = (int)PyInt_AsLong(item);
  1539. #endif
  1540. setup_listen_sock(listen_sock);
  1541. ret = picoev_add(main_loop, listen_sock, PICOEV_READ, ACCEPT_TIMEOUT_SECS, accept_callback, NULL);
  1542. if (ret == 0) {
  1543. activecnt++;
  1544. }
  1545. }
  1546. Py_DECREF(item);
  1547. }
  1548. Py_DECREF(iter);
  1549. return 1;
  1550. }
  1551. static int
  1552. close_all_sockets(void)
  1553. {
  1554. PyObject *iter = NULL, *item = NULL;
  1555. int listen_sock = 0;
  1556. iter = PyObject_GetIter(listen_socks);
  1557. if (PyErr_Occurred()){
  1558. call_error_logger();
  1559. return -1;
  1560. }
  1561. while((item = PyIter_Next(iter))){
  1562. #ifdef PY3
  1563. if (PyLong_Check(item)) {
  1564. listen_sock = (int)PyLong_AsLong(item);
  1565. #else
  1566. if (PyInt_Check(item)) {
  1567. listen_sock = (int)PyInt_AsLong(item);
  1568. #endif
  1569. close(listen_sock);
  1570. if (unix_sock_name) {
  1571. unlink(unix_sock_name);
  1572. unix_sock_name = NULL;
  1573. }
  1574. }
  1575. Py_DECREF(item);
  1576. }
  1577. Py_DECREF(iter);
  1578. return 1;
  1579. }
  1580. static PyObject *
  1581. meinheld_run_loop(PyObject *self, PyObject *args, PyObject *kwds)
  1582. {
  1583. PyObject *watchdog_result;
  1584. int silent = 0;
  1585. int interrupted = 0;
  1586. static char *kwlist[] = {"app", "silent", 0};
  1587. if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:run",
  1588. kwlist, &wsgi_app, &silent)) {
  1589. return NULL;
  1590. }
  1591. if (listen_socks == NULL) {
  1592. PyErr_Format(PyExc_TypeError, "not found listen socket");
  1593. return NULL;
  1594. }
  1595. Py_INCREF(wsgi_app);
  1596. setup_server_env();
  1597. init_main_loop();
  1598. loop_done = 1;
  1599. PyOS_setsig(SIGPIPE, sigpipe_cb);
  1600. PyOS_setsig(SIGINT, sigint_cb);
  1601. PyOS_setsig(SIGTERM, sigint_cb);
  1602. if (listen_all_sockets() < 0) {
  1603. //FATAL Error
  1604. return NULL;
  1605. }
  1606. /* loop */
  1607. while (likely(loop_done == 1 && activecnt > 0)) {
  1608. /* DEBUG("before activecnt:%d", activecnt); */
  1609. fire_pendings();
  1610. fire_timers();
  1611. picoev_loop_once(main_loop, 10);
  1612. if (unlikely(catch_signal != 0)) {
  1613. if (catch_signal == SIGINT) {
  1614. interrupted = 1;
  1615. }
  1616. catch_signal = 0;
  1617. kill_server(0);
  1618. }
  1619. if (watch_loop && watchdog_lasttime != main_loop->now) {
  1620. watchdog_lasttime = main_loop->now;
  1621. if (tempfile_fd) {
  1622. fast_notify();
  1623. } else if (watchdog) {
  1624. watchdog_result = PyObject_CallFunction(watchdog, NULL);
  1625. if (PyErr_Occurred()) {
  1626. PyErr_Print();
  1627. PyErr_Clear();
  1628. }
  1629. Py_XDECREF(watchdog_result);
  1630. }
  1631. }
  1632. /* DEBUG("after activecnt:%d", activecnt); */
  1633. /* DEBUG("pendings->size:%d", g_pendings->size); */
  1634. }
  1635. Py_DECREF(wsgi_app);
  1636. Py_CLEAR(watchdog);
  1637. current_client = NULL;
  1638. picoev_destroy_loop(main_loop);
  1639. picoev_deinit();
  1640. main_loop = NULL;
  1641. clear_server_env();
  1642. if (close_all_sockets() < 0) {
  1643. Py_CLEAR(listen_socks);
  1644. return NULL;
  1645. }
  1646. Py_CLEAR(listen_socks);
  1647. if (!silent && interrupted) {
  1648. //override
  1649. PyErr_Clear();
  1650. PyErr_SetNone(PyExc_KeyboardInterrupt);
  1651. return NULL;
  1652. }
  1653. Py_RETURN_NONE;
  1654. }
  1655. PyObject *
  1656. meinheld_set_keepalive(PyObject *self, PyObject *args)
  1657. {
  1658. int on;
  1659. if (!PyArg_ParseTuple(args, "i", &on))
  1660. return NULL;
  1661. if (on < 0) {
  1662. PyErr_SetString(PyExc_ValueError, "keep alive value out of range ");
  1663. return NULL;
  1664. }
  1665. is_keep_alive = on;
  1666. if (is_keep_alive) {
  1667. keep_alive_timeout = on;
  1668. } else {
  1669. keep_alive_timeout = 2;
  1670. }
  1671. Py_RETURN_NONE;
  1672. }
  1673. PyObject *
  1674. meinheld_get_keepalive(PyObject *self, PyObject *args)
  1675. {
  1676. return Py_BuildValue("i", is_keep_alive);
  1677. }
  1678. PyObject *
  1679. meinheld_set_backlog(PyObject *self, PyObject *args)
  1680. {
  1681. int temp;
  1682. if (!PyArg_ParseTuple(args, "i", &temp))
  1683. return NULL;
  1684. if (temp <= 0) {
  1685. PyErr_SetString(PyExc_ValueError, "backlog value out of range ");
  1686. return NULL;
  1687. }
  1688. backlog = temp;
  1689. Py_RETURN_NONE;
  1690. }
  1691. PyObject *
  1692. meinheld_get_backlog(PyObject *self, PyObject *args)
  1693. {
  1694. return Py_BuildValue("i", backlog);
  1695. }
  1696. PyObject *
  1697. meinheld_set_picoev_max_fd(PyObject *self, PyObject *args)
  1698. {
  1699. int temp;
  1700. if (!PyArg_ParseTuple(args, "i", &temp))
  1701. return NULL;
  1702. if (temp <= 0) {
  1703. PyErr_SetString(PyExc_ValueError, "max_fd value out of range ");
  1704. return NULL;
  1705. }
  1706. max_fd = temp;
  1707. Py_RETURN_NONE;
  1708. }
  1709. PyObject *
  1710. meinheld_get_picoev_max_fd(PyObject *self, PyObject *args)
  1711. {
  1712. return Py_BuildValue("i", max_fd);
  1713. }
  1714. PyObject *
  1715. meinheld_set_max_content_length(PyObject *self, PyObject *args)
  1716. {
  1717. int temp;
  1718. if (!PyArg_ParseTuple(args, "i", &temp))
  1719. return NULL;
  1720. if (temp <= 0) {
  1721. PyErr_SetString(PyExc_ValueError, "max_content_length value out of range ");
  1722. return NULL;
  1723. }
  1724. max_content_length = temp;
  1725. Py

Large files files are truncated, but you can click here to view the full file