Merge branch 'refs/heads/t/blob'
[paraslash.git] / http_send.c
index d692c2d..330b45a 100644 (file)
@@ -16,6 +16,7 @@
 #include "error.h"
 #include "string.h"
 #include "afh.h"
+#include "net.h"
 #include "server.h"
 #include "http.h"
 #include "list.h"
 #include "sched.h"
 #include "vss.h"
 #include "close_on_fork.h"
-#include "net.h"
 #include "fd.h"
 #include "chunk_queue.h"
-#include "acl.h"
 
 /** Message sent to clients that do not send a valid get request. */
 #define HTTP_ERR_MSG "HTTP/1.0 400 Bad Request\n"
@@ -77,6 +76,12 @@ static void http_shutdown_clients(void)
        shutdown_clients(hss);
 }
 
+static void http_shutdown(void)
+{
+       http_shutdown_clients();
+       generic_acl_deplete(&hss->acl);
+}
+
 static int queue_chunk_or_shutdown(struct sender_client *sc,
                struct sender_status *ss, const char *buf, size_t num_bytes)
 {
@@ -193,10 +198,13 @@ static void http_post_select(fd_set *rfds, __a_unused fd_set *wfds)
 static void http_pre_select(int *max_fileno, fd_set *rfds, fd_set *wfds)
 {
        struct sender_client *sc, *tmp;
+       unsigned n;
 
-       if (hss->listen_fd < 0)
-               return;
-       para_fd_set(hss->listen_fd, rfds, max_fileno);
+       FOR_EACH_LISTEN_FD(n, hss) {
+               if (hss->listen_fds[n] < 0)
+                       continue;
+               para_fd_set(hss->listen_fds[n], rfds, max_fileno);
+       }
        list_for_each_entry_safe(sc, tmp, &hss->client_list, node) {
                struct private_http_sender_data *phsd = sc->private_data;
                if (phsd->status == HTTP_CONNECTED) /* need to recv get request */
@@ -236,34 +244,45 @@ static char *http_status(void)
        return generic_sender_status(hss, "http");
 }
 
-/**
- * The init function of the http sender.
- *
- * \param s Pointer to the http sender struct.
- *
- * It initializes all function pointers of \a s, the client list and the access
- * control list. If the autostart option was given, the tcp port is opened.
+/*
+ * Initialize the client list and the access control list, and optionally
+ * listen on the tcp port.
  */
-void http_send_init(struct sender *s)
+static void http_send_init(void)
 {
-       s->status = http_status;
-       s->send = http_send;
-       s->pre_select = http_pre_select;
-       s->post_select = http_post_select;
-       s->shutdown_clients = http_shutdown_clients;
-       s->resolve_target = NULL;
-       s->help = generic_sender_help;
-       s->client_cmds[SENDER_on] = http_com_on;
-       s->client_cmds[SENDER_off] = http_com_off;
-       s->client_cmds[SENDER_deny] = http_com_deny;
-       s->client_cmds[SENDER_allow] = http_com_allow;
-       s->client_cmds[SENDER_add] = NULL;
-       s->client_cmds[SENDER_delete] = NULL;
-
        init_sender_status(hss, OPT_RESULT(HTTP_ACCESS),
+               OPT_RESULT(HTTP_LISTEN_ADDRESS),
                OPT_UINT32_VAL(HTTP_PORT), OPT_UINT32_VAL(HTTP_MAX_CLIENTS),
                OPT_GIVEN(HTTP_DEFAULT_DENY));
        if (OPT_GIVEN(HTTP_NO_AUTOSTART))
                return;
        generic_com_on(hss, IPPROTO_TCP);
 }
+
+/**
+ * The HTTP sender.
+ *
+ * This is the only sender which does not FEC-encode the stream. This is not
+ * necessary because HTTP sits on top of TCP, a reliable transport which
+ * retransmits lost packets automatically. The sender employs per-client queues
+ * which queue chunks of audio data if they can not be sent immediately because
+ * the write operation would block. Most methods of the sender are implemented
+ * as wrappers for the generic functions defined in \ref send_common.c.
+ */
+const struct sender http_sender = {
+       .name = "http",
+       .init = http_send_init,
+       .shutdown = http_shutdown,
+       .pre_select = http_pre_select,
+       .post_select = http_post_select,
+       .send = http_send,
+       .shutdown_clients = http_shutdown_clients,
+       .client_cmds = {
+               [SENDER_on] = http_com_on,
+               [SENDER_off] = http_com_off,
+               [SENDER_deny] = http_com_deny,
+               [SENDER_allow] = http_com_allow,
+       },
+       .help = generic_sender_help,
+       .status = http_status,
+};