[FFmpeg-devel] [PATCH] lavf/http: Rework http_write_reply()

Stephan Holljes klaxa1337 at googlemail.com
Fri Aug 21 20:03:23 CEST 2015


Add error codes 301 and 503, make replies more customizable
and use AVBPrint for strings.

Signed-off-by: Stephan Holljes <klaxa1337 at googlemail.com>
---
 libavformat/http.c | 74 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 62 insertions(+), 12 deletions(-)

Earlier version added an extra newline when sending a reply with a body.


diff --git a/libavformat/http.c b/libavformat/http.c
index 9044c27..fba87ac 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -27,6 +27,7 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
 #include "libavutil/opt.h"
 
 #include "avformat.h"
@@ -330,11 +331,15 @@ int ff_http_averror(int status_code, int default_averror)
 static int http_write_reply(URLContext* h, int status_code)
 {
     int ret, body = 0, reply_code, message_len;
-    const char *reply_text, *content_type;
+    const char *reply_text, *content_type, *location = NULL, *headers = "\r\n";
     HTTPContext *s = h->priv_data;
-    char message[BUFFER_SIZE];
+    AVBPrint message;
+    AVBPrint body_content;
     content_type = "text/plain";
 
+    av_bprint_init(&message,      BUFFER_SIZE, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprint_init(&body_content, BUFFER_SIZE, AV_BPRINT_SIZE_AUTOMATIC);
+
     if (status_code < 0)
         body = 1;
     switch (status_code) {
@@ -358,31 +363,69 @@ static int http_write_reply(URLContext* h, int status_code)
         reply_text = "OK";
         content_type = "application/octet-stream";
         break;
+    case 301:
+        reply_code = 301;
+        reply_text = "Moved Permanently";
+        if (!s->location) {
+            av_log(s, AV_LOG_WARNING, "Reply code 301, but no redirection url set\n");
+            break;
+        }
+        location = s->location;
+
+        break;
     case AVERROR_HTTP_SERVER_ERROR:
     case 500:
         reply_code = 500;
         reply_text = "Internal server error";
         break;
+    case 503:
+        reply_code = 503;
+        reply_text = "Service Unavailable";
+        break;
     default:
         return AVERROR(EINVAL);
     }
+    if (s->reply_text)
+        reply_text = s->reply_text;
+    if (s->content_type)
+        content_type = s->content_type;
+    if (s->headers)
+        headers = s->headers;
+    if (s->body) {
+        av_bprintf(&body_content, s->body);
+        body = 1;
+    } else {
+        av_bprintf(&body_content, "%03d %s\r\n", reply_code, reply_text);
+    }
+
+    if (!av_bprint_is_complete(&body_content)) {
+        av_log(s, AV_LOG_WARNING, "Content truncated.\n");
+        message_len = body_content.size;
+    } else
+        message_len = body_content.len;
+
     if (body) {
         s->chunked_post = 0;
-        message_len = snprintf(message, sizeof(message),
+        av_bprintf(&message,
                  "HTTP/1.1 %03d %s\r\n"
                  "Content-Type: %s\r\n"
-                 "Content-Length: %zu\r\n"
-                 "\r\n"
-                 "%03d %s\r\n",
+                 "Content-Length: %zu\r\n",
                  reply_code,
                  reply_text,
                  content_type,
-                 strlen(reply_text) + 6, // 3 digit status code + space + \r\n
-                 reply_code,
-                 reply_text);
+                 message_len);
+        if (location)
+            av_bprintf(&message,
+                 "Location: %s\r\n", location);
+        av_bprintf(&message,
+                 "%s"
+                 "%s",
+                 headers,
+                 body_content.str);
+
     } else {
         s->chunked_post = 1;
-        message_len = snprintf(message, sizeof(message),
+        av_bprintf(&message,
                  "HTTP/1.1 %03d %s\r\n"
                  "Content-Type: %s\r\n"
                  "Transfer-Encoding: chunked\r\n"
@@ -391,8 +434,15 @@ static int http_write_reply(URLContext* h, int status_code)
                  reply_text,
                  content_type);
     }
-    av_log(h, AV_LOG_TRACE, "HTTP reply header: \n%s----\n", message);
-    if ((ret = ffurl_write(s->hd, message, message_len)) < 0)
+    if (!av_bprint_is_complete(&message)) {
+        av_log(s, AV_LOG_WARNING, "Reply truncated.\n");
+        message_len = message.size;
+    } else
+        message_len = message.len;
+
+    av_log(h, AV_LOG_TRACE, "HTTP reply header: \n%s----\n", message.str);
+
+    if ((ret = ffurl_write(s->hd, message.str, message_len)) < 0)
         return ret;
     return 0;
 }
-- 
2.1.0



More information about the ffmpeg-devel mailing list