Mercurial > mplayer.hg
annotate stream/http.c @ 33307:552f1f7731c8
Set GUI initialization flag earlier.
So far, the flag is set after the call of guiInit(), but there are calls
to GUI functions (like reading the GUI config) before that. As MPlayer
(when exiting) only calls GUI's cleanup function guiDone() if the flag
is set, it neglects calling guiDone() on any error between the first GUI
function call and execution of guiInit(). Now the flag is set before the
first GUI function call.
As a result, GUI's own exit function (also used for fatal GUI errors, and
thus also for errors occurring before guiInit() properly finishes) doesn't
have to handle cleanup any longer. The code can be moved to guiDone().
author | ib |
---|---|
date | Sat, 07 May 2011 15:30:14 +0000 |
parents | 1afbc8e3ff55 |
children | 25667edae85c |
rev | line source |
---|---|
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
1 /* |
902 | 2 * HTTP Helper |
30426
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
3 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
4 * Copyright (C) 2001 Bertrand Baudet <bertrand_baudet@yahoo.com> |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
5 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
6 * This file is part of MPlayer. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
7 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
11 * (at your option) any later version. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
12 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
16 * GNU General Public License for more details. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
17 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30357
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
902 | 21 */ |
22 | |
15614
a4a46131ee71
Change header order to avoid compile error because of STREAM_SEEK
reimar
parents:
15585
diff
changeset
|
23 #include "config.h" |
a4a46131ee71
Change header order to avoid compile error because of STREAM_SEEK
reimar
parents:
15585
diff
changeset
|
24 |
870 | 25 #include <stdio.h> |
26 #include <stdlib.h> | |
27 #include <string.h> | |
15585 | 28 #include <unistd.h> |
870 | 29 |
28402 | 30 #if !HAVE_WINSOCK2_H |
27472
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
31 #else |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
32 #include <winsock2.h> |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
33 #include <ws2tcpip.h> |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
34 #endif |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
35 |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
36 #include "http.h" |
4816
f1dea39a50bb
Fixed the http response parser when the http header only has the HTTP
bertrand
parents:
4311
diff
changeset
|
37 #include "url.h" |
5915 | 38 #include "mp_msg.h" |
870 | 39 |
15585 | 40 #include "stream.h" |
19312
ab8d6b6deb63
proper inclusion of demuxer.h (including libmpdemux in Makefile only was to make previous split easier)
ben
parents:
19271
diff
changeset
|
41 #include "libmpdemux/demuxer.h" |
15585 | 42 #include "network.h" |
43 #include "help_mp.h" | |
44 | |
32585 | 45 #include "libavutil/base64.h" |
15585 | 46 |
16013 | 47 typedef struct { |
48 unsigned metaint; | |
49 unsigned metapos; | |
50 int is_ultravox; | |
51 } scast_data_t; | |
52 | |
53 /** | |
54 * \brief first read any data from sc->buffer then from fd | |
55 * \param fd file descriptor to read data from | |
56 * \param buffer buffer to read into | |
57 * \param len how many bytes to read | |
58 * \param sc streaming control containing buffer to read from first | |
59 * \return len unless there is a read error or eof | |
60 */ | |
61 static unsigned my_read(int fd, char *buffer, int len, streaming_ctrl_t *sc) { | |
62 unsigned pos = 0; | |
63 unsigned cp_len = sc->buffer_size - sc->buffer_pos; | |
64 if (cp_len > len) | |
65 cp_len = len; | |
66 memcpy(buffer, &sc->buffer[sc->buffer_pos], cp_len); | |
67 sc->buffer_pos += cp_len; | |
68 pos += cp_len; | |
69 while (pos < len) { | |
16070 | 70 int ret = recv(fd, &buffer[pos], len - pos, 0); |
16013 | 71 if (ret <= 0) |
72 break; | |
73 pos += ret; | |
74 } | |
75 return pos; | |
76 } | |
77 | |
16032 | 78 /** |
79 * \brief read and process (i.e. discard *g*) a block of ultravox metadata | |
80 * \param fd file descriptor to read from | |
81 * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd | |
82 * \return number of real data before next metadata block starts or 0 on error | |
83 */ | |
16013 | 84 static unsigned uvox_meta_read(int fd, streaming_ctrl_t *sc) { |
85 unsigned metaint; | |
16070 | 86 unsigned char info[6] = {0, 0, 0, 0, 0, 0}; |
87 int info_read; | |
16013 | 88 do { |
16070 | 89 info_read = my_read(fd, info, 1, sc); |
16013 | 90 if (info[0] == 0x00) |
16070 | 91 info_read = my_read(fd, info, 6, sc); |
16013 | 92 else |
16070 | 93 info_read += my_read(fd, &info[1], 5, sc); |
94 if (info_read != 6) // read error or eof | |
95 return 0; | |
16031
c2e78215f0d9
Ultravox improvements according to specs (didn't know they existed *g*)
reimar
parents:
16013
diff
changeset
|
96 // sync byte and reserved flags |
c2e78215f0d9
Ultravox improvements according to specs (didn't know they existed *g*)
reimar
parents:
16013
diff
changeset
|
97 if (info[0] != 0x5a || (info[1] & 0xfc) != 0x00) { |
16013 | 98 mp_msg(MSGT_DEMUXER, MSGL_ERR, "Invalid or unknown uvox metadata\n"); |
99 return 0; | |
100 } | |
16031
c2e78215f0d9
Ultravox improvements according to specs (didn't know they existed *g*)
reimar
parents:
16013
diff
changeset
|
101 if (info[1] & 0x01) |
c2e78215f0d9
Ultravox improvements according to specs (didn't know they existed *g*)
reimar
parents:
16013
diff
changeset
|
102 mp_msg(MSGT_DEMUXER, MSGL_WARN, "Encrypted ultravox data\n"); |
16013 | 103 metaint = info[4] << 8 | info[5]; |
16031
c2e78215f0d9
Ultravox improvements according to specs (didn't know they existed *g*)
reimar
parents:
16013
diff
changeset
|
104 if ((info[3] & 0xf) < 0x07) { // discard any metadata nonsense |
16013 | 105 char *metabuf = malloc(metaint); |
106 my_read(fd, metabuf, metaint, sc); | |
107 free(metabuf); | |
108 } | |
16031
c2e78215f0d9
Ultravox improvements according to specs (didn't know they existed *g*)
reimar
parents:
16013
diff
changeset
|
109 } while ((info[3] & 0xf) < 0x07); |
16013 | 110 return metaint; |
111 } | |
112 | |
113 /** | |
114 * \brief read one scast meta data entry and print it | |
16032 | 115 * \param fd file descriptor to read from |
116 * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd | |
16013 | 117 */ |
118 static void scast_meta_read(int fd, streaming_ctrl_t *sc) { | |
119 unsigned char tmp = 0; | |
120 unsigned metalen; | |
121 my_read(fd, &tmp, 1, sc); | |
122 metalen = tmp * 16; | |
123 if (metalen > 0) { | |
30938 | 124 int i; |
30941
fb3bde3ec3a8
Change type to uint8_t to avoid checks depending on char signedness.
reimar
parents:
30938
diff
changeset
|
125 uint8_t *info = malloc(metalen + 1); |
16013 | 126 unsigned nlen = my_read(fd, info, metalen, sc); |
30938 | 127 // avoid breaking the user's terminal too much |
128 if (nlen > 256) nlen = 256; | |
129 for (i = 0; i < nlen; i++) | |
130 if (info[i] && info[i] < 32) info[i] = '?'; | |
16013 | 131 info[nlen] = 0; |
132 mp_msg(MSGT_DEMUXER, MSGL_INFO, "\nICY Info: %s\n", info); | |
133 free(info); | |
134 } | |
135 } | |
136 | |
16032 | 137 /** |
138 * \brief read data from scast/ultravox stream without any metadata | |
139 * \param fd file descriptor to read from | |
140 * \param buffer buffer to read data into | |
141 * \param size number of bytes to read | |
142 * \param sc streaming_ctrl_t whose buffer is consumed before reading from fd | |
143 */ | |
16013 | 144 static int scast_streaming_read(int fd, char *buffer, int size, |
145 streaming_ctrl_t *sc) { | |
146 scast_data_t *sd = (scast_data_t *)sc->data; | |
147 unsigned block, ret; | |
148 unsigned done = 0; | |
149 | |
150 // first read remaining data up to next metadata | |
151 block = sd->metaint - sd->metapos; | |
152 if (block > size) | |
153 block = size; | |
154 ret = my_read(fd, buffer, block, sc); | |
155 sd->metapos += ret; | |
156 done += ret; | |
157 if (ret != block) // read problems or eof | |
158 size = done; | |
159 | |
160 while (done < size) { // now comes the metadata | |
161 if (sd->is_ultravox) | |
16070 | 162 { |
16013 | 163 sd->metaint = uvox_meta_read(fd, sc); |
16070 | 164 if (!sd->metaint) |
165 size = done; | |
166 } | |
16013 | 167 else |
168 scast_meta_read(fd, sc); // read and display metadata | |
169 sd->metapos = 0; | |
170 block = size - done; | |
171 if (block > sd->metaint) | |
172 block = sd->metaint; | |
173 ret = my_read(fd, &buffer[done], block, sc); | |
174 sd->metapos += ret; | |
175 done += ret; | |
176 if (ret != block) // read problems or eof | |
177 size = done; | |
178 } | |
179 return done; | |
180 } | |
181 | |
182 static int scast_streaming_start(stream_t *stream) { | |
183 int metaint; | |
184 scast_data_t *scast_data; | |
185 HTTP_header_t *http_hdr = stream->streaming_ctrl->data; | |
16070 | 186 int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0; |
16013 | 187 if (!stream || stream->fd < 0 || !http_hdr) |
188 return -1; | |
189 if (is_ultravox) | |
190 metaint = 0; | |
191 else { | |
192 metaint = atoi(http_get_field(http_hdr, "Icy-MetaInt")); | |
193 if (metaint <= 0) | |
194 return -1; | |
195 } | |
196 stream->streaming_ctrl->buffer = malloc(http_hdr->body_size); | |
197 stream->streaming_ctrl->buffer_size = http_hdr->body_size; | |
198 stream->streaming_ctrl->buffer_pos = 0; | |
199 memcpy(stream->streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size); | |
200 scast_data = malloc(sizeof(scast_data_t)); | |
201 scast_data->metaint = metaint; | |
202 scast_data->metapos = 0; | |
203 scast_data->is_ultravox = is_ultravox; | |
204 http_free(http_hdr); | |
205 stream->streaming_ctrl->data = scast_data; | |
206 stream->streaming_ctrl->streaming_read = scast_streaming_read; | |
207 stream->streaming_ctrl->streaming_seek = NULL; | |
208 stream->streaming_ctrl->prebuffer_size = 64 * 1024; // 64 KBytes | |
209 stream->streaming_ctrl->buffering = 1; | |
210 stream->streaming_ctrl->status = streaming_playing_e; | |
211 return 0; | |
212 } | |
213 | |
15585 | 214 static int nop_streaming_start( stream_t *stream ) { |
215 HTTP_header_t *http_hdr = NULL; | |
216 char *next_url=NULL; | |
217 URL_t *rd_url=NULL; | |
218 int fd,ret; | |
219 if( stream==NULL ) return -1; | |
220 | |
221 fd = stream->fd; | |
222 if( fd<0 ) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
223 fd = http_send_request( stream->streaming_ctrl->url, 0 ); |
15585 | 224 if( fd<0 ) return -1; |
225 http_hdr = http_read_response( fd ); | |
226 if( http_hdr==NULL ) return -1; | |
227 | |
228 switch( http_hdr->status_code ) { | |
229 case 200: // OK | |
230 mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") ); | |
231 mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); | |
232 if( http_hdr->body_size>0 ) { | |
233 if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { | |
234 http_free( http_hdr ); | |
235 return -1; | |
236 } | |
237 } | |
238 break; | |
239 // Redirect | |
240 case 301: // Permanently | |
241 case 302: // Temporarily | |
19459
6dad4b1efb82
Handle 303 (See Other) redirect, part of a patch by Benjamin Zores (ben at geexbox org)
reimar
parents:
19312
diff
changeset
|
242 case 303: // See Other |
32630
2653cb380532
Add support for HTTP 307 (Temporary Redirect) responses.
cboesch
parents:
32585
diff
changeset
|
243 case 307: // Temporarily (since HTTP/1.1) |
15585 | 244 ret=-1; |
245 next_url = http_get_field( http_hdr, "Location" ); | |
246 | |
247 if (next_url != NULL) | |
248 rd_url=url_new(next_url); | |
249 | |
250 if (next_url != NULL && rd_url != NULL) { | |
251 mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url); | |
252 stream->streaming_ctrl->url=check4proxies(rd_url); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
253 ret=nop_streaming_start(stream); //recursively get streaming started |
15585 | 254 } else { |
255 mp_msg(MSGT_NETWORK,MSGL_ERR,"Redirection failed\n"); | |
256 closesocket( fd ); | |
257 fd = -1; | |
258 } | |
259 return ret; | |
260 break; | |
261 case 401: //Authorization required | |
262 case 403: //Forbidden | |
263 case 404: //Not found | |
264 case 500: //Server Error | |
265 default: | |
266 mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned code %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); | |
267 closesocket( fd ); | |
268 fd = -1; | |
269 return -1; | |
270 break; | |
271 } | |
272 stream->fd = fd; | |
273 } else { | |
274 http_hdr = (HTTP_header_t*)stream->streaming_ctrl->data; | |
275 if( http_hdr->body_size>0 ) { | |
276 if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { | |
277 http_free( http_hdr ); | |
278 stream->streaming_ctrl->data = NULL; | |
279 return -1; | |
280 } | |
281 } | |
282 } | |
283 | |
284 if( http_hdr ) { | |
285 http_free( http_hdr ); | |
286 stream->streaming_ctrl->data = NULL; | |
287 } | |
288 | |
289 stream->streaming_ctrl->streaming_read = nop_streaming_read; | |
290 stream->streaming_ctrl->streaming_seek = nop_streaming_seek; | |
291 stream->streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes | |
292 stream->streaming_ctrl->buffering = 1; | |
293 stream->streaming_ctrl->status = streaming_playing_e; | |
294 return 0; | |
295 } | |
296 | |
870 | 297 HTTP_header_t * |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
16948
diff
changeset
|
298 http_new_header(void) { |
870 | 299 HTTP_header_t *http_hdr; |
300 | |
32636 | 301 http_hdr = calloc(1, sizeof(*http_hdr)); |
870 | 302 if( http_hdr==NULL ) return NULL; |
303 | |
304 return http_hdr; | |
305 } | |
306 | |
307 void | |
308 http_free( HTTP_header_t *http_hdr ) { | |
3039 | 309 HTTP_field_t *field, *field2free; |
870 | 310 if( http_hdr==NULL ) return; |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
311 free(http_hdr->protocol); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
312 free(http_hdr->uri); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
313 free(http_hdr->reason_phrase); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
314 free(http_hdr->field_search); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
315 free(http_hdr->method); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
316 free(http_hdr->buffer); |
3039 | 317 field = http_hdr->first_field; |
318 while( field!=NULL ) { | |
319 field2free = field; | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
320 free(field->field_name); |
3039 | 321 field = field->next; |
322 free( field2free ); | |
323 } | |
870 | 324 free( http_hdr ); |
3039 | 325 http_hdr = NULL; |
870 | 326 } |
327 | |
902 | 328 int |
329 http_response_append( HTTP_header_t *http_hdr, char *response, int length ) { | |
1027 | 330 if( http_hdr==NULL || response==NULL || length<0 ) return -1; |
7304
7da2c2a68547
Check if realloc failed on http_hdr->buffer instead of ptr in http_response_append,
bertrand
parents:
7293
diff
changeset
|
331 |
18558
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18094
diff
changeset
|
332 if( (unsigned)length > SIZE_MAX - http_hdr->buffer_size - 1) { |
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18094
diff
changeset
|
333 mp_msg(MSGT_NETWORK,MSGL_FATAL,"Bad size in memory (re)allocation\n"); |
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18094
diff
changeset
|
334 return -1; |
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18094
diff
changeset
|
335 } |
30702 | 336 http_hdr->buffer = realloc( http_hdr->buffer, http_hdr->buffer_size+length+1 ); |
7304
7da2c2a68547
Check if realloc failed on http_hdr->buffer instead of ptr in http_response_append,
bertrand
parents:
7293
diff
changeset
|
337 if( http_hdr->buffer==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
338 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
902 | 339 return -1; |
340 } | |
7293 | 341 memcpy( http_hdr->buffer+http_hdr->buffer_size, response, length ); |
342 http_hdr->buffer_size += length; | |
343 http_hdr->buffer[http_hdr->buffer_size]=0; // close the string! | |
902 | 344 return http_hdr->buffer_size; |
345 } | |
346 | |
347 int | |
2489
0ecc1b4f7cf8
Added ASF http server streaming (Not mms streaming).
bertrand
parents:
2310
diff
changeset
|
348 http_is_header_entire( HTTP_header_t *http_hdr ) { |
902 | 349 if( http_hdr==NULL ) return -1; |
7293 | 350 if( http_hdr->buffer==NULL ) return 0; // empty |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
351 |
3784 | 352 if( strstr(http_hdr->buffer, "\r\n\r\n")==NULL && |
353 strstr(http_hdr->buffer, "\n\n")==NULL ) return 0; | |
354 return 1; | |
902 | 355 } |
356 | |
357 int | |
358 http_response_parse( HTTP_header_t *http_hdr ) { | |
870 | 359 char *hdr_ptr, *ptr; |
360 char *field=NULL; | |
18558
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18094
diff
changeset
|
361 int pos_hdr_sep, hdr_sep_len; |
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18094
diff
changeset
|
362 size_t len; |
902 | 363 if( http_hdr==NULL ) return -1; |
364 if( http_hdr->is_parsed ) return 0; | |
870 | 365 |
366 // Get the protocol | |
902 | 367 hdr_ptr = strstr( http_hdr->buffer, " " ); |
870 | 368 if( hdr_ptr==NULL ) { |
5915 | 369 mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. No space separator found.\n"); |
902 | 370 return -1; |
870 | 371 } |
902 | 372 len = hdr_ptr-http_hdr->buffer; |
18879 | 373 http_hdr->protocol = malloc(len+1); |
870 | 374 if( http_hdr->protocol==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
375 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
902 | 376 return -1; |
870 | 377 } |
902 | 378 strncpy( http_hdr->protocol, http_hdr->buffer, len ); |
379 http_hdr->protocol[len]='\0'; | |
870 | 380 if( !strncasecmp( http_hdr->protocol, "HTTP", 4) ) { |
381 if( sscanf( http_hdr->protocol+5,"1.%d", &(http_hdr->http_minor_version) )!=1 ) { | |
5915 | 382 mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get HTTP minor version.\n"); |
902 | 383 return -1; |
870 | 384 } |
385 } | |
386 | |
387 // Get the status code | |
388 if( sscanf( ++hdr_ptr, "%d", &(http_hdr->status_code) )!=1 ) { | |
5915 | 389 mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get status code.\n"); |
902 | 390 return -1; |
870 | 391 } |
392 hdr_ptr += 4; | |
393 | |
394 // Get the reason phrase | |
3514
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
395 ptr = strstr( hdr_ptr, "\n" ); |
870 | 396 if( hdr_ptr==NULL ) { |
5915 | 397 mp_msg(MSGT_NETWORK,MSGL_ERR,"Malformed answer. Unable to get the reason phrase.\n"); |
902 | 398 return -1; |
870 | 399 } |
400 len = ptr-hdr_ptr; | |
18879 | 401 http_hdr->reason_phrase = malloc(len+1); |
870 | 402 if( http_hdr->reason_phrase==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
403 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
902 | 404 return -1; |
870 | 405 } |
406 strncpy( http_hdr->reason_phrase, hdr_ptr, len ); | |
4311 | 407 if( http_hdr->reason_phrase[len-1]=='\r' ) { |
408 len--; | |
409 } | |
870 | 410 http_hdr->reason_phrase[len]='\0'; |
411 | |
412 // Set the position of the header separator: \r\n\r\n | |
8179
63a5e03f4346
Removed hard coded value for the length of the header separator.
bertrand
parents:
7304
diff
changeset
|
413 hdr_sep_len = 4; |
902 | 414 ptr = strstr( http_hdr->buffer, "\r\n\r\n" ); |
870 | 415 if( ptr==NULL ) { |
3514
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
416 ptr = strstr( http_hdr->buffer, "\n\n" ); |
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
417 if( ptr==NULL ) { |
5915 | 418 mp_msg(MSGT_NETWORK,MSGL_ERR,"Header may be incomplete. No CRLF CRLF found.\n"); |
3514
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
419 return -1; |
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
420 } |
8179
63a5e03f4346
Removed hard coded value for the length of the header separator.
bertrand
parents:
7304
diff
changeset
|
421 hdr_sep_len = 2; |
870 | 422 } |
902 | 423 pos_hdr_sep = ptr-http_hdr->buffer; |
870 | 424 |
3514
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
425 // Point to the first line after the method line. |
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
426 hdr_ptr = strstr( http_hdr->buffer, "\n" )+1; |
870 | 427 do { |
3514
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
428 ptr = hdr_ptr; |
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
429 while( *ptr!='\r' && *ptr!='\n' ) ptr++; |
870 | 430 len = ptr-hdr_ptr; |
4816
f1dea39a50bb
Fixed the http response parser when the http header only has the HTTP
bertrand
parents:
4311
diff
changeset
|
431 if( len==0 ) break; |
30702 | 432 field = realloc(field, len+1); |
870 | 433 if( field==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
434 mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MemAllocFailed); |
902 | 435 return -1; |
870 | 436 } |
437 strncpy( field, hdr_ptr, len ); | |
438 field[len]='\0'; | |
439 http_set_field( http_hdr, field ); | |
3514
43518985def8
Handle broken server that doesn't send CRLF but jusr LF.
bertrand
parents:
3497
diff
changeset
|
440 hdr_ptr = ptr+((*ptr=='\r')?2:1); |
902 | 441 } while( hdr_ptr<(http_hdr->buffer+pos_hdr_sep) ); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
442 |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
443 free(field); |
870 | 444 |
8179
63a5e03f4346
Removed hard coded value for the length of the header separator.
bertrand
parents:
7304
diff
changeset
|
445 if( pos_hdr_sep+hdr_sep_len<http_hdr->buffer_size ) { |
870 | 446 // Response has data! |
8179
63a5e03f4346
Removed hard coded value for the length of the header separator.
bertrand
parents:
7304
diff
changeset
|
447 http_hdr->body = http_hdr->buffer+pos_hdr_sep+hdr_sep_len; |
63a5e03f4346
Removed hard coded value for the length of the header separator.
bertrand
parents:
7304
diff
changeset
|
448 http_hdr->body_size = http_hdr->buffer_size-(pos_hdr_sep+hdr_sep_len); |
870 | 449 } |
450 | |
902 | 451 http_hdr->is_parsed = 1; |
452 return 0; | |
870 | 453 } |
454 | |
455 char * | |
902 | 456 http_build_request( HTTP_header_t *http_hdr ) { |
3497 | 457 char *ptr, *uri=NULL; |
902 | 458 int len; |
3039 | 459 HTTP_field_t *field; |
870 | 460 if( http_hdr==NULL ) return NULL; |
461 | |
462 if( http_hdr->method==NULL ) http_set_method( http_hdr, "GET"); | |
463 if( http_hdr->uri==NULL ) http_set_uri( http_hdr, "/"); | |
3497 | 464 else { |
18879 | 465 uri = malloc(strlen(http_hdr->uri) + 1); |
3497 | 466 if( uri==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
467 mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MemAllocFailed); |
3497 | 468 return NULL; |
469 } | |
12391 | 470 strcpy(uri,http_hdr->uri); |
3497 | 471 } |
870 | 472 |
3497 | 473 //**** Compute the request length |
474 // Add the Method line | |
475 len = strlen(http_hdr->method)+strlen(uri)+12; | |
476 // Add the fields | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
477 field = http_hdr->first_field; |
3039 | 478 while( field!=NULL ) { |
479 len += strlen(field->field_name)+2; | |
480 field = field->next; | |
481 } | |
3497 | 482 // Add the CRLF |
483 len += 2; | |
484 // Add the body | |
902 | 485 if( http_hdr->body!=NULL ) { |
486 len += http_hdr->body_size; | |
487 } | |
3497 | 488 // Free the buffer if it was previously used |
902 | 489 if( http_hdr->buffer!=NULL ) { |
490 free( http_hdr->buffer ); | |
491 http_hdr->buffer = NULL; | |
492 } | |
18879 | 493 http_hdr->buffer = malloc(len+1); |
902 | 494 if( http_hdr->buffer==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
495 mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MemAllocFailed); |
902 | 496 return NULL; |
497 } | |
498 http_hdr->buffer_size = len; | |
499 | |
3497 | 500 //*** Building the request |
902 | 501 ptr = http_hdr->buffer; |
3497 | 502 // Add the method line |
503 ptr += sprintf( ptr, "%s %s HTTP/1.%d\r\n", http_hdr->method, uri, http_hdr->http_minor_version ); | |
3039 | 504 field = http_hdr->first_field; |
3497 | 505 // Add the field |
3039 | 506 while( field!=NULL ) { |
507 ptr += sprintf( ptr, "%s\r\n", field->field_name ); | |
508 field = field->next; | |
509 } | |
870 | 510 ptr += sprintf( ptr, "\r\n" ); |
3497 | 511 // Add the body |
870 | 512 if( http_hdr->body!=NULL ) { |
513 memcpy( ptr, http_hdr->body, http_hdr->body_size ); | |
514 } | |
3497 | 515 |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32052
diff
changeset
|
516 free(uri); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
517 return http_hdr->buffer; |
870 | 518 } |
519 | |
520 char * | |
521 http_get_field( HTTP_header_t *http_hdr, const char *field_name ) { | |
522 if( http_hdr==NULL || field_name==NULL ) return NULL; | |
3039 | 523 http_hdr->field_search_pos = http_hdr->first_field; |
30702 | 524 http_hdr->field_search = realloc( http_hdr->field_search, strlen(field_name)+1 ); |
870 | 525 if( http_hdr->field_search==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
526 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
870 | 527 return NULL; |
528 } | |
529 strcpy( http_hdr->field_search, field_name ); | |
530 return http_get_next_field( http_hdr ); | |
531 } | |
532 | |
533 char * | |
534 http_get_next_field( HTTP_header_t *http_hdr ) { | |
535 char *ptr; | |
3039 | 536 HTTP_field_t *field; |
870 | 537 if( http_hdr==NULL ) return NULL; |
538 | |
3039 | 539 field = http_hdr->field_search_pos; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
540 while( field!=NULL ) { |
3039 | 541 ptr = strstr( field->field_name, ":" ); |
870 | 542 if( ptr==NULL ) return NULL; |
3039 | 543 if( !strncasecmp( field->field_name, http_hdr->field_search, ptr-(field->field_name) ) ) { |
870 | 544 ptr++; // Skip the column |
545 while( ptr[0]==' ' ) ptr++; // Skip the spaces if there is some | |
3039 | 546 http_hdr->field_search_pos = field->next; |
870 | 547 return ptr; // return the value without the field name |
548 } | |
3039 | 549 field = field->next; |
870 | 550 } |
551 return NULL; | |
552 } | |
553 | |
554 void | |
3039 | 555 http_set_field( HTTP_header_t *http_hdr, const char *field_name ) { |
556 HTTP_field_t *new_field; | |
557 if( http_hdr==NULL || field_name==NULL ) return; | |
870 | 558 |
18879 | 559 new_field = malloc(sizeof(HTTP_field_t)); |
3039 | 560 if( new_field==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
561 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
870 | 562 return; |
563 } | |
3039 | 564 new_field->next = NULL; |
18879 | 565 new_field->field_name = malloc(strlen(field_name)+1); |
3039 | 566 if( new_field->field_name==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
567 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
27834
d35bcab9833b
Avoid a memleak if allocation of field_name fails, fixes bug #1319.
reimar
parents:
27473
diff
changeset
|
568 free(new_field); |
3039 | 569 return; |
570 } | |
571 strcpy( new_field->field_name, field_name ); | |
572 | |
573 if( http_hdr->last_field==NULL ) { | |
574 http_hdr->first_field = new_field; | |
575 } else { | |
576 http_hdr->last_field->next = new_field; | |
577 } | |
578 http_hdr->last_field = new_field; | |
870 | 579 http_hdr->field_nb++; |
580 } | |
581 | |
582 void | |
583 http_set_method( HTTP_header_t *http_hdr, const char *method ) { | |
584 if( http_hdr==NULL || method==NULL ) return; | |
585 | |
18879 | 586 http_hdr->method = malloc(strlen(method)+1); |
870 | 587 if( http_hdr->method==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
588 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
870 | 589 return; |
590 } | |
591 strcpy( http_hdr->method, method ); | |
592 } | |
593 | |
594 void | |
595 http_set_uri( HTTP_header_t *http_hdr, const char *uri ) { | |
596 if( http_hdr==NULL || uri==NULL ) return; | |
597 | |
18879 | 598 http_hdr->uri = malloc(strlen(uri)+1); |
870 | 599 if( http_hdr->uri==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
600 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
870 | 601 return; |
602 } | |
603 strcpy( http_hdr->uri, uri ); | |
604 } | |
605 | |
32547
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
606 static int |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
607 http_add_authentication( HTTP_header_t *http_hdr, const char *username, const char *password, const char *auth_str ) { |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
608 char *auth = NULL, *usr_pass = NULL, *b64_usr_pass = NULL; |
32585 | 609 int encoded_len, pass_len=0; |
610 size_t auth_len, usr_pass_len; | |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
611 int res = -1; |
6514 | 612 if( http_hdr==NULL || username==NULL ) return -1; |
613 | |
614 if( password!=NULL ) { | |
615 pass_len = strlen(password); | |
616 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
617 |
32585 | 618 usr_pass_len = strlen(username) + 1 + pass_len; |
619 usr_pass = malloc(usr_pass_len + 1); | |
6514 | 620 if( usr_pass==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
621 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
622 goto out; |
6514 | 623 } |
624 | |
625 sprintf( usr_pass, "%s:%s", username, (password==NULL)?"":password ); | |
626 | |
32585 | 627 encoded_len = AV_BASE64_SIZE(usr_pass_len); |
18879 | 628 b64_usr_pass = malloc(encoded_len); |
6514 | 629 if( b64_usr_pass==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
630 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
631 goto out; |
6514 | 632 } |
32585 | 633 av_base64_encode(b64_usr_pass, encoded_len, usr_pass, usr_pass_len); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
634 |
32547
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
635 auth_len = encoded_len + 100; |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
636 auth = malloc(auth_len); |
6514 | 637 if( auth==NULL ) { |
32515
84bdbf9e9c48
Use MSGTR_MemAllocFailed instead of hardcoded string
cboesch
parents:
32511
diff
changeset
|
638 mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
639 goto out; |
6514 | 640 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
641 |
32547
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
642 snprintf(auth, auth_len, "%s: Basic %s", auth_str, b64_usr_pass); |
6514 | 643 http_set_field( http_hdr, auth ); |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
644 res = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
645 |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
646 out: |
6514 | 647 free( usr_pass ); |
648 free( b64_usr_pass ); | |
649 free( auth ); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
650 |
18094
16f2bcd5d148
free memory on error in http_add_basic_authentication
reimar
parents:
17932
diff
changeset
|
651 return res; |
6514 | 652 } |
653 | |
32547
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
654 int |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
655 http_add_basic_authentication( HTTP_header_t *http_hdr, const char *username, const char *password ) { |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
656 return http_add_authentication(http_hdr, username, password, "Authorization"); |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
657 } |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
658 |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
659 int |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
660 http_add_basic_proxy_authentication( HTTP_header_t *http_hdr, const char *username, const char *password ) { |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
661 return http_add_authentication(http_hdr, username, password, "Proxy-Authorization"); |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
662 } |
6a629e6fdb09
Add Proxy-Authorization header to authenticate on proxies
cboesch
parents:
32515
diff
changeset
|
663 |
870 | 664 void |
665 http_debug_hdr( HTTP_header_t *http_hdr ) { | |
3039 | 666 HTTP_field_t *field; |
667 int i = 0; | |
902 | 668 if( http_hdr==NULL ) return; |
870 | 669 |
5915 | 670 mp_msg(MSGT_NETWORK,MSGL_V,"--- HTTP DEBUG HEADER --- START ---\n"); |
671 mp_msg(MSGT_NETWORK,MSGL_V,"protocol: [%s]\n", http_hdr->protocol ); | |
672 mp_msg(MSGT_NETWORK,MSGL_V,"http minor version: [%d]\n", http_hdr->http_minor_version ); | |
673 mp_msg(MSGT_NETWORK,MSGL_V,"uri: [%s]\n", http_hdr->uri ); | |
674 mp_msg(MSGT_NETWORK,MSGL_V,"method: [%s]\n", http_hdr->method ); | |
675 mp_msg(MSGT_NETWORK,MSGL_V,"status code: [%d]\n", http_hdr->status_code ); | |
676 mp_msg(MSGT_NETWORK,MSGL_V,"reason phrase: [%s]\n", http_hdr->reason_phrase ); | |
31854
c680009d6779
Add 'z' length modifier to %d printf format specifier for size_t argument.
diego
parents:
31427
diff
changeset
|
677 mp_msg(MSGT_NETWORK,MSGL_V,"body size: [%zd]\n", http_hdr->body_size ); |
870 | 678 |
5915 | 679 mp_msg(MSGT_NETWORK,MSGL_V,"Fields:\n"); |
3039 | 680 field = http_hdr->first_field; |
681 while( field!=NULL ) { | |
5915 | 682 mp_msg(MSGT_NETWORK,MSGL_V," %d - %s\n", i++, field->field_name ); |
3039 | 683 field = field->next; |
684 } | |
5915 | 685 mp_msg(MSGT_NETWORK,MSGL_V,"--- HTTP DEBUG HEADER --- END ---\n"); |
870 | 686 } |
6514 | 687 |
25970
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
688 static void print_icy_metadata(HTTP_header_t *http_hdr) { |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
689 const char *field_data; |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
690 // note: I skip icy-notice1 and 2, as they contain html <BR> |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
691 // and are IMHO useless info ::atmos |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
692 if( (field_data = http_get_field(http_hdr, "icy-name")) != NULL ) |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
693 mp_msg(MSGT_NETWORK,MSGL_INFO,"Name : %s\n", field_data); |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
694 if( (field_data = http_get_field(http_hdr, "icy-genre")) != NULL ) |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
695 mp_msg(MSGT_NETWORK,MSGL_INFO,"Genre : %s\n", field_data); |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
696 if( (field_data = http_get_field(http_hdr, "icy-url")) != NULL ) |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
697 mp_msg(MSGT_NETWORK,MSGL_INFO,"Website: %s\n", field_data); |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
698 // XXX: does this really mean public server? ::atmos |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
699 if( (field_data = http_get_field(http_hdr, "icy-pub")) != NULL ) |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
700 mp_msg(MSGT_NETWORK,MSGL_INFO,"Public : %s\n", atoi(field_data)?"yes":"no"); |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
701 if( (field_data = http_get_field(http_hdr, "icy-br")) != NULL ) |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
702 mp_msg(MSGT_NETWORK,MSGL_INFO,"Bitrate: %skbit/s\n", field_data); |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
703 } |
c6ec51cc3b13
Move printing of Icy-Metadata into an extra function
reimar
parents:
25969
diff
changeset
|
704 |
21567 | 705 //! If this function succeeds you must closesocket stream->fd |
15585 | 706 static int http_streaming_start(stream_t *stream, int* file_format) { |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
707 HTTP_header_t *http_hdr = NULL; |
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
708 int fd = stream->fd; |
25135
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
709 int res = STREAM_UNSUPPORTED; |
15585 | 710 int redirect = 0; |
711 int auth_retry=0; | |
712 int seekable=0; | |
713 char *content_type; | |
30357
3fdf04500df2
Handle Content-Length also when Content-Type is not set.
reimar
parents:
30356
diff
changeset
|
714 const char *content_length; |
15585 | 715 char *next_url; |
716 URL_t *url = stream->streaming_ctrl->url; | |
6514 | 717 |
15585 | 718 do |
719 { | |
21541
3b4ed8857b38
Fix potential endless loop in http_streaming_start due
reimar
parents:
21540
diff
changeset
|
720 redirect = 0; |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
721 if (fd > 0) closesocket(fd); |
15585 | 722 fd = http_send_request( url, 0 ); |
723 if( fd<0 ) { | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
724 goto err_out; |
15585 | 725 } |
726 | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
727 http_free(http_hdr); |
15585 | 728 http_hdr = http_read_response( fd ); |
729 if( http_hdr==NULL ) { | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
730 goto err_out; |
15585 | 731 } |
732 | |
17932 | 733 if( mp_msg_test(MSGT_NETWORK,MSGL_V) ) { |
15585 | 734 http_debug_hdr( http_hdr ); |
735 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
736 |
15585 | 737 // Check if we can make partial content requests and thus seek in http-streams |
738 if( http_hdr!=NULL && http_hdr->status_code==200 ) { | |
30106 | 739 const char *accept_ranges = http_get_field(http_hdr,"Accept-Ranges"); |
30105
31b7d4637b50
Fix crash if http reply contains neither "Accept-Ranges" nor "Server" fields.
reimar
parents:
30103
diff
changeset
|
740 const char *server = http_get_field(http_hdr, "Server"); |
30106 | 741 if (accept_ranges) |
15585 | 742 seekable = strncmp(accept_ranges,"bytes",5)==0; |
32720
1afbc8e3ff55
100l, fix hack to check for MakeMKV server being inverted.
reimar
parents:
32698
diff
changeset
|
743 else if (server && (strcmp(server, "gvs 1.0") == 0 || |
1afbc8e3ff55
100l, fix hack to check for MakeMKV server being inverted.
reimar
parents:
32698
diff
changeset
|
744 strncmp(server, "MakeMKV", 7) == 0)) { |
32698
b171c744cd06
Add MakeMKV to list of webservers always supporting ranges even when they
reimar
parents:
32636
diff
changeset
|
745 // HACK for youtube and MakeMKV incorrectly claiming not to support seeking |
b171c744cd06
Add MakeMKV to list of webservers always supporting ranges even when they
reimar
parents:
32636
diff
changeset
|
746 mp_msg(MSGT_NETWORK, MSGL_WARN, "Broken webserver, incorrectly claims to not support Accept-Ranges\n"); |
b171c744cd06
Add MakeMKV to list of webservers always supporting ranges even when they
reimar
parents:
32636
diff
changeset
|
747 seekable = 1; |
b171c744cd06
Add MakeMKV to list of webservers always supporting ranges even when they
reimar
parents:
32636
diff
changeset
|
748 } |
15585 | 749 } |
750 | |
25971
64b1e4ea04fc
Always display Icy-Metadata if available, whether we recognize an ICY-Server
reimar
parents:
25970
diff
changeset
|
751 print_icy_metadata(http_hdr); |
64b1e4ea04fc
Always display Icy-Metadata if available, whether we recognize an ICY-Server
reimar
parents:
25970
diff
changeset
|
752 |
15585 | 753 // Check if the response is an ICY status_code reason_phrase |
25968
c7f41f9e2eb8
Detect IceCast also by Icy-MetaInt header part in http_streaming_start(),
reimar
parents:
25246
diff
changeset
|
754 if( !strcasecmp(http_hdr->protocol, "ICY") || |
c7f41f9e2eb8
Detect IceCast also by Icy-MetaInt header part in http_streaming_start(),
reimar
parents:
25246
diff
changeset
|
755 http_get_field(http_hdr, "Icy-MetaInt") ) { |
15585 | 756 switch( http_hdr->status_code ) { |
757 case 200: { // OK | |
25969 | 758 char *field_data; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
759 // If content-type == video/nsv we most likely have a winamp video stream |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
760 // otherwise it should be mp3. if there are more types consider adding mime type |
15585 | 761 // handling like later |
762 if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "video/nsv") || !strcmp(field_data, "misc/ultravox"))) | |
763 *file_format = DEMUXER_TYPE_NSV; | |
16948
9b7925705f5b
Add another content-type for aac audio in shoutcast streams
rtognimp
parents:
16932
diff
changeset
|
764 else if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "audio/aacp") || !strcmp(field_data, "audio/aac"))) |
16917
c45409728a9d
Use correct demuxer type for aac in shoutcast streams
rtognimp
parents:
16614
diff
changeset
|
765 *file_format = DEMUXER_TYPE_AAC; |
15585 | 766 else |
767 *file_format = DEMUXER_TYPE_AUDIO; | |
25135
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
768 res = STREAM_ERROR; |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
769 goto out; |
15585 | 770 } |
771 case 400: // Server Full | |
772 mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server is full, skipping!\n"); | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
773 goto err_out; |
15585 | 774 case 401: // Service Unavailable |
775 mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return service unavailable, skipping!\n"); | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
776 goto err_out; |
15585 | 777 case 403: // Service Forbidden |
778 mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return 'Service Forbidden'\n"); | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
779 goto err_out; |
15585 | 780 case 404: // Resource Not Found |
781 mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server couldn't find requested stream, skipping!\n"); | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
782 goto err_out; |
15585 | 783 default: |
784 mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: unhandled ICY-Errorcode, contact MPlayer developers!\n"); | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
785 goto err_out; |
15585 | 786 } |
787 } | |
788 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
789 // Assume standard http if not ICY |
15585 | 790 switch( http_hdr->status_code ) { |
791 case 200: // OK | |
30357
3fdf04500df2
Handle Content-Length also when Content-Type is not set.
reimar
parents:
30356
diff
changeset
|
792 content_length = http_get_field(http_hdr, "Content-Length"); |
3fdf04500df2
Handle Content-Length also when Content-Type is not set.
reimar
parents:
30356
diff
changeset
|
793 if (content_length) { |
3fdf04500df2
Handle Content-Length also when Content-Type is not set.
reimar
parents:
30356
diff
changeset
|
794 mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", content_length); |
3fdf04500df2
Handle Content-Length also when Content-Type is not set.
reimar
parents:
30356
diff
changeset
|
795 stream->end_pos = atoll(content_length); |
3fdf04500df2
Handle Content-Length also when Content-Type is not set.
reimar
parents:
30356
diff
changeset
|
796 } |
15585 | 797 // Look if we can use the Content-Type |
798 content_type = http_get_field( http_hdr, "Content-Type" ); | |
799 if( content_type!=NULL ) { | |
32557 | 800 unsigned int i; |
801 | |
15585 | 802 mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", content_type ); |
803 // Check in the mime type table for a demuxer type | |
32557 | 804 for (i = 0; mime_type_table[i].mime_type != NULL; i++) { |
15585 | 805 if( !strcasecmp( content_type, mime_type_table[i].mime_type ) ) { |
806 *file_format = mime_type_table[i].demuxer_type; | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
807 res = seekable; |
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
808 goto out; |
15585 | 809 } |
810 } | |
811 } | |
812 // Not found in the mime type table, don't fail, | |
813 // we should try raw HTTP | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
814 res = seekable; |
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
815 goto out; |
15585 | 816 // Redirect |
817 case 301: // Permanently | |
818 case 302: // Temporarily | |
19459
6dad4b1efb82
Handle 303 (See Other) redirect, part of a patch by Benjamin Zores (ben at geexbox org)
reimar
parents:
19312
diff
changeset
|
819 case 303: // See Other |
32630
2653cb380532
Add support for HTTP 307 (Temporary Redirect) responses.
cboesch
parents:
32585
diff
changeset
|
820 case 307: // Temporarily (since HTTP/1.1) |
15585 | 821 // TODO: RFC 2616, recommand to detect infinite redirection loops |
822 next_url = http_get_field( http_hdr, "Location" ); | |
823 if( next_url!=NULL ) { | |
25238
f42b8e689416
Preserve unsv:// protocol specifier over http redirects.
reimar
parents:
25211
diff
changeset
|
824 int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0; |
20784
720206eef78b
Support URL redirections that do not specify full URL.
reimar
parents:
20185
diff
changeset
|
825 stream->streaming_ctrl->url = url_redirect( &url, next_url ); |
25135
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
826 if (!strcasecmp(url->protocol, "mms")) { |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
827 res = STREAM_REDIRECTED; |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
828 goto err_out; |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
829 } |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
830 if (strcasecmp(url->protocol, "http")) { |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
831 mp_msg(MSGT_NETWORK,MSGL_ERR,"Unsupported http %d redirect to %s protocol\n", http_hdr->status_code, url->protocol); |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
832 goto err_out; |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
833 } |
25238
f42b8e689416
Preserve unsv:// protocol specifier over http redirects.
reimar
parents:
25211
diff
changeset
|
834 if (is_ultravox) { |
f42b8e689416
Preserve unsv:// protocol specifier over http redirects.
reimar
parents:
25211
diff
changeset
|
835 free(url->protocol); |
f42b8e689416
Preserve unsv:// protocol specifier over http redirects.
reimar
parents:
25211
diff
changeset
|
836 url->protocol = strdup("unsv"); |
f42b8e689416
Preserve unsv:// protocol specifier over http redirects.
reimar
parents:
25211
diff
changeset
|
837 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
838 redirect = 1; |
15585 | 839 } |
840 break; | |
841 case 401: // Authentication required | |
21566
79d969f9eec0
STREAM_UNSUPPORTED is -1, so use the former for return value in all places.
reimar
parents:
21565
diff
changeset
|
842 if( http_authenticate(http_hdr, url, &auth_retry)<0 ) |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
843 goto err_out; |
15585 | 844 redirect = 1; |
845 break; | |
846 default: | |
847 mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
848 goto err_out; |
15585 | 849 } |
850 } while( redirect ); | |
851 | |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
852 err_out: |
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
853 if (fd > 0) closesocket( fd ); |
21565
546cf4a6377a
Make sure stream->fd is set correct (esp. to -1 on error when fd is closed)
reimar
parents:
21542
diff
changeset
|
854 fd = -1; |
21542 | 855 http_free( http_hdr ); |
21776 | 856 http_hdr = NULL; |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
857 out: |
21776 | 858 stream->streaming_ctrl->data = (void*)http_hdr; |
21565
546cf4a6377a
Make sure stream->fd is set correct (esp. to -1 on error when fd is closed)
reimar
parents:
21542
diff
changeset
|
859 stream->fd = fd; |
21540
147c1c305f21
Fix lots and lots of potential memory/fd leaks in http_streaming_start
reimar
parents:
20784
diff
changeset
|
860 return res; |
15585 | 861 } |
862 | |
863 static int fixup_open(stream_t *stream,int seekable) { | |
16013 | 864 HTTP_header_t *http_hdr = stream->streaming_ctrl->data; |
16078
095e980cf7c0
Some ICY servers (e.g. http://broadcast.spnet.net:8000/darikhigh) do not set
reimar
parents:
16070
diff
changeset
|
865 int is_icy = http_hdr && http_get_field(http_hdr, "Icy-MetaInt"); |
16070 | 866 int is_ultravox = strcasecmp(stream->streaming_ctrl->url->protocol, "unsv") == 0; |
15585 | 867 |
868 stream->type = STREAMTYPE_STREAM; | |
16013 | 869 if(!is_icy && !is_ultravox && seekable) |
15585 | 870 { |
29920
4f740437ed2b
Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many
reimar
parents:
29263
diff
changeset
|
871 stream->flags |= MP_STREAM_SEEK; |
15585 | 872 stream->seek = http_seek; |
873 } | |
874 stream->streaming_ctrl->bandwidth = network_bandwidth; | |
16013 | 875 if ((!is_icy && !is_ultravox) || scast_streaming_start(stream)) |
15585 | 876 if(nop_streaming_start( stream )) { |
877 mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n"); | |
21567 | 878 if (stream->fd >= 0) |
879 closesocket(stream->fd); | |
880 stream->fd = -1; | |
15585 | 881 streaming_ctrl_free(stream->streaming_ctrl); |
882 stream->streaming_ctrl = NULL; | |
24257 | 883 return STREAM_UNSUPPORTED; |
15585 | 884 } |
885 | |
886 fixup_network_stream_cache(stream); | |
887 return STREAM_OK; | |
888 } | |
889 | |
890 static int open_s1(stream_t *stream,int mode, void* opts, int* file_format) { | |
891 int seekable=0; | |
892 URL_t *url; | |
893 | |
894 stream->streaming_ctrl = streaming_ctrl_new(); | |
895 if( stream->streaming_ctrl==NULL ) { | |
896 return STREAM_ERROR; | |
897 } | |
898 stream->streaming_ctrl->bandwidth = network_bandwidth; | |
899 url = url_new(stream->url); | |
900 stream->streaming_ctrl->url = check4proxies(url); | |
16417 | 901 url_free(url); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
902 |
20185 | 903 mp_msg(MSGT_OPEN, MSGL_V, "STREAM_HTTP(1), URL: %s\n", stream->url); |
15585 | 904 seekable = http_streaming_start(stream, file_format); |
905 if((seekable < 0) || (*file_format == DEMUXER_TYPE_ASF)) { | |
21567 | 906 if (stream->fd >= 0) |
907 closesocket(stream->fd); | |
908 stream->fd = -1; | |
25135
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
909 if (seekable == STREAM_REDIRECTED) |
66f628d13442
Support stream redirection from http to mms, fix bug #927.
ulion
parents:
24257
diff
changeset
|
910 return seekable; |
15585 | 911 streaming_ctrl_free(stream->streaming_ctrl); |
912 stream->streaming_ctrl = NULL; | |
24257 | 913 return STREAM_UNSUPPORTED; |
15585 | 914 } |
915 | |
916 return fixup_open(stream, seekable); | |
917 } | |
918 | |
919 static int open_s2(stream_t *stream,int mode, void* opts, int* file_format) { | |
920 int seekable=0; | |
921 URL_t *url; | |
922 | |
923 stream->streaming_ctrl = streaming_ctrl_new(); | |
924 if( stream->streaming_ctrl==NULL ) { | |
925 return STREAM_ERROR; | |
926 } | |
927 stream->streaming_ctrl->bandwidth = network_bandwidth; | |
928 url = url_new(stream->url); | |
929 stream->streaming_ctrl->url = check4proxies(url); | |
16614 | 930 url_free(url); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
931 |
20185 | 932 mp_msg(MSGT_OPEN, MSGL_V, "STREAM_HTTP(2), URL: %s\n", stream->url); |
15585 | 933 seekable = http_streaming_start(stream, file_format); |
934 if(seekable < 0) { | |
21567 | 935 if (stream->fd >= 0) |
936 closesocket(stream->fd); | |
937 stream->fd = -1; | |
15585 | 938 streaming_ctrl_free(stream->streaming_ctrl); |
939 stream->streaming_ctrl = NULL; | |
24257 | 940 return STREAM_UNSUPPORTED; |
15585 | 941 } |
942 | |
943 return fixup_open(stream, seekable); | |
944 } | |
945 | |
946 | |
25211 | 947 const stream_info_t stream_info_http1 = { |
15585 | 948 "http streaming", |
949 "null", | |
950 "Bertrand, Albeau, Reimar Doeffinger, Arpi?", | |
951 "plain http", | |
952 open_s1, | |
27847
28deb37052cd
Add a noicyx:// protocol to allow easier testing for misconfigured servers.
reimar
parents:
27834
diff
changeset
|
953 {"http", "http_proxy", "unsv", "icyx", "noicyx", NULL}, |
15585 | 954 NULL, |
955 0 // Urls are an option string | |
956 }; | |
957 | |
25211 | 958 const stream_info_t stream_info_http2 = { |
15585 | 959 "http streaming", |
960 "null", | |
961 "Bertrand, Albeu, Arpi? who?", | |
16932
c30e0970250c
fix typos: aslo->also, falback->fallback (they were just too annoying *g*)
reimar
parents:
16917
diff
changeset
|
962 "plain http, also used as fallback for many other protocols", |
15585 | 963 open_s2, |
964 {"http", "http_proxy", "pnm", "mms", "mmsu", "mmst", "rtsp", NULL}, //all the others as fallback | |
965 NULL, | |
966 0 // Urls are an option string | |
967 }; |