Tests about a simple python3 fastcgi runner using libfcgi and the Python-C API.
python
c
wsgi
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

monitor.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "monitor.h"
  2. pid_t pyfcgi_spawn_monitor()
  3. {
  4. pid_t res;
  5. res = fork();
  6. if(res == -1)
  7. {
  8. pyfcgi_log(LOG_ALERT, "Unable to fork into monitoring server process : %s",
  9. strerror(errno));
  10. sleep(1);
  11. }
  12. if(!res)
  13. {
  14. pyfcgi_logger_set_ident("StatServ");
  15. pyfcgi_monitor_init();
  16. pyfcgi_monitor_loop();
  17. pyfcgi_log(LOG_ALERT, "Monitor loop should never return but just did it...");
  18. exit(PYFCGI_FATAL);
  19. }
  20. return res;
  21. }
  22. void pyfcgi_monitor_init()
  23. {
  24. }
  25. void pyfcgi_monitor_loop()
  26. {
  27. }
  28. int pyfcgi_monitor_check_sock(const char* sockurl)
  29. {
  30. const char *port;
  31. short tcp;
  32. const char *urlorig;
  33. urlorig = sockurl;
  34. if(!(tcp = strncasecmp("tcp://", sockurl, 6)) ||
  35. !strncasecmp("udp://", sockurl, 6))
  36. {
  37. sockurl += 6; //first addr chr
  38. }
  39. else if(!strncasecmp("unix://", sockurl, 7))
  40. {
  41. sockurl += 7;
  42. if(!strlen(sockurl))
  43. {
  44. dprintf(2, "UNIX socket missing file path : '%s'\n",
  45. urlorig);
  46. return -1;
  47. }
  48. if(strlen(sockurl) > UNIX_SOCKPATH_MAX)
  49. {
  50. dprintf(2, "UNIX socket support only path with length <= %d but given path is %ld bytes long : '%s'",
  51. UNIX_SOCKPATH_MAX, strlen(sockurl), urlorig);
  52. return -1;
  53. }
  54. return 0;
  55. }
  56. else
  57. {
  58. dprintf(2, "Invalid protocol in '%s'\n", sockurl);
  59. return -1;
  60. }
  61. do { sockurl++; } while(*sockurl && *sockurl != ':');
  62. if(!sockurl)
  63. {
  64. dprintf(2, "%s protocol choosen but not port given : '%s'\n",
  65. tcp?"TCP":"UDP", sockurl);
  66. return -1;
  67. }
  68. if(!*sockurl)
  69. {
  70. dprintf(2, "Port missing in socket URL '%s'\n", urlorig);
  71. return -1;
  72. }
  73. sockurl++;
  74. port = sockurl;
  75. while(*sockurl && *sockurl >= '0' && *sockurl <= '9')
  76. {
  77. sockurl++;
  78. }
  79. if(*sockurl)
  80. {
  81. dprintf(2, "Invalid port '%s' in socket URL '%s'\n",
  82. port, urlorig);
  83. return -1;
  84. }
  85. return 0;
  86. }
  87. int pyfcgi_monitor_parse_sock(const char *sockurl, int sockargs[3],
  88. pyfcgi_monitor_addr_t *listen_addr)
  89. {
  90. const char *addr_ptr;
  91. short tcp;
  92. int *domain, *type, *protocol;
  93. struct sockaddr_un *addr_un;
  94. domain = &sockargs[0];
  95. type = &sockargs[1];
  96. protocol = &sockargs[2];
  97. addr_un = &(listen_addr->un);
  98. if(!strncasecmp("unix://", sockurl, 7))
  99. {
  100. addr_ptr = sockurl + 7;
  101. *domain = AF_UNIX;
  102. *type = SOCK_STREAM;
  103. *protocol = 0;
  104. addr_un->sun_family = AF_UNIX;
  105. strncpy(addr_un->sun_path, addr_ptr, UNIX_SOCKPATH_MAX);
  106. return 0;
  107. }
  108. if((tcp = strncasecmp("tcp://", sockurl, 6)) &&
  109. strncasecmp("udp://", sockurl, 6))
  110. { //Unchecked URL??!!
  111. pyfcgi_log(LOG_ERR, "Invalid protocol in URL : '%s'",
  112. sockurl);
  113. return -1;
  114. }
  115. addr_ptr = sockurl + 6;
  116. *type = tcp ? SOCK_DGRAM : SOCK_STREAM;
  117. *protocol = 0;
  118. if(pyfcgi_monitor_parse_inet_addr(addr_ptr, *type, listen_addr, domain))
  119. {
  120. return -1;
  121. }
  122. return 0;
  123. }
  124. int pyfcgi_monitor_parse_inet_addr(const char* addr_str, int socktype,
  125. pyfcgi_monitor_addr_t *listen_addr, int* domain)
  126. {
  127. char *addr, *port, *ptr, *ipstr;
  128. char v6str[64];
  129. struct addrinfo *infos, hints, *info;
  130. short v4, v6, i;
  131. int ret;
  132. // initialize temporary address & port pointers
  133. addr = strdup(addr_str);
  134. if(!addr)
  135. {
  136. pyfcgi_log(LOG_ALERT, "strdup() failed to copy socket addr : %s",
  137. strerror(errno));
  138. return -1;
  139. }
  140. ptr = addr;
  141. do { ptr++; }while(*ptr && *ptr != ':');
  142. if(!ptr)
  143. {
  144. pyfcgi_log(LOG_ERR, "No port found in INET url : %s",
  145. addr_str);
  146. goto free_err;
  147. }
  148. *ptr = '\0';
  149. port = ptr+1;
  150. memset(&hints, 0, sizeof(struct addrinfo));
  151. v4 = PyFCGI_conf.ipv4;
  152. v6 = PyFCGI_conf.ipv6;
  153. hints.ai_family = (v4?AF_INET:(v6?AF_INET6:PF_UNSPEC));
  154. hints.ai_socktype = socktype;
  155. hints.ai_flags = AI_CANONNAME;
  156. if((ret = getaddrinfo(addr, port, &hints, &infos)))
  157. {
  158. pyfcgi_log(LOG_ALERT, "getaddrinfo fails on '%s' : %s",
  159. gai_strerror(ret));
  160. goto free_err;
  161. }
  162. for(info = infos; info != NULL; info = info->ai_next)
  163. {
  164. if(info->ai_family == AF_INET)
  165. {
  166. memcpy(&listen_addr->in, info->ai_addr,
  167. info->ai_addrlen);
  168. ipstr = inet_ntoa(listen_addr->in.sin_addr);
  169. }
  170. else if(info->ai_family == AF_INET6)
  171. {
  172. memcpy(&listen_addr->in6, info->ai_addr,
  173. info->ai_addrlen);
  174. ptr = v6str;
  175. for(i=0; i<16; i++)
  176. {
  177. ptr += snprintf(ptr, 4,
  178. "%s%02X", ((i==0)?"":":"),
  179. listen_addr->in6.sin6_addr.s6_addr[i]);
  180. }
  181. ipstr = v6str;
  182. }
  183. else
  184. {
  185. continue;
  186. }
  187. *domain = info->ai_family;
  188. pyfcgi_log(LOG_DEBUG, "Listen addr resolved to %s(%s)",
  189. info->ai_canonname, ipstr);
  190. freeaddrinfo(infos);
  191. free(addr);
  192. return 0;
  193. }
  194. pyfcgi_log(LOG_ERR, "Unable to resolve to a valid AF_INET[6] address");
  195. freeaddrinfo(infos);
  196. free_err:
  197. free(addr);
  198. return -1;
  199. }