Imported Debian version 2.5.0~trusty1.1
[deb_ffmpeg.git] / ffmpeg / libavformat / http.c
index 018d25c9d73f4338bf4bc1d99a4de7a6fea29913..d9de05c968c58172f6e9ddfede4449e695a89a89 100644 (file)
@@ -207,6 +207,8 @@ static int http_open_cnx(URLContext *h, AVDictionary **options)
     HTTPContext *s = h->priv_data;
     int location_changed, attempts = 0, redirects = 0;
 redo:
+    av_dict_copy(options, s->chained_options, 0);
+
     cur_auth_type       = s->auth_state.auth_type;
     cur_proxy_auth_type = s->auth_state.auth_type;
 
@@ -250,7 +252,9 @@ redo:
 fail:
     if (s->hd)
         ffurl_closep(&s->hd);
-    return AVERROR(EIO);
+    if (location_changed < 0)
+        return location_changed;
+    return ff_http_averror(s->http_code, AVERROR(EIO));
 }
 
 int ff_http_do_new_request(URLContext *h, const char *uri)
@@ -266,12 +270,28 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
     if (!s->location)
         return AVERROR(ENOMEM);
 
-    av_dict_copy(&options, s->chained_options, 0);
     ret = http_open_cnx(h, &options);
     av_dict_free(&options);
     return ret;
 }
 
+int ff_http_averror(int status_code, int default_averror)
+{
+    switch (status_code) {
+        case 400: return AVERROR_HTTP_BAD_REQUEST;
+        case 401: return AVERROR_HTTP_UNAUTHORIZED;
+        case 403: return AVERROR_HTTP_FORBIDDEN;
+        case 404: return AVERROR_HTTP_NOT_FOUND;
+        default: break;
+    }
+    if (status_code >= 400 && status_code <= 499)
+        return AVERROR_HTTP_OTHER_4XX;
+    else if (status_code >= 500)
+        return AVERROR_HTTP_SERVER_ERROR;
+    else
+        return default_averror;
+}
+
 static int http_open(URLContext *h, const char *uri, int flags,
                      AVDictionary **options)
 {
@@ -354,7 +374,7 @@ static int check_http_code(URLContext *h, int http_code, const char *end)
         (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 ff_http_averror(http_code, AVERROR(EIO));
     }
     return 0;
 }
@@ -1117,7 +1137,6 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
     s->hd = NULL;
 
     /* if it fails, continue on old connection */
-    av_dict_copy(&options, s->chained_options, 0);
     if ((ret = http_open_cnx(h, &options)) < 0) {
         av_dict_free(&options);
         memcpy(s->buffer, old_buf, old_buf_size);
@@ -1267,7 +1286,7 @@ redo:
 
     if (s->http_code < 400)
         return 0;
-    ret = AVERROR(EIO);
+    ret = ff_http_averror(s->http_code, AVERROR(EIO));
 
 fail:
     http_proxy_close(h);