}
}
- 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;