This is shared by both applehttp demuxer and protocol.
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
| ... | ... |
@@ -86,57 +86,6 @@ static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) |
| 86 | 86 |
return len; |
| 87 | 87 |
} |
| 88 | 88 |
|
| 89 |
-static void make_absolute_url(char *buf, int size, const char *base, |
|
| 90 |
- const char *rel) |
|
| 91 |
-{
|
|
| 92 |
- char *sep; |
|
| 93 |
- /* Absolute path, relative to the current server */ |
|
| 94 |
- if (base && strstr(base, "://") && rel[0] == '/') {
|
|
| 95 |
- if (base != buf) |
|
| 96 |
- av_strlcpy(buf, base, size); |
|
| 97 |
- sep = strstr(buf, "://"); |
|
| 98 |
- if (sep) {
|
|
| 99 |
- sep += 3; |
|
| 100 |
- sep = strchr(sep, '/'); |
|
| 101 |
- if (sep) |
|
| 102 |
- *sep = '\0'; |
|
| 103 |
- } |
|
| 104 |
- av_strlcat(buf, rel, size); |
|
| 105 |
- return; |
|
| 106 |
- } |
|
| 107 |
- /* If rel actually is an absolute url, just copy it */ |
|
| 108 |
- if (!base || strstr(rel, "://") || rel[0] == '/') {
|
|
| 109 |
- av_strlcpy(buf, rel, size); |
|
| 110 |
- return; |
|
| 111 |
- } |
|
| 112 |
- if (base != buf) |
|
| 113 |
- av_strlcpy(buf, base, size); |
|
| 114 |
- /* Remove the file name from the base url */ |
|
| 115 |
- sep = strrchr(buf, '/'); |
|
| 116 |
- if (sep) |
|
| 117 |
- sep[1] = '\0'; |
|
| 118 |
- else |
|
| 119 |
- buf[0] = '\0'; |
|
| 120 |
- while (av_strstart(rel, "../", NULL) && sep) {
|
|
| 121 |
- /* Remove the path delimiter at the end */ |
|
| 122 |
- sep[0] = '\0'; |
|
| 123 |
- sep = strrchr(buf, '/'); |
|
| 124 |
- /* If the next directory name to pop off is "..", break here */ |
|
| 125 |
- if (!strcmp(sep ? &sep[1] : buf, "..")) {
|
|
| 126 |
- /* Readd the slash we just removed */ |
|
| 127 |
- av_strlcat(buf, "/", size); |
|
| 128 |
- break; |
|
| 129 |
- } |
|
| 130 |
- /* Cut off the directory name */ |
|
| 131 |
- if (sep) |
|
| 132 |
- sep[1] = '\0'; |
|
| 133 |
- else |
|
| 134 |
- buf[0] = '\0'; |
|
| 135 |
- rel += 3; |
|
| 136 |
- } |
|
| 137 |
- av_strlcat(buf, rel, size); |
|
| 138 |
-} |
|
| 139 |
- |
|
| 140 | 89 |
static void free_segment_list(struct variant *var) |
| 141 | 90 |
{
|
| 142 | 91 |
int i; |
| ... | ... |
@@ -183,7 +132,7 @@ static struct variant *new_variant(AppleHTTPContext *c, int bandwidth, |
| 183 | 183 |
return NULL; |
| 184 | 184 |
reset_packet(&var->pkt); |
| 185 | 185 |
var->bandwidth = bandwidth; |
| 186 |
- make_absolute_url(var->url, sizeof(var->url), base, url); |
|
| 186 |
+ ff_make_absolute_url(var->url, sizeof(var->url), base, url); |
|
| 187 | 187 |
dynarray_add(&c->variants, &c->n_variants, var); |
| 188 | 188 |
return var; |
| 189 | 189 |
} |
| ... | ... |
@@ -274,7 +223,7 @@ static int parse_playlist(AppleHTTPContext *c, const char *url, |
| 274 | 274 |
goto fail; |
| 275 | 275 |
} |
| 276 | 276 |
seg->duration = duration; |
| 277 |
- make_absolute_url(seg->url, sizeof(seg->url), url, line); |
|
| 277 |
+ ff_make_absolute_url(seg->url, sizeof(seg->url), url, line); |
|
| 278 | 278 |
dynarray_add(&var->segments, &var->n_segments, seg); |
| 279 | 279 |
is_segment = 0; |
| 280 | 280 |
} |
| ... | ... |
@@ -75,57 +75,6 @@ static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) |
| 75 | 75 |
return len; |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 |
-static void make_absolute_url(char *buf, int size, const char *base, |
|
| 79 |
- const char *rel) |
|
| 80 |
-{
|
|
| 81 |
- char *sep; |
|
| 82 |
- /* Absolute path, relative to the current server */ |
|
| 83 |
- if (base && strstr(base, "://") && rel[0] == '/') {
|
|
| 84 |
- if (base != buf) |
|
| 85 |
- av_strlcpy(buf, base, size); |
|
| 86 |
- sep = strstr(buf, "://"); |
|
| 87 |
- if (sep) {
|
|
| 88 |
- sep += 3; |
|
| 89 |
- sep = strchr(sep, '/'); |
|
| 90 |
- if (sep) |
|
| 91 |
- *sep = '\0'; |
|
| 92 |
- } |
|
| 93 |
- av_strlcat(buf, rel, size); |
|
| 94 |
- return; |
|
| 95 |
- } |
|
| 96 |
- /* If rel actually is an absolute url, just copy it */ |
|
| 97 |
- if (!base || strstr(rel, "://") || rel[0] == '/') {
|
|
| 98 |
- av_strlcpy(buf, rel, size); |
|
| 99 |
- return; |
|
| 100 |
- } |
|
| 101 |
- if (base != buf) |
|
| 102 |
- av_strlcpy(buf, base, size); |
|
| 103 |
- /* Remove the file name from the base url */ |
|
| 104 |
- sep = strrchr(buf, '/'); |
|
| 105 |
- if (sep) |
|
| 106 |
- sep[1] = '\0'; |
|
| 107 |
- else |
|
| 108 |
- buf[0] = '\0'; |
|
| 109 |
- while (av_strstart(rel, "../", NULL) && sep) {
|
|
| 110 |
- /* Remove the path delimiter at the end */ |
|
| 111 |
- sep[0] = '\0'; |
|
| 112 |
- sep = strrchr(buf, '/'); |
|
| 113 |
- /* If the next directory name to pop off is "..", break here */ |
|
| 114 |
- if (!strcmp(sep ? &sep[1] : buf, "..")) {
|
|
| 115 |
- /* Readd the slash we just removed */ |
|
| 116 |
- av_strlcat(buf, "/", size); |
|
| 117 |
- break; |
|
| 118 |
- } |
|
| 119 |
- /* Cut off the directory name */ |
|
| 120 |
- if (sep) |
|
| 121 |
- sep[1] = '\0'; |
|
| 122 |
- else |
|
| 123 |
- buf[0] = '\0'; |
|
| 124 |
- rel += 3; |
|
| 125 |
- } |
|
| 126 |
- av_strlcat(buf, rel, size); |
|
| 127 |
-} |
|
| 128 |
- |
|
| 129 | 78 |
static void free_segment_list(AppleHTTPContext *s) |
| 130 | 79 |
{
|
| 131 | 80 |
int i; |
| ... | ... |
@@ -201,7 +150,7 @@ static int parse_playlist(URLContext *h, const char *url) |
| 201 | 201 |
goto fail; |
| 202 | 202 |
} |
| 203 | 203 |
seg->duration = duration; |
| 204 |
- make_absolute_url(seg->url, sizeof(seg->url), url, line); |
|
| 204 |
+ ff_make_absolute_url(seg->url, sizeof(seg->url), url, line); |
|
| 205 | 205 |
dynarray_add(&s->segments, &s->n_segments, seg); |
| 206 | 206 |
is_segment = 0; |
| 207 | 207 |
} else if (is_variant) {
|
| ... | ... |
@@ -211,7 +160,7 @@ static int parse_playlist(URLContext *h, const char *url) |
| 211 | 211 |
goto fail; |
| 212 | 212 |
} |
| 213 | 213 |
var->bandwidth = bandwidth; |
| 214 |
- make_absolute_url(var->url, sizeof(var->url), url, line); |
|
| 214 |
+ ff_make_absolute_url(var->url, sizeof(var->url), url, line); |
|
| 215 | 215 |
dynarray_add(&s->variants, &s->n_variants, var); |
| 216 | 216 |
is_variant = 0; |
| 217 | 217 |
} |
| ... | ... |
@@ -239,4 +239,15 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, |
| 239 | 239 |
*/ |
| 240 | 240 |
void ff_reduce_index(AVFormatContext *s, int stream_index); |
| 241 | 241 |
|
| 242 |
+/* |
|
| 243 |
+ * Convert a relative url into an absolute url, given a base url. |
|
| 244 |
+ * |
|
| 245 |
+ * @param buf the buffer where output absolute url is written |
|
| 246 |
+ * @param size the size of buf |
|
| 247 |
+ * @param base the base url, may be equal to buf. |
|
| 248 |
+ * @param rel the new url, which is interpreted relative to base |
|
| 249 |
+ */ |
|
| 250 |
+void ff_make_absolute_url(char *buf, int size, const char *base, |
|
| 251 |
+ const char *rel); |
|
| 252 |
+ |
|
| 242 | 253 |
#endif /* AVFORMAT_INTERNAL_H */ |
| ... | ... |
@@ -3814,3 +3814,54 @@ int ff_find_stream_index(AVFormatContext *s, int id) |
| 3814 | 3814 |
} |
| 3815 | 3815 |
return -1; |
| 3816 | 3816 |
} |
| 3817 |
+ |
|
| 3818 |
+void ff_make_absolute_url(char *buf, int size, const char *base, |
|
| 3819 |
+ const char *rel) |
|
| 3820 |
+{
|
|
| 3821 |
+ char *sep; |
|
| 3822 |
+ /* Absolute path, relative to the current server */ |
|
| 3823 |
+ if (base && strstr(base, "://") && rel[0] == '/') {
|
|
| 3824 |
+ if (base != buf) |
|
| 3825 |
+ av_strlcpy(buf, base, size); |
|
| 3826 |
+ sep = strstr(buf, "://"); |
|
| 3827 |
+ if (sep) {
|
|
| 3828 |
+ sep += 3; |
|
| 3829 |
+ sep = strchr(sep, '/'); |
|
| 3830 |
+ if (sep) |
|
| 3831 |
+ *sep = '\0'; |
|
| 3832 |
+ } |
|
| 3833 |
+ av_strlcat(buf, rel, size); |
|
| 3834 |
+ return; |
|
| 3835 |
+ } |
|
| 3836 |
+ /* If rel actually is an absolute url, just copy it */ |
|
| 3837 |
+ if (!base || strstr(rel, "://") || rel[0] == '/') {
|
|
| 3838 |
+ av_strlcpy(buf, rel, size); |
|
| 3839 |
+ return; |
|
| 3840 |
+ } |
|
| 3841 |
+ if (base != buf) |
|
| 3842 |
+ av_strlcpy(buf, base, size); |
|
| 3843 |
+ /* Remove the file name from the base url */ |
|
| 3844 |
+ sep = strrchr(buf, '/'); |
|
| 3845 |
+ if (sep) |
|
| 3846 |
+ sep[1] = '\0'; |
|
| 3847 |
+ else |
|
| 3848 |
+ buf[0] = '\0'; |
|
| 3849 |
+ while (av_strstart(rel, "../", NULL) && sep) {
|
|
| 3850 |
+ /* Remove the path delimiter at the end */ |
|
| 3851 |
+ sep[0] = '\0'; |
|
| 3852 |
+ sep = strrchr(buf, '/'); |
|
| 3853 |
+ /* If the next directory name to pop off is "..", break here */ |
|
| 3854 |
+ if (!strcmp(sep ? &sep[1] : buf, "..")) {
|
|
| 3855 |
+ /* Readd the slash we just removed */ |
|
| 3856 |
+ av_strlcat(buf, "/", size); |
|
| 3857 |
+ break; |
|
| 3858 |
+ } |
|
| 3859 |
+ /* Cut off the directory name */ |
|
| 3860 |
+ if (sep) |
|
| 3861 |
+ sep[1] = '\0'; |
|
| 3862 |
+ else |
|
| 3863 |
+ buf[0] = '\0'; |
|
| 3864 |
+ rel += 3; |
|
| 3865 |
+ } |
|
| 3866 |
+ av_strlcat(buf, rel, size); |
|
| 3867 |
+} |