[vlc-commits] http: stream write callback

Rémi Denis-Courmont git at videolan.org
Sun Oct 4 12:26:20 CEST 2020


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Oct  1 23:10:45 2020 +0300| [62be79b1cb281768ac0c0ef10b87cf1c454b2dd4] | committer: Rémi Denis-Courmont

http: stream write callback

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=62be79b1cb281768ac0c0ef10b87cf1c454b2dd4
---

 modules/access/http/chunked.c   |  1 +
 modules/access/http/file_test.c |  1 +
 modules/access/http/h1conn.c    |  1 +
 modules/access/http/h2conn.c    |  1 +
 modules/access/http/message.c   | 31 +++++++++++++++++++++++++++++++
 modules/access/http/message.h   | 35 +++++++++++++++++++++++++++++++++++
 6 files changed, 70 insertions(+)

diff --git a/modules/access/http/chunked.c b/modules/access/http/chunked.c
index 549f590ebd..eb94299cae 100644
--- a/modules/access/http/chunked.c
+++ b/modules/access/http/chunked.c
@@ -146,6 +146,7 @@ static void vlc_chunked_close(struct vlc_http_stream *stream, bool abort)
 static struct vlc_http_stream_cbs vlc_chunked_callbacks =
 {
     vlc_chunked_wait,
+    NULL,
     vlc_chunked_read,
     vlc_chunked_close,
 };
diff --git a/modules/access/http/file_test.c b/modules/access/http/file_test.c
index 0c300ddf0b..5779812056 100644
--- a/modules/access/http/file_test.c
+++ b/modules/access/http/file_test.c
@@ -327,6 +327,7 @@ static void stream_close(struct vlc_http_stream *s, bool abort)
 static const struct vlc_http_stream_cbs stream_callbacks =
 {
     stream_read_headers,
+    NULL,
     stream_read,
     stream_close,
 };
diff --git a/modules/access/http/h1conn.c b/modules/access/http/h1conn.c
index 5a427f41a6..ee7072793b 100644
--- a/modules/access/http/h1conn.c
+++ b/modules/access/http/h1conn.c
@@ -286,6 +286,7 @@ static void vlc_h1_stream_close(struct vlc_http_stream *stream, bool abort)
 static const struct vlc_http_stream_cbs vlc_h1_stream_callbacks =
 {
     vlc_h1_stream_wait,
+    NULL,
     vlc_h1_stream_read,
     vlc_h1_stream_close,
 };
diff --git a/modules/access/http/h2conn.c b/modules/access/http/h2conn.c
index 54022168e9..93106cdc76 100644
--- a/modules/access/http/h2conn.c
+++ b/modules/access/http/h2conn.c
@@ -404,6 +404,7 @@ static void vlc_h2_stream_close(struct vlc_http_stream *stream, bool aborted)
 static const struct vlc_http_stream_cbs vlc_h2_stream_callbacks =
 {
     vlc_h2_stream_wait,
+    NULL,
     vlc_h2_stream_read,
     vlc_h2_stream_close,
 };
diff --git a/modules/access/http/message.c b/modules/access/http/message.c
index 232b340c44..d6df07769e 100644
--- a/modules/access/http/message.c
+++ b/modules/access/http/message.c
@@ -33,6 +33,7 @@
 
 #include <vlc_common.h>
 #include <vlc_http.h>
+#include <vlc_block.h>
 #include <vlc_strings.h>
 #include <vlc_memstream.h>
 #include "message.h"
@@ -293,6 +294,36 @@ block_t *vlc_http_msg_read(struct vlc_http_msg *m)
     return vlc_http_stream_read(m->payload);
 }
 
+int vlc_http_msg_write(struct vlc_http_msg *m, block_t *block, bool eos)
+{
+    if (m->payload == NULL)
+        return -1;
+
+    /* Ideally, we'd send the end-of-stream with the last block of data.
+     * But if there are zero blocks, then we have to send it separately.
+     */
+    if (block == NULL && eos)
+        return vlc_http_stream_write(m->payload, NULL, 0, true);
+
+    while (block != NULL)
+    {
+        block_t *next = block->p_next;
+        bool end = eos && next == NULL;
+
+        if (vlc_http_stream_write(m->payload, block->p_buffer, block->i_buffer,
+                                  end) < (ssize_t)block->i_buffer)
+            goto error;
+
+        block_Release(block);
+        block = next;
+    }
+
+    return 0;
+error:
+    block_ChainRelease(block);
+    return -1;
+}
+
 /* Serialization and deserialization */
 
 char *vlc_http_msg_format(const struct vlc_http_msg *m, size_t *restrict lenp,
diff --git a/modules/access/http/message.h b/modules/access/http/message.h
index 45e9b7c353..eec3bad9e4 100644
--- a/modules/access/http/message.h
+++ b/modules/access/http/message.h
@@ -288,6 +288,20 @@ struct vlc_http_msg *vlc_http_msg_get_final(struct vlc_http_msg *) VLC_USED;
  */
 struct block_t *vlc_http_msg_read(struct vlc_http_msg *) VLC_USED;
 
+/**
+ * Sends HTTP data.
+ *
+ * Queues the next block of data for an HTTP message payload.
+ *
+ * @note This function takes ownership of the passed data block(s).
+ *
+ * @param b chain of block of data to be sent
+ * @param eos true to indicate the end of the payload
+ * @retval 0 success
+ * @retval -1 fatal error
+ */
+int vlc_http_msg_write(struct vlc_http_msg *, block_t *b, bool eos);
+
 /** @} */
 
 /**
@@ -333,6 +347,7 @@ VLC_USED;
 struct vlc_http_stream_cbs
 {
     struct vlc_http_msg *(*read_headers)(struct vlc_http_stream *);
+    ssize_t (*write)(struct vlc_http_stream *, const void *, size_t, bool eos);
     struct block_t *(*read)(struct vlc_http_stream *);
     void (*close)(struct vlc_http_stream *, bool abort);
 };
@@ -360,6 +375,26 @@ struct vlc_http_msg *vlc_http_stream_read_headers(struct vlc_http_stream *s)
     return s->cbs->read_headers(s);
 }
 
+/**
+ * Write message payload data.
+ *
+ * Writes data as message payload of an HTTP stream.
+ *
+ * @todo Take a block structure rather than a byte array.
+ *
+ * @param base start address of data to write
+ * @param length length in bytes of data to write
+ * @param eos whether this is the last write on the stream
+ * @retval len success
+ * @retval -1 error
+ */
+static inline ssize_t vlc_http_stream_write(struct vlc_http_stream *s,
+                                            const void *base, size_t length,
+                                            bool eos)
+{
+    return s->cbs->write(s, base, length, eos);
+}
+
 /**
  * Reads message payload data.
  *



More information about the vlc-commits mailing list