mirror of https://git.ffmpeg.org/ffmpeg.git
http: Refactor process_line
This commit is contained in:
parent
7a2fddb448
commit
4ff99ab3d7
|
@ -303,11 +303,89 @@ static int http_get_line(HTTPContext *s, char *line, int line_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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 AVERROR(ENOSYS);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int process_line(URLContext *h, char *line, int line_count,
|
static int process_line(URLContext *h, char *line, int line_count,
|
||||||
int *new_location)
|
int *new_location)
|
||||||
{
|
{
|
||||||
HTTPContext *s = h->priv_data;
|
HTTPContext *s = h->priv_data;
|
||||||
char *tag, *p, *end;
|
char *tag, *p, *end;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* end of header */
|
/* end of header */
|
||||||
if (line[0] == '\0') {
|
if (line[0] == '\0') {
|
||||||
|
@ -325,15 +403,8 @@ static int process_line(URLContext *h, char *line, int line_count,
|
||||||
|
|
||||||
av_dlog(NULL, "http_code=%d\n", s->http_code);
|
av_dlog(NULL, "http_code=%d\n", s->http_code);
|
||||||
|
|
||||||
/* error codes are 4xx and 5xx, but regard 401 as a success, so we
|
if ((ret = check_http_code(h, s->http_code, end)) < 0)
|
||||||
* don't abort until all headers have been parsed. */
|
return ret;
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
while (*p != '\0' && *p != ':')
|
while (*p != '\0' && *p != ':')
|
||||||
p++;
|
p++;
|
||||||
|
@ -346,27 +417,13 @@ static int process_line(URLContext *h, char *line, int line_count,
|
||||||
while (av_isspace(*p))
|
while (av_isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
if (!av_strcasecmp(tag, "Location")) {
|
if (!av_strcasecmp(tag, "Location")) {
|
||||||
char redirected_location[MAX_URL_SIZE], *new_loc;
|
if ((ret = parse_location(s, p)) < 0)
|
||||||
ff_make_absolute_url(redirected_location, sizeof(redirected_location),
|
return ret;
|
||||||
s->location, p);
|
|
||||||
new_loc = av_strdup(redirected_location);
|
|
||||||
if (!new_loc)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
av_free(s->location);
|
|
||||||
s->location = new_loc;
|
|
||||||
*new_location = 1;
|
*new_location = 1;
|
||||||
} else if (!av_strcasecmp(tag, "Content-Length") && s->filesize == -1) {
|
} else if (!av_strcasecmp(tag, "Content-Length") && s->filesize == -1) {
|
||||||
s->filesize = strtoll(p, NULL, 10);
|
s->filesize = strtoll(p, NULL, 10);
|
||||||
} else if (!av_strcasecmp(tag, "Content-Range")) {
|
} else if (!av_strcasecmp(tag, "Content-Range")) {
|
||||||
/* "bytes $from-$to/$document_size" */
|
parse_content_range(h, p);
|
||||||
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);
|
|
||||||
}
|
|
||||||
h->is_streamed = 0; /* we _can_ in fact seek */
|
|
||||||
} else if (!av_strcasecmp(tag, "Accept-Ranges") &&
|
} else if (!av_strcasecmp(tag, "Accept-Ranges") &&
|
||||||
!strncmp(p, "bytes", 5)) {
|
!strncmp(p, "bytes", 5)) {
|
||||||
h->is_streamed = 0;
|
h->is_streamed = 0;
|
||||||
|
@ -384,31 +441,8 @@ static int process_line(URLContext *h, char *line, int line_count,
|
||||||
if (!strcmp(p, "close"))
|
if (!strcmp(p, "close"))
|
||||||
s->willclose = 1;
|
s->willclose = 1;
|
||||||
} else if (!av_strcasecmp(tag, "Content-Encoding")) {
|
} else if (!av_strcasecmp(tag, "Content-Encoding")) {
|
||||||
if (!av_strncasecmp(p, "gzip", 4) ||
|
if ((ret = parse_content_encoding(h, p)) < 0)
|
||||||
!av_strncasecmp(p, "deflate", 7)) {
|
return ret;
|
||||||
#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 AVERROR(ENOSYS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue