|
| 1 | +From 471ccf6b139063fabacf243501ae0c69000bbe8e Mon Sep 17 00:00:00 2001 |
| 2 | +From: qianlongxu < [email protected]> |
| 3 | +Date: Tue, 5 Nov 2024 18:51:46 +0800 |
| 4 | +Subject: [PATCH 23] fix http open and http_seek (redirect) authentication bug |
| 5 | + |
| 6 | +--- |
| 7 | + libavformat/http.c | 25 +++++++++++++++++++++++-- |
| 8 | + 1 file changed, 23 insertions(+), 2 deletions(-) |
| 9 | + |
| 10 | +diff --git a/libavformat/http.c b/libavformat/http.c |
| 11 | +index 06f1bdd..dc0ba67 100644 |
| 12 | +--- a/libavformat/http.c |
| 13 | ++++ b/libavformat/http.c |
| 14 | +@@ -78,6 +78,7 @@ typedef struct HTTPContext { |
| 15 | + char *uri; |
| 16 | + char *location; |
| 17 | + HTTPAuthState auth_state; |
| 18 | ++ int auth_type2; |
| 19 | + HTTPAuthState proxy_auth_state; |
| 20 | + char *http_proxy; |
| 21 | + char *headers; |
| 22 | +@@ -166,6 +167,7 @@ static const AVOption options[] = { |
| 23 | + { "icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_EXPORT }, |
| 24 | + { "metadata", "metadata read from the bitstream", OFFSET(metadata), AV_OPT_TYPE_DICT, {0}, 0, 0, AV_OPT_FLAG_EXPORT }, |
| 25 | + { "auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, { .i64 = HTTP_AUTH_NONE }, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D | E, "auth_type"}, |
| 26 | ++ { "auth_type2", "backup HTTP authentication type for seek request", OFFSET(auth_type2), AV_OPT_TYPE_INT, { .i64 = HTTP_AUTH_NONE }, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D | E, "auth_type"}, |
| 27 | + { "none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_NONE }, 0, 0, D | E, "auth_type"}, |
| 28 | + { "basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_BASIC }, 0, 0, D | E, "auth_type"}, |
| 29 | + { "send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, E }, |
| 30 | +@@ -699,7 +701,10 @@ static int http_open(URLContext *h, const char *uri, int flags, |
| 31 | + HTTPContext *s = h->priv_data; |
| 32 | + int ret; |
| 33 | + s->app_ctx = (AVApplicationContext *)av_dict_strtoptr(s->app_ctx_intptr); |
| 34 | +- |
| 35 | ++ if (s->auth_type2 == HTTP_AUTH_NONE) { |
| 36 | ++ //backup the init auth_type, when not assign. |
| 37 | ++ s->auth_type2 = s->auth_state.auth_type; |
| 38 | ++ } |
| 39 | + // av_log(NULL, AV_LOG_INFO, "%-*s: %-*s = %s\n", 12, "xql http_open verify", 28, "ijkapplication", s->app_ctx_intptr); |
| 40 | + // av_log(NULL, AV_LOG_INFO, "%-*s: %-*s = %s\n", 12, "xql http_open verify", 28, "tcp_hook", s->tcp_hook); |
| 41 | + |
| 42 | +@@ -1428,6 +1433,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, |
| 43 | + uint64_t off = s->off; |
| 44 | + const char *method; |
| 45 | + int send_expect_100 = 0; |
| 46 | ++ int cur_auth_type = s->auth_state.auth_type; |
| 47 | + |
| 48 | + av_bprint_init_for_buffer(&request, s->buffer, sizeof(s->buffer)); |
| 49 | + |
| 50 | +@@ -1569,9 +1575,19 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, |
| 51 | + |
| 52 | + if (s->new_location) |
| 53 | + s->off = off; |
| 54 | +- |
| 55 | + err = (off == s->off) ? 0 : -1; |
| 56 | ++ |
| 57 | ++ //in http_seek_internal func reverted to the original uri,but the s->off is not zero,so err is -1,cause can't goto the 401 authenticate logic. |
| 58 | ++ if (err != 0 && cur_auth_type != s->auth_state.auth_type && s->http_code == 401) { |
| 59 | ++ //reverte the off,otherwise can't seek the target position. |
| 60 | ++ s->off = off; |
| 61 | ++ av_log(NULL, AV_LOG_ERROR, "http 401 error,need authenticate,s->off:%llu\n", s->buffer, s->off); |
| 62 | ++ err = 0; |
| 63 | ++ } |
| 64 | + done: |
| 65 | ++ if (err != 0) { |
| 66 | ++ av_log(NULL, AV_LOG_ERROR, "http error %s\n", s->buffer); |
| 67 | ++ } |
| 68 | + av_freep(&authstr); |
| 69 | + av_freep(&proxyauthstr); |
| 70 | + return err; |
| 71 | +@@ -1961,6 +1977,8 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo |
| 72 | + return s->off; |
| 73 | + } |
| 74 | + |
| 75 | ++ // http_seek use lasest redirect location, because after redirect, reset the auth_state: `memset(&s->auth_state, 0, sizeof(s->auth_state));` |
| 76 | ++ |
| 77 | + /* if the location changed (redirect), revert to the original uri */ |
| 78 | + if (strcmp(s->uri, s->location)) { |
| 79 | + char *new_uri; |
| 80 | +@@ -1969,6 +1987,9 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo |
| 81 | + return AVERROR(ENOMEM); |
| 82 | + av_free(s->location); |
| 83 | + s->location = new_uri; |
| 84 | ++ if (s->auth_type2 != HTTP_AUTH_NONE) { |
| 85 | ++ s->auth_state.auth_type = s->auth_type2; |
| 86 | ++ } |
| 87 | + } |
| 88 | + |
| 89 | + /* we save the old context in case the seek fails */ |
| 90 | +-- |
| 91 | +2.39.5 (Apple Git-154) |
| 92 | + |
0 commit comments