mptsd reads mpegts streams from udp/multicast or http and combines them into one multiple program stream that is suitable for outputting to DVB-C modulator. Tested with Dektec DTE-3114 Quad QAM Modulator and used in production in small DVB-C networks. https://georgi.unixsol.org/programs/mptsd/

web_server.c 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * mptsd internal web server
  3. * Copyright (C) 2010-2011 Unix Solutions Ltd.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  17. */
  18. #include <stdlib.h>
  19. #include <regex.h>
  20. #include <errno.h>
  21. #include <string.h>
  22. #include <signal.h>
  23. #include <arpa/inet.h>
  24. #include <netinet/in.h>
  25. #include "libfuncs/libfuncs.h"
  26. #include "web_pages.h"
  27. #include "web_server.h"
  28. typedef struct req_info {
  29. int clientsock;
  30. struct sockaddr_in client;
  31. } request_info;
  32. extern int keep_going;
  33. #define NEXT_CLIENT { FREE(path); FREE(buf); pthread_exit(0); }
  34. #define SHUTDOWN_CLIENT { FREE(path); FREE(buf); shutdown_fd(&clientsock); pthread_exit(0); }
  35. #define BUF_SIZE 1024
  36. void *process_web_request(void *);
  37. void *web_server_thread(void *data) {
  38. CONFIG *conf = data;
  39. while (keep_going) {
  40. struct sockaddr_in client;
  41. unsigned int clientlen = sizeof(client);
  42. int clientsock;
  43. clientsock = accept(conf->server_socket, (struct sockaddr *) &client, &clientlen);
  44. if (clientsock < 0) {
  45. if (conf->server_socket > -1) // The server_socket is closed on exit, so do not report errors
  46. LOGf("ERROR : Failed to accept client fd: %i err: %s\n", clientsock, strerror(errno));
  47. if (errno==EMFILE || errno==ENFILE) /* No more FDs */
  48. break;
  49. } else {
  50. request_info *req;
  51. pthread_t req_thread;
  52. req = malloc(sizeof(request_info));
  53. if (!req) {
  54. log_perror("Can't allocate request_info", errno);
  55. continue;
  56. }
  57. req->clientsock = clientsock;
  58. req->client = client;
  59. if (pthread_create(&req_thread, NULL, (void *)&process_web_request, (void *)req)) {
  60. log_perror("Error creating request processing thread.", errno);
  61. exit(1);
  62. }
  63. pthread_detach(req_thread);
  64. }
  65. }
  66. pthread_exit(0);
  67. }
  68. void web_server_start(CONFIG *conf) {
  69. if (conf->server_socket > -1)
  70. pthread_create(&conf->server_thread, NULL, &web_server_thread, conf);
  71. }
  72. void web_server_stop(CONFIG *conf) {
  73. if (conf->server_socket > -1) {
  74. shutdown_fd(&conf->server_socket);
  75. pthread_join(conf->server_thread, NULL);
  76. }
  77. }
  78. void *process_web_request(void *in_req) {
  79. request_info *req = (request_info *)in_req;
  80. int clientsock = req->clientsock;
  81. regmatch_t res[3];
  82. char *path=NULL, *buf=NULL;
  83. FREE(req);
  84. signal(SIGPIPE, SIG_IGN);
  85. if (!keep_going)
  86. pthread_exit(0);
  87. buf = malloc(BUF_SIZE);
  88. if (!buf) {
  89. log_perror("Can't allocate buffer", errno);
  90. SHUTDOWN_CLIENT;
  91. }
  92. if (fdgetline(clientsock,buf,BUF_SIZE)<=0) {
  93. SHUTDOWN_CLIENT;
  94. }
  95. regex_t request_get;
  96. regcomp(&request_get, "^GET /([^ ]*) HTTP/1.*$", REG_EXTENDED);
  97. if (regexec(&request_get,buf,2,res,0)==REG_NOMATCH) {
  98. send_501_not_implemented(clientsock);
  99. SHUTDOWN_CLIENT;
  100. }
  101. buf[res[1].rm_eo]=0;
  102. chomp(buf+res[1].rm_so);
  103. if (buf[res[1].rm_eo-1]=='/') buf[res[1].rm_eo-1]=0;
  104. path = strdup(buf+res[1].rm_so);
  105. regfree(&request_get);
  106. while (fdgetline(clientsock,buf,BUF_SIZE) > 0) {
  107. if (buf[0] == '\n' || buf[0] == '\r') // End of headers
  108. break;
  109. }
  110. if (strlen(path) == 0) {
  111. cmd_index(clientsock);
  112. } else if (strstr(path,"reconnect")==path) {
  113. cmd_reconnect(clientsock);
  114. } else {
  115. send_404_not_found(clientsock);
  116. }
  117. SHUTDOWN_CLIENT;
  118. }