+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, const 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, const 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;
+}
+
+// Concat all Icy- header lines
+static int parse_icy(HTTPContext *s, const char *tag, const char *p)
+{
+ int len = 4 + strlen(p) + strlen(tag);
+ int is_first = !s->icy_metadata_headers;
+ int ret;
+
+ if (s->icy_metadata_headers)
+ len += strlen(s->icy_metadata_headers);
+
+ if ((ret = av_reallocp(&s->icy_metadata_headers, len)) < 0)
+ return ret;
+
+ if (is_first)
+ *s->icy_metadata_headers = '\0';
+
+ av_strlcatf(s->icy_metadata_headers, len, "%s: %s\n", tag, p);
+
+ return 0;
+}
+