Merge commit '4ff99ab3d7d5576e99e6b8a411b4a44500ed88fa'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 12 Mar 2014 01:52:17 +0000 (02:52 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 12 Mar 2014 01:52:17 +0000 (02:52 +0100)
* commit '4ff99ab3d7d5576e99e6b8a411b4a44500ed88fa':
  http: Refactor process_line

Conflicts:
libavformat/http.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/http.c

@@@ -326,6 -303,83 +326,83 @@@ static int http_get_line(HTTPContext *s
      }
  }
  
 -    h->is_streamed = 0; /* we _can_ in fact seek */
+ static int check_http_code(URLContext *h, int http_code, const char *end)
+ {
+     HTTPContext *s = h->priv_data;
+     /* error codes are 4xx and 5xx, but regard 401 as a success, so we
+      * don't abort until all headers have been parsed. */
+     if (http_code >= 400 && http_code < 600 &&
+         (http_code != 401 || s->auth_state.auth_type != HTTP_AUTH_NONE) &&
+         (http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
+         end += strspn(end, SPACE_CHARS);
+         av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", http_code, end);
+         return AVERROR(EIO);
+     }
+     return 0;
+ }
+ static int parse_location(HTTPContext *s, const char *p)
+ {
+     char redirected_location[MAX_URL_SIZE], *new_loc;
+     ff_make_absolute_url(redirected_location, sizeof(redirected_location),
+                          s->location, p);
+     new_loc = av_strdup(redirected_location);
+     if (!new_loc)
+         return AVERROR(ENOMEM);
+     av_free(s->location);
+     s->location = new_loc;
+     return 0;
+ }
+ /* "bytes $from-$to/$document_size" */
+ static void parse_content_range(URLContext *h, char *p)
+ {
+     HTTPContext *s = h->priv_data;
+     const char *slash;
+     if (!strncmp(p, "bytes ", 6)) {
+         p += 6;
+         s->off = strtoll(p, NULL, 10);
+         if ((slash = strchr(p, '/')) && strlen(slash) > 0)
+             s->filesize = strtoll(slash+1, NULL, 10);
+     }
 -        return AVERROR(ENOSYS);
++    if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
++        h->is_streamed = 0; /* we _can_ in fact seek */
+ }
+ static int parse_content_encoding(URLContext *h, char *p)
+ {
+     HTTPContext *s = h->priv_data;
+     if (!av_strncasecmp(p, "gzip", 4) ||
+         !av_strncasecmp(p, "deflate", 7)) {
+ #if CONFIG_ZLIB
+         s->compressed = 1;
+         inflateEnd(&s->inflate_stream);
+         if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
+             av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
+                    s->inflate_stream.msg);
+             return AVERROR(ENOSYS);
+         }
+         if (zlibCompileFlags() & (1 << 17)) {
+             av_log(h, AV_LOG_WARNING,
+                    "Your zlib was compiled without gzip support.\n");
+             return AVERROR(ENOSYS);
+         }
+ #else
+         av_log(h, AV_LOG_WARNING,
+                "Compressed (%s) content, need zlib with gzip support\n", p);
+         return AVERROR(ENOSYS);
+ #endif
+     } else if (!av_strncasecmp(p, "identity", 8)) {
+         // The normal, no-encoding case (although servers shouldn't include
+         // the header at all if this is the case).
+     } else {
+         av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
+     }
+     return 0;
+ }
  static int process_line(URLContext *h, char *line, int line_count,
                          int *new_location)
  {
              p++;
          s->http_code = strtol(p, &end, 10);
  
 -        av_dlog(NULL, "http_code=%d\n", s->http_code);
 +        av_log(h, AV_LOG_DEBUG, "http_code=%d\n", s->http_code);
  
-         /* error codes are 4xx and 5xx, but regard 401 as a success, so we
-          * don't abort until all headers have been parsed. */
-         if (s->http_code >= 400 && s->http_code < 600 &&
-             (s->http_code != 401 || s->auth_state.auth_type != HTTP_AUTH_NONE) &&
-             (s->http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
-             end += strspn(end, SPACE_CHARS);
-             av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", s->http_code, end);
-             return AVERROR(EIO);
-         }
+         if ((ret = check_http_code(h, s->http_code, end)) < 0)
+             return ret;
      } else {
          while (*p != '\0' && *p != ':')
              p++;
          } else if (!av_strcasecmp(tag, "Content-Length") && s->filesize == -1) {
              s->filesize = strtoll(p, NULL, 10);
          } else if (!av_strcasecmp(tag, "Content-Range")) {
-             /* "bytes $from-$to/$document_size" */
-             const char *slash;
-             if (!strncmp(p, "bytes ", 6)) {
-                 p += 6;
-                 s->off = strtoll(p, NULL, 10);
-                 if ((slash = strchr(p, '/')) && strlen(slash) > 0)
-                     s->filesize = strtoll(slash+1, NULL, 10);
-             }
-             if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
-                 h->is_streamed = 0; /* we _can_ in fact seek */
+             parse_content_range(h, p);
          } else if (!av_strcasecmp(tag, "Accept-Ranges") &&
 -                   !strncmp(p, "bytes", 5)) {
 +                   !strncmp(p, "bytes", 5) &&
 +                   s->seekable == -1) {
              h->is_streamed = 0;
          } else if (!av_strcasecmp(tag, "Transfer-Encoding") &&
                     !av_strncasecmp(p, "chunked", 7)) {
          } else if (!av_strcasecmp(tag, "Connection")) {
              if (!strcmp(p, "close"))
                  s->willclose = 1;
 +        } else if (!av_strcasecmp (tag, "Server")) {
 +            if (!av_strcasecmp (p, "AkamaiGHost")) {
 +                s->is_akamai = 1;
 +            } else if (!av_strncasecmp (p, "MediaGateway", 12)) {
 +                s->is_mediagateway = 1;
 +            }
 +        } else if (!av_strcasecmp (tag, "Content-Type")) {
 +            av_free(s->mime_type); s->mime_type = av_strdup(p);
 +        } else if (!av_strcasecmp (tag, "Set-Cookie")) {
 +            if (!s->cookies) {
 +                if (!(s->cookies = av_strdup(p)))
 +                    return AVERROR(ENOMEM);
 +            } else {
 +                char *tmp = s->cookies;
 +                size_t str_size = strlen(tmp) + strlen(p) + 2;
 +                if (!(s->cookies = av_malloc(str_size))) {
 +                    s->cookies = tmp;
 +                    return AVERROR(ENOMEM);
 +                }
 +                snprintf(s->cookies, str_size, "%s\n%s", tmp, p);
 +                av_free(tmp);
 +            }
 +        } else if (!av_strcasecmp (tag, "Icy-MetaInt")) {
 +            s->icy_metaint = strtoll(p, NULL, 10);
 +        } else if (!av_strncasecmp(tag, "Icy-", 4)) {
 +            // Concat all Icy- header lines
 +            char *buf = av_asprintf("%s%s: %s\n",
 +                s->icy_metadata_headers ? s->icy_metadata_headers : "", tag, p);
 +            if (!buf)
 +                return AVERROR(ENOMEM);
 +            av_freep(&s->icy_metadata_headers);
 +            s->icy_metadata_headers = buf;
          } else if (!av_strcasecmp(tag, "Content-Encoding")) {
-             if (!av_strncasecmp(p, "gzip", 4) ||
-                 !av_strncasecmp(p, "deflate", 7)) {
- #if CONFIG_ZLIB
-                 s->compressed = 1;
-                 inflateEnd(&s->inflate_stream);
-                 if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
-                     av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
-                            s->inflate_stream.msg);
-                     return AVERROR(ENOSYS);
-                 }
-                 if (zlibCompileFlags() & (1 << 17)) {
-                     av_log(h, AV_LOG_WARNING, "Your zlib was compiled without gzip support.\n");
-                     return AVERROR(ENOSYS);
-                 }
- #else
-                 av_log(h, AV_LOG_WARNING, "Compressed (%s) content, need zlib with gzip support\n", p);
-                 return AVERROR(ENOSYS);
- #endif
-             } else if (!av_strncasecmp(p, "identity", 8)) {
-                 // The normal, no-encoding case (although servers shouldn't include
-                 // the header at all if this is the case).
-             } else {
-                 av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
-             }
+             if ((ret = parse_content_encoding(h, p)) < 0)
+                 return ret;
          }
      }
      return 1;