Add APIchanges entry for the av_metadata_copy() addition.
[ffmpeg:ffmpeg-mt.git] / ffserver.c
1 /*
2  * Multiple format streaming server
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #define _XOPEN_SOURCE 600
23
24 #include "config.h"
25 #if !HAVE_CLOSESOCKET
26 #define closesocket close
27 #endif
28 #include <string.h>
29 #include <strings.h>
30 #include <stdlib.h>
31 #include "libavformat/avformat.h"
32 #include "libavformat/network.h"
33 #include "libavformat/os_support.h"
34 #include "libavformat/rtpdec.h"
35 #include "libavformat/rtsp.h"
36 #include "libavutil/avstring.h"
37 #include "libavutil/lfg.h"
38 #include "libavutil/random_seed.h"
39 #include "libavcore/parseutils.h"
40 #include "libavcodec/opt.h"
41 #include <stdarg.h>
42 #include <unistd.h>
43 #include <fcntl.h>
44 #include <sys/ioctl.h>
45 #if HAVE_POLL_H
46 #include <poll.h>
47 #endif
48 #include <errno.h>
49 #include <sys/time.h>
50 #include <time.h>
51 #include <sys/wait.h>
52 #include <signal.h>
53 #if HAVE_DLFCN_H
54 #include <dlfcn.h>
55 #endif
56
57 #include "cmdutils.h"
58
59 const char program_name[] = "FFserver";
60 const int program_birth_year = 2000;
61
62 static const OptionDef options[];
63
64 enum HTTPState {
65     HTTPSTATE_WAIT_REQUEST,
66     HTTPSTATE_SEND_HEADER,
67     HTTPSTATE_SEND_DATA_HEADER,
68     HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
69     HTTPSTATE_SEND_DATA_TRAILER,
70     HTTPSTATE_RECEIVE_DATA,
71     HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
72     HTTPSTATE_READY,
73
74     RTSPSTATE_WAIT_REQUEST,
75     RTSPSTATE_SEND_REPLY,
76     RTSPSTATE_SEND_PACKET,
77 };
78
79 static const char *http_state[] = {
80     "HTTP_WAIT_REQUEST",
81     "HTTP_SEND_HEADER",
82
83     "SEND_DATA_HEADER",
84     "SEND_DATA",
85     "SEND_DATA_TRAILER",
86     "RECEIVE_DATA",
87     "WAIT_FEED",
88     "READY",
89
90     "RTSP_WAIT_REQUEST",
91     "RTSP_SEND_REPLY",
92     "RTSP_SEND_PACKET",
93 };
94
95 #if !FF_API_MAX_STREAMS
96 #define MAX_STREAMS 20
97 #endif
98
99 #define IOBUFFER_INIT_SIZE 8192
100
101 /* timeouts are in ms */
102 #define HTTP_REQUEST_TIMEOUT (15 * 1000)
103 #define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
104
105 #define SYNC_TIMEOUT (10 * 1000)
106
107 typedef struct RTSPActionServerSetup {
108     uint32_t ipaddr;
109     char transport_option[512];
110 } RTSPActionServerSetup;
111
112 typedef struct {
113     int64_t count1, count2;
114     int64_t time1, time2;
115 } DataRateData;
116
117 /* context associated with one connection */
118 typedef struct HTTPContext {
119     enum HTTPState state;
120     int fd; /* socket file descriptor */
121     struct sockaddr_in from_addr; /* origin */
122     struct pollfd *poll_entry; /* used when polling */
123     int64_t timeout;
124     uint8_t *buffer_ptr, *buffer_end;
125     int http_error;
126     int post;
127     int chunked_encoding;
128     int chunk_size;               /* 0 if it needs to be read */
129     struct HTTPContext *next;
130     int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
131     int64_t data_count;
132     /* feed input */
133     int feed_fd;
134     /* input format handling */
135     AVFormatContext *fmt_in;
136     int64_t start_time;            /* In milliseconds - this wraps fairly often */
137     int64_t first_pts;            /* initial pts value */
138     int64_t cur_pts;             /* current pts value from the stream in us */
139     int64_t cur_frame_duration;  /* duration of the current frame in us */
140     int cur_frame_bytes;       /* output frame size, needed to compute
141                                   the time at which we send each
142                                   packet */
143     int pts_stream_index;        /* stream we choose as clock reference */
144     int64_t cur_clock;           /* current clock reference value in us */
145     /* output format handling */
146     struct FFStream *stream;
147     /* -1 is invalid stream */
148     int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
149     int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
150     int switch_pending;
151     AVFormatContext fmt_ctx; /* instance of FFStream for one user */
152     int last_packet_sent; /* true if last data packet was sent */
153     int suppress_log;
154     DataRateData datarate;
155     int wmp_client_id;
156     char protocol[16];
157     char method[16];
158     char url[128];
159     int buffer_size;
160     uint8_t *buffer;
161     int is_packetized; /* if true, the stream is packetized */
162     int packet_stream_index; /* current stream for output in state machine */
163
164     /* RTSP state specific */
165     uint8_t *pb_buffer; /* XXX: use that in all the code */
166     ByteIOContext *pb;
167     int seq; /* RTSP sequence number */
168
169     /* RTP state specific */
170     enum RTSPLowerTransport rtp_protocol;
171     char session_id[32]; /* session id */
172     AVFormatContext *rtp_ctx[MAX_STREAMS];
173
174     /* RTP/UDP specific */
175     URLContext *rtp_handles[MAX_STREAMS];
176
177     /* RTP/TCP specific */
178     struct HTTPContext *rtsp_c;
179     uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
180 } HTTPContext;
181
182 /* each generated stream is described here */
183 enum StreamType {
184     STREAM_TYPE_LIVE,
185     STREAM_TYPE_STATUS,
186     STREAM_TYPE_REDIRECT,
187 };
188
189 enum IPAddressAction {
190     IP_ALLOW = 1,
191     IP_DENY,
192 };
193
194 typedef struct IPAddressACL {
195     struct IPAddressACL *next;
196     enum IPAddressAction action;
197     /* These are in host order */
198     struct in_addr first;
199     struct in_addr last;
200 } IPAddressACL;
201
202 /* description of each stream of the ffserver.conf file */
203 typedef struct FFStream {
204     enum StreamType stream_type;
205     char filename[1024];     /* stream filename */
206     struct FFStream *feed;   /* feed we are using (can be null if
207                                 coming from file) */
208     AVFormatParameters *ap_in; /* input parameters */
209     AVInputFormat *ifmt;       /* if non NULL, force input format */
210     AVOutputFormat *fmt;
211     IPAddressACL *acl;
212     char dynamic_acl[1024];
213     int nb_streams;
214     int prebuffer;      /* Number of millseconds early to start */
215     int64_t max_time;      /* Number of milliseconds to run */
216     int send_on_key;
217     AVStream *streams[MAX_STREAMS];
218     int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
219     char feed_filename[1024]; /* file name of the feed storage, or
220                                  input file name for a stream */
221     char author[512];
222     char title[512];
223     char copyright[512];
224     char comment[512];
225     pid_t pid;  /* Of ffmpeg process */
226     time_t pid_start;  /* Of ffmpeg process */
227     char **child_argv;
228     struct FFStream *next;
229     unsigned bandwidth; /* bandwidth, in kbits/s */
230     /* RTSP options */
231     char *rtsp_option;
232     /* multicast specific */
233     int is_multicast;
234     struct in_addr multicast_ip;
235     int multicast_port; /* first port used for multicast */
236     int multicast_ttl;
237     int loop; /* if true, send the stream in loops (only meaningful if file) */
238
239     /* feed specific */
240     int feed_opened;     /* true if someone is writing to the feed */
241     int is_feed;         /* true if it is a feed */
242     int readonly;        /* True if writing is prohibited to the file */
243     int truncate;        /* True if feeder connection truncate the feed file */
244     int conns_served;
245     int64_t bytes_served;
246     int64_t feed_max_size;      /* maximum storage size, zero means unlimited */
247     int64_t feed_write_index;   /* current write position in feed (it wraps around) */
248     int64_t feed_size;          /* current size of feed */
249     struct FFStream *next_feed;
250 } FFStream;
251
252 typedef struct FeedData {
253     long long data_count;
254     float avg_frame_size;   /* frame size averaged over last frames with exponential mean */
255 } FeedData;
256
257 static struct sockaddr_in my_http_addr;
258 static struct sockaddr_in my_rtsp_addr;
259
260 static char logfilename[1024];
261 static HTTPContext *first_http_ctx;
262 static FFStream *first_feed;   /* contains only feeds */
263 static FFStream *first_stream; /* contains all streams, including feeds */
264
265 static void new_connection(int server_fd, int is_rtsp);
266 static void close_connection(HTTPContext *c);
267
268 /* HTTP handling */
269 static int handle_connection(HTTPContext *c);
270 static int http_parse_request(HTTPContext *c);
271 static int http_send_data(HTTPContext *c);
272 static void compute_status(HTTPContext *c);
273 static int open_input_stream(HTTPContext *c, const char *info);
274 static int http_start_receive_data(HTTPContext *c);
275 static int http_receive_data(HTTPContext *c);
276
277 /* RTSP handling */
278 static int rtsp_parse_request(HTTPContext *c);
279 static void rtsp_cmd_describe(HTTPContext *c, const char *url);
280 static void rtsp_cmd_options(HTTPContext *c, const char *url);
281 static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
282 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
283 static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
284 static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
285
286 /* SDP handling */
287 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
288                                    struct in_addr my_ip);
289
290 /* RTP handling */
291 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
292                                        FFStream *stream, const char *session_id,
293                                        enum RTSPLowerTransport rtp_protocol);
294 static int rtp_new_av_stream(HTTPContext *c,
295                              int stream_index, struct sockaddr_in *dest_addr,
296                              HTTPContext *rtsp_c);
297
298 static const char *my_program_name;
299 static const char *my_program_dir;
300
301 static const char *config_filename = "/etc/ffserver.conf";
302
303 static int ffserver_debug;
304 static int ffserver_daemon;
305 static int no_launch;
306 static int need_to_start_children;
307
308 /* maximum number of simultaneous HTTP connections */
309 static unsigned int nb_max_http_connections = 2000;
310 static unsigned int nb_max_connections = 5;
311 static unsigned int nb_connections;
312
313 static uint64_t max_bandwidth = 1000;
314 static uint64_t current_bandwidth;
315
316 static int64_t cur_time;           // Making this global saves on passing it around everywhere
317
318 static AVLFG random_state;
319
320 static FILE *logfile = NULL;
321
322 /* FIXME: make ffserver work with IPv6 */
323 /* resolve host with also IP address parsing */
324 static int resolve_host(struct in_addr *sin_addr, const char *hostname)
325 {
326
327     if (!ff_inet_aton(hostname, sin_addr)) {
328 #if HAVE_GETADDRINFO
329         struct addrinfo *ai, *cur;
330         struct addrinfo hints;
331         memset(&hints, 0, sizeof(hints));
332         hints.ai_family = AF_INET;
333         if (getaddrinfo(hostname, NULL, &hints, &ai))
334             return -1;
335         /* getaddrinfo returns a linked list of addrinfo structs.
336          * Even if we set ai_family = AF_INET above, make sure
337          * that the returned one actually is of the correct type. */
338         for (cur = ai; cur; cur = cur->ai_next) {
339             if (cur->ai_family == AF_INET) {
340                 *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
341                 freeaddrinfo(ai);
342                 return 0;
343             }
344         }
345         freeaddrinfo(ai);
346         return -1;
347 #else
348         struct hostent *hp;
349         hp = gethostbyname(hostname);
350         if (!hp)
351             return -1;
352         memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
353 #endif
354     }
355     return 0;
356 }
357
358 static char *ctime1(char *buf2)
359 {
360     time_t ti;
361     char *p;
362
363     ti = time(NULL);
364     p = ctime(&ti);
365     strcpy(buf2, p);
366     p = buf2 + strlen(p) - 1;
367     if (*p == '\n')
368         *p = '\0';
369     return buf2;
370 }
371
372 static void http_vlog(const char *fmt, va_list vargs)
373 {
374     static int print_prefix = 1;
375     if (logfile) {
376         if (print_prefix) {
377             char buf[32];
378             ctime1(buf);
379             fprintf(logfile, "%s ", buf);
380         }
381         print_prefix = strstr(fmt, "\n") != NULL;
382         vfprintf(logfile, fmt, vargs);
383         fflush(logfile);
384     }
385 }
386
387 static void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...)
388 {
389     va_list vargs;
390     va_start(vargs, fmt);
391     http_vlog(fmt, vargs);
392     va_end(vargs);
393 }
394
395 static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs)
396 {
397     static int print_prefix = 1;
398     AVClass *avc = ptr ? *(AVClass**)ptr : NULL;
399     if (level > av_log_get_level())
400         return;
401     if (print_prefix && avc)
402         http_log("[%s @ %p]", avc->item_name(ptr), ptr);
403     print_prefix = strstr(fmt, "\n") != NULL;
404     http_vlog(fmt, vargs);
405 }
406
407 static void log_connection(HTTPContext *c)
408 {
409     if (c->suppress_log)
410         return;
411
412     http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n",
413              inet_ntoa(c->from_addr.sin_addr), c->method, c->url,
414              c->protocol, (c->http_error ? c->http_error : 200), c->data_count);
415 }
416
417 static void update_datarate(DataRateData *drd, int64_t count)
418 {
419     if (!drd->time1 && !drd->count1) {
420         drd->time1 = drd->time2 = cur_time;
421         drd->count1 = drd->count2 = count;
422     } else if (cur_time - drd->time2 > 5000) {
423         drd->time1 = drd->time2;
424         drd->count1 = drd->count2;
425         drd->time2 = cur_time;
426         drd->count2 = count;
427     }
428 }
429
430 /* In bytes per second */
431 static int compute_datarate(DataRateData *drd, int64_t count)
432 {
433     if (cur_time == drd->time1)
434         return 0;
435
436     return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
437 }
438
439
440 static void start_children(FFStream *feed)
441 {
442     if (no_launch)
443         return;
444
445     for (; feed; feed = feed->next) {
446         if (feed->child_argv && !feed->pid) {
447             feed->pid_start = time(0);
448
449             feed->pid = fork();
450
451             if (feed->pid < 0) {
452                 http_log("Unable to create children\n");
453                 exit(1);
454             }
455             if (!feed->pid) {
456                 /* In child */
457                 char pathname[1024];
458                 char *slash;
459                 int i;
460
461                 av_strlcpy(pathname, my_program_name, sizeof(pathname));
462
463                 slash = strrchr(pathname, '/');
464                 if (!slash)
465                     slash = pathname;
466                 else
467                     slash++;
468                 strcpy(slash, "ffmpeg");
469
470                 http_log("Launch commandline: ");
471                 http_log("%s ", pathname);
472                 for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++)
473                     http_log("%s ", feed->child_argv[i]);
474                 http_log("\n");
475
476                 for (i = 3; i < 256; i++)
477                     close(i);
478
479                 if (!ffserver_debug) {
480                     i = open("/dev/null", O_RDWR);
481                     if (i != -1) {
482                         dup2(i, 0);
483                         dup2(i, 1);
484                         dup2(i, 2);
485                         close(i);
486                     }
487                 }
488
489                 /* This is needed to make relative pathnames work */
490                 chdir(my_program_dir);
491
492                 signal(SIGPIPE, SIG_DFL);
493
494                 execvp(pathname, feed->child_argv);
495
496                 _exit(1);
497             }
498         }
499     }
500 }
501
502 /* open a listening socket */
503 static int socket_open_listen(struct sockaddr_in *my_addr)
504 {
505     int server_fd, tmp;
506
507     server_fd = socket(AF_INET,SOCK_STREAM,0);
508     if (server_fd < 0) {
509         perror ("socket");
510         return -1;
511     }
512
513     tmp = 1;
514     setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
515
516     if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
517         char bindmsg[32];
518         snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
519         perror (bindmsg);
520         closesocket(server_fd);
521         return -1;
522     }
523
524     if (listen (server_fd, 5) < 0) {
525         perror ("listen");
526         closesocket(server_fd);
527         return -1;
528     }
529     ff_socket_nonblock(server_fd, 1);
530
531     return server_fd;
532 }
533
534 /* start all multicast streams */
535 static void start_multicast(void)
536 {
537     FFStream *stream;
538     char session_id[32];
539     HTTPContext *rtp_c;
540     struct sockaddr_in dest_addr;
541     int default_port, stream_index;
542
543     default_port = 6000;
544     for(stream = first_stream; stream != NULL; stream = stream->next) {
545         if (stream->is_multicast) {
546             /* open the RTP connection */
547             snprintf(session_id, sizeof(session_id), "%08x%08x",
548                      av_lfg_get(&random_state), av_lfg_get(&random_state));
549
550             /* choose a port if none given */
551             if (stream->multicast_port == 0) {
552                 stream->multicast_port = default_port;
553                 default_port += 100;
554             }
555
556             dest_addr.sin_family = AF_INET;
557             dest_addr.sin_addr = stream->multicast_ip;
558             dest_addr.sin_port = htons(stream->multicast_port);
559
560             rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
561                                        RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
562             if (!rtp_c)
563                 continue;
564
565             if (open_input_stream(rtp_c, "") < 0) {
566                 http_log("Could not open input stream for stream '%s'\n",
567                          stream->filename);
568                 continue;
569             }
570
571             /* open each RTP stream */
572             for(stream_index = 0; stream_index < stream->nb_streams;
573                 stream_index++) {
574                 dest_addr.sin_port = htons(stream->multicast_port +
575                                            2 * stream_index);
576                 if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
577                     http_log("Could not open output stream '%s/streamid=%d'\n",
578                              stream->filename, stream_index);
579                     exit(1);
580                 }
581             }
582
583             /* change state to send data */
584             rtp_c->state = HTTPSTATE_SEND_DATA;
585         }
586     }
587 }
588
589 /* main loop of the http server */
590 static int http_server(void)
591 {
592     int server_fd = 0, rtsp_server_fd = 0;
593     int ret, delay, delay1;
594     struct pollfd *poll_table, *poll_entry;
595     HTTPContext *c, *c_next;
596
597     if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
598         http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
599         return -1;
600     }
601
602     if (my_http_addr.sin_port) {
603         server_fd = socket_open_listen(&my_http_addr);
604         if (server_fd < 0)
605             return -1;
606     }
607
608     if (my_rtsp_addr.sin_port) {
609         rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
610         if (rtsp_server_fd < 0)
611             return -1;
612     }
613
614     if (!rtsp_server_fd && !server_fd) {
615         http_log("HTTP and RTSP disabled.\n");
616         return -1;
617     }
618
619     http_log("FFserver started.\n");
620
621     start_children(first_feed);
622
623     start_multicast();
624
625     for(;;) {
626         poll_entry = poll_table;
627         if (server_fd) {
628             poll_entry->fd = server_fd;
629             poll_entry->events = POLLIN;
630             poll_entry++;
631         }
632         if (rtsp_server_fd) {
633             poll_entry->fd = rtsp_server_fd;
634             poll_entry->events = POLLIN;
635             poll_entry++;
636         }
637
638         /* wait for events on each HTTP handle */
639         c = first_http_ctx;
640         delay = 1000;
641         while (c != NULL) {
642             int fd;
643             fd = c->fd;
644             switch(c->state) {
645             case HTTPSTATE_SEND_HEADER:
646             case RTSPSTATE_SEND_REPLY:
647             case RTSPSTATE_SEND_PACKET:
648                 c->poll_entry = poll_entry;
649                 poll_entry->fd = fd;
650                 poll_entry->events = POLLOUT;
651                 poll_entry++;
652                 break;
653             case HTTPSTATE_SEND_DATA_HEADER:
654             case HTTPSTATE_SEND_DATA:
655             case HTTPSTATE_SEND_DATA_TRAILER:
656                 if (!c->is_packetized) {
657                     /* for TCP, we output as much as we can (may need to put a limit) */
658                     c->poll_entry = poll_entry;
659                     poll_entry->fd = fd;
660                     poll_entry->events = POLLOUT;
661                     poll_entry++;
662                 } else {
663                     /* when ffserver is doing the timing, we work by
664                        looking at which packet need to be sent every
665                        10 ms */
666                     delay1 = 10; /* one tick wait XXX: 10 ms assumed */
667                     if (delay1 < delay)
668                         delay = delay1;
669                 }
670                 break;
671             case HTTPSTATE_WAIT_REQUEST:
672             case HTTPSTATE_RECEIVE_DATA:
673             case HTTPSTATE_WAIT_FEED:
674             case RTSPSTATE_WAIT_REQUEST:
675                 /* need to catch errors */
676                 c->poll_entry = poll_entry;
677                 poll_entry->fd = fd;
678                 poll_entry->events = POLLIN;/* Maybe this will work */
679                 poll_entry++;
680                 break;
681             default:
682                 c->poll_entry = NULL;
683                 break;
684             }
685             c = c->next;
686         }
687
688         /* wait for an event on one connection. We poll at least every
689            second to handle timeouts */
690         do {
691             ret = poll(poll_table, poll_entry - poll_table, delay);
692             if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
693                 ff_neterrno() != FF_NETERROR(EINTR))
694                 return -1;
695         } while (ret < 0);
696
697         cur_time = av_gettime() / 1000;
698
699         if (need_to_start_children) {
700             need_to_start_children = 0;
701             start_children(first_feed);
702         }
703
704         /* now handle the events */
705         for(c = first_http_ctx; c != NULL; c = c_next) {
706             c_next = c->next;
707             if (handle_connection(c) < 0) {
708                 /* close and free the connection */
709                 log_connection(c);
710                 close_connection(c);
711             }
712         }
713
714         poll_entry = poll_table;
715         if (server_fd) {
716             /* new HTTP connection request ? */
717             if (poll_entry->revents & POLLIN)
718                 new_connection(server_fd, 0);
719             poll_entry++;
720         }
721         if (rtsp_server_fd) {
722             /* new RTSP connection request ? */
723             if (poll_entry->revents & POLLIN)
724                 new_connection(rtsp_server_fd, 1);
725         }
726     }
727 }
728
729 /* start waiting for a new HTTP/RTSP request */
730 static void start_wait_request(HTTPContext *c, int is_rtsp)
731 {
732     c->buffer_ptr = c->buffer;
733     c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
734
735     if (is_rtsp) {
736         c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
737         c->state = RTSPSTATE_WAIT_REQUEST;
738     } else {
739         c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
740         c->state = HTTPSTATE_WAIT_REQUEST;
741     }
742 }
743
744 static void http_send_too_busy_reply(int fd)
745 {
746     char buffer[300];
747     int len = snprintf(buffer, sizeof(buffer),
748                        "HTTP/1.0 503 Server too busy\r\n"
749                        "Content-type: text/html\r\n"
750                        "\r\n"
751                        "<html><head><title>Too busy</title></head><body>\r\n"
752                        "<p>The server is too busy to serve your request at this time.</p>\r\n"
753                        "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
754                        "</body></html>\r\n",
755                        nb_connections, nb_max_connections);
756     send(fd, buffer, len, 0);
757 }
758
759
760 static void new_connection(int server_fd, int is_rtsp)
761 {
762     struct sockaddr_in from_addr;
763     int fd, len;
764     HTTPContext *c = NULL;
765
766     len = sizeof(from_addr);
767     fd = accept(server_fd, (struct sockaddr *)&from_addr,
768                 &len);
769     if (fd < 0) {
770         http_log("error during accept %s\n", strerror(errno));
771         return;
772     }
773     ff_socket_nonblock(fd, 1);
774
775     if (nb_connections >= nb_max_connections) {
776         http_send_too_busy_reply(fd);
777         goto fail;
778     }
779
780     /* add a new connection */
781     c = av_mallocz(sizeof(HTTPContext));
782     if (!c)
783         goto fail;
784
785     c->fd = fd;
786     c->poll_entry = NULL;
787     c->from_addr = from_addr;
788     c->buffer_size = IOBUFFER_INIT_SIZE;
789     c->buffer = av_malloc(c->buffer_size);
790     if (!c->buffer)
791         goto fail;
792
793     c->next = first_http_ctx;
794     first_http_ctx = c;
795     nb_connections++;
796
797     start_wait_request(c, is_rtsp);
798
799     return;
800
801  fail:
802     if (c) {
803         av_free(c->buffer);
804         av_free(c);
805     }
806     closesocket(fd);
807 }
808
809 static void close_connection(HTTPContext *c)
810 {
811     HTTPContext **cp, *c1;
812     int i, nb_streams;
813     AVFormatContext *ctx;
814     URLContext *h;
815     AVStream *st;
816
817     /* remove connection from list */
818     cp = &first_http_ctx;
819     while ((*cp) != NULL) {
820         c1 = *cp;
821         if (c1 == c)
822             *cp = c->next;
823         else
824             cp = &c1->next;
825     }
826
827     /* remove references, if any (XXX: do it faster) */
828     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
829         if (c1->rtsp_c == c)
830             c1->rtsp_c = NULL;
831     }
832
833     /* remove connection associated resources */
834     if (c->fd >= 0)
835         closesocket(c->fd);
836     if (c->fmt_in) {
837         /* close each frame parser */
838         for(i=0;i<c->fmt_in->nb_streams;i++) {
839             st = c->fmt_in->streams[i];
840             if (st->codec->codec)
841                 avcodec_close(st->codec);
842         }
843         av_close_input_file(c->fmt_in);
844     }
845
846     /* free RTP output streams if any */
847     nb_streams = 0;
848     if (c->stream)
849         nb_streams = c->stream->nb_streams;
850
851     for(i=0;i<nb_streams;i++) {
852         ctx = c->rtp_ctx[i];
853         if (ctx) {
854             av_write_trailer(ctx);
855             av_metadata_free(&ctx->metadata);
856             av_free(ctx->streams[0]);
857             av_free(ctx);
858         }
859         h = c->rtp_handles[i];
860         if (h)
861             url_close(h);
862     }
863
864     ctx = &c->fmt_ctx;
865
866     if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
867         if (ctx->oformat) {
868             /* prepare header */
869             if (url_open_dyn_buf(&ctx->pb) >= 0) {
870                 av_write_trailer(ctx);
871                 av_freep(&c->pb_buffer);
872                 url_close_dyn_buf(ctx->pb, &c->pb_buffer);
873             }
874         }
875     }
876
877     for(i=0; i<ctx->nb_streams; i++)
878         av_free(ctx->streams[i]);
879
880     if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
881         current_bandwidth -= c->stream->bandwidth;
882
883     /* signal that there is no feed if we are the feeder socket */
884     if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
885         c->stream->feed_opened = 0;
886         close(c->feed_fd);
887     }
888
889     av_freep(&c->pb_buffer);
890     av_freep(&c->packet_buffer);
891     av_free(c->buffer);
892     av_free(c);
893     nb_connections--;
894 }
895
896 static int handle_connection(HTTPContext *c)
897 {
898     int len, ret;
899
900     switch(c->state) {
901     case HTTPSTATE_WAIT_REQUEST:
902     case RTSPSTATE_WAIT_REQUEST:
903         /* timeout ? */
904         if ((c->timeout - cur_time) < 0)
905             return -1;
906         if (c->poll_entry->revents & (POLLERR | POLLHUP))
907             return -1;
908
909         /* no need to read if no events */
910         if (!(c->poll_entry->revents & POLLIN))
911             return 0;
912         /* read the data */
913     read_loop:
914         len = recv(c->fd, c->buffer_ptr, 1, 0);
915         if (len < 0) {
916             if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
917                 ff_neterrno() != FF_NETERROR(EINTR))
918                 return -1;
919         } else if (len == 0) {
920             return -1;
921         } else {
922             /* search for end of request. */
923             uint8_t *ptr;
924             c->buffer_ptr += len;
925             ptr = c->buffer_ptr;
926             if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
927                 (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
928                 /* request found : parse it and reply */
929                 if (c->state == HTTPSTATE_WAIT_REQUEST) {
930                     ret = http_parse_request(c);
931                 } else {
932                     ret = rtsp_parse_request(c);
933                 }
934                 if (ret < 0)
935                     return -1;
936             } else if (ptr >= c->buffer_end) {
937                 /* request too long: cannot do anything */
938                 return -1;
939             } else goto read_loop;
940         }
941         break;
942
943     case HTTPSTATE_SEND_HEADER:
944         if (c->poll_entry->revents & (POLLERR | POLLHUP))
945             return -1;
946
947         /* no need to write if no events */
948         if (!(c->poll_entry->revents & POLLOUT))
949             return 0;
950         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
951         if (len < 0) {
952             if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
953                 ff_neterrno() != FF_NETERROR(EINTR)) {
954                 /* error : close connection */
955                 av_freep(&c->pb_buffer);
956                 return -1;
957             }
958         } else {
959             c->buffer_ptr += len;
960             if (c->stream)
961                 c->stream->bytes_served += len;
962             c->data_count += len;
963             if (c->buffer_ptr >= c->buffer_end) {
964                 av_freep(&c->pb_buffer);
965                 /* if error, exit */
966                 if (c->http_error)
967                     return -1;
968                 /* all the buffer was sent : synchronize to the incoming stream */
969                 c->state = HTTPSTATE_SEND_DATA_HEADER;
970                 c->buffer_ptr = c->buffer_end = c->buffer;
971             }
972         }
973         break;
974
975     case HTTPSTATE_SEND_DATA:
976     case HTTPSTATE_SEND_DATA_HEADER:
977     case HTTPSTATE_SEND_DATA_TRAILER:
978         /* for packetized output, we consider we can always write (the
979            input streams sets the speed). It may be better to verify
980            that we do not rely too much on the kernel queues */
981         if (!c->is_packetized) {
982             if (c->poll_entry->revents & (POLLERR | POLLHUP))
983                 return -1;
984
985             /* no need to read if no events */
986             if (!(c->poll_entry->revents & POLLOUT))
987                 return 0;
988         }
989         if (http_send_data(c) < 0)
990             return -1;
991         /* close connection if trailer sent */
992         if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
993             return -1;
994         break;
995     case HTTPSTATE_RECEIVE_DATA:
996         /* no need to read if no events */
997         if (c->poll_entry->revents & (POLLERR | POLLHUP))
998             return -1;
999         if (!(c->poll_entry->revents & POLLIN))
1000             return 0;
1001         if (http_receive_data(c) < 0)
1002             return -1;
1003         break;
1004     case HTTPSTATE_WAIT_FEED:
1005         /* no need to read if no events */
1006         if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
1007             return -1;
1008
1009         /* nothing to do, we'll be waken up by incoming feed packets */
1010         break;
1011
1012     case RTSPSTATE_SEND_REPLY:
1013         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1014             av_freep(&c->pb_buffer);
1015             return -1;
1016         }
1017         /* no need to write if no events */
1018         if (!(c->poll_entry->revents & POLLOUT))
1019             return 0;
1020         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1021         if (len < 0) {
1022             if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
1023                 ff_neterrno() != FF_NETERROR(EINTR)) {
1024                 /* error : close connection */
1025                 av_freep(&c->pb_buffer);
1026                 return -1;
1027             }
1028         } else {
1029             c->buffer_ptr += len;
1030             c->data_count += len;
1031             if (c->buffer_ptr >= c->buffer_end) {
1032                 /* all the buffer was sent : wait for a new request */
1033                 av_freep(&c->pb_buffer);
1034                 start_wait_request(c, 1);
1035             }
1036         }
1037         break;
1038     case RTSPSTATE_SEND_PACKET:
1039         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1040             av_freep(&c->packet_buffer);
1041             return -1;
1042         }
1043         /* no need to write if no events */
1044         if (!(c->poll_entry->revents & POLLOUT))
1045             return 0;
1046         len = send(c->fd, c->packet_buffer_ptr,
1047                     c->packet_buffer_end - c->packet_buffer_ptr, 0);
1048         if (len < 0) {
1049             if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
1050                 ff_neterrno() != FF_NETERROR(EINTR)) {
1051                 /* error : close connection */
1052                 av_freep(&c->packet_buffer);
1053                 return -1;
1054             }
1055         } else {
1056             c->packet_buffer_ptr += len;
1057             if (c->packet_buffer_ptr >= c->packet_buffer_end) {
1058                 /* all the buffer was sent : wait for a new request */
1059                 av_freep(&c->packet_buffer);
1060                 c->state = RTSPSTATE_WAIT_REQUEST;
1061             }
1062         }
1063         break;
1064     case HTTPSTATE_READY:
1065         /* nothing to do */
1066         break;
1067     default:
1068         return -1;
1069     }
1070     return 0;
1071 }
1072
1073 static int extract_rates(char *rates, int ratelen, const char *request)
1074 {
1075     const char *p;
1076
1077     for (p = request; *p && *p != '\r' && *p != '\n'; ) {
1078         if (strncasecmp(p, "Pragma:", 7) == 0) {
1079             const char *q = p + 7;
1080
1081             while (*q && *q != '\n' && isspace(*q))
1082                 q++;
1083
1084             if (strncasecmp(q, "stream-switch-entry=", 20) == 0) {
1085                 int stream_no;
1086                 int rate_no;
1087
1088                 q += 20;
1089
1090                 memset(rates, 0xff, ratelen);
1091
1092                 while (1) {
1093                     while (*q && *q != '\n' && *q != ':')
1094                         q++;
1095
1096                     if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
1097                         break;
1098
1099                     stream_no--;
1100                     if (stream_no < ratelen && stream_no >= 0)
1101                         rates[stream_no] = rate_no;
1102
1103                     while (*q && *q != '\n' && !isspace(*q))
1104                         q++;
1105                 }
1106
1107                 return 1;
1108             }
1109         }
1110         p = strchr(p, '\n');
1111         if (!p)
1112             break;
1113
1114         p++;
1115     }
1116
1117     return 0;
1118 }
1119
1120 static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
1121 {
1122     int i;
1123     int best_bitrate = 100000000;
1124     int best = -1;
1125
1126     for (i = 0; i < feed->nb_streams; i++) {
1127         AVCodecContext *feed_codec = feed->streams[i]->codec;
1128
1129         if (feed_codec->codec_id != codec->codec_id ||
1130             feed_codec->sample_rate != codec->sample_rate ||
1131             feed_codec->width != codec->width ||
1132             feed_codec->height != codec->height)
1133             continue;
1134
1135         /* Potential stream */
1136
1137         /* We want the fastest stream less than bit_rate, or the slowest
1138          * faster than bit_rate
1139          */
1140
1141         if (feed_codec->bit_rate <= bit_rate) {
1142             if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
1143                 best_bitrate = feed_codec->bit_rate;
1144                 best = i;
1145             }
1146         } else {
1147             if (feed_codec->bit_rate < best_bitrate) {
1148                 best_bitrate = feed_codec->bit_rate;
1149                 best = i;
1150             }
1151         }
1152     }
1153
1154     return best;
1155 }
1156
1157 static int modify_current_stream(HTTPContext *c, char *rates)
1158 {
1159     int i;
1160     FFStream *req = c->stream;
1161     int action_required = 0;
1162
1163     /* Not much we can do for a feed */
1164     if (!req->feed)
1165         return 0;
1166
1167     for (i = 0; i < req->nb_streams; i++) {
1168         AVCodecContext *codec = req->streams[i]->codec;
1169
1170         switch(rates[i]) {
1171             case 0:
1172                 c->switch_feed_streams[i] = req->feed_streams[i];
1173                 break;
1174             case 1:
1175                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
1176                 break;
1177             case 2:
1178                 /* Wants off or slow */
1179                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
1180 #ifdef WANTS_OFF
1181                 /* This doesn't work well when it turns off the only stream! */
1182                 c->switch_feed_streams[i] = -2;
1183                 c->feed_streams[i] = -2;
1184 #endif
1185                 break;
1186         }
1187
1188         if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
1189             action_required = 1;
1190     }
1191
1192     return action_required;
1193 }
1194
1195
1196 static void do_switch_stream(HTTPContext *c, int i)
1197 {
1198     if (c->switch_feed_streams[i] >= 0) {
1199 #ifdef PHILIP
1200         c->feed_streams[i] = c->switch_feed_streams[i];
1201 #endif
1202
1203         /* Now update the stream */
1204     }
1205     c->switch_feed_streams[i] = -1;
1206 }
1207
1208 /* XXX: factorize in utils.c ? */
1209 /* XXX: take care with different space meaning */
1210 static void skip_spaces(const char **pp)
1211 {
1212     const char *p;
1213     p = *pp;
1214     while (*p == ' ' || *p == '\t')
1215         p++;
1216     *pp = p;
1217 }
1218
1219 static void get_word(char *buf, int buf_size, const char **pp)
1220 {
1221     const char *p;
1222     char *q;
1223
1224     p = *pp;
1225     skip_spaces(&p);
1226     q = buf;
1227     while (!isspace(*p) && *p != '\0') {
1228         if ((q - buf) < buf_size - 1)
1229             *q++ = *p;
1230         p++;
1231     }
1232     if (buf_size > 0)
1233         *q = '\0';
1234     *pp = p;
1235 }
1236
1237 static void get_arg(char *buf, int buf_size, const char **pp)
1238 {
1239     const char *p;
1240     char *q;
1241     int quote;
1242
1243     p = *pp;
1244     while (isspace(*p)) p++;
1245     q = buf;
1246     quote = 0;
1247     if (*p == '\"' || *p == '\'')
1248         quote = *p++;
1249     for(;;) {
1250         if (quote) {
1251             if (*p == quote)
1252                 break;
1253         } else {
1254             if (isspace(*p))
1255                 break;
1256         }
1257         if (*p == '\0')
1258             break;
1259         if ((q - buf) < buf_size - 1)
1260             *q++ = *p;
1261         p++;
1262     }
1263     *q = '\0';
1264     if (quote && *p == quote)
1265         p++;
1266     *pp = p;
1267 }
1268
1269 static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
1270                          const char *p, const char *filename, int line_num)
1271 {
1272     char arg[1024];
1273     IPAddressACL acl;
1274     int errors = 0;
1275
1276     get_arg(arg, sizeof(arg), &p);
1277     if (strcasecmp(arg, "allow") == 0)
1278         acl.action = IP_ALLOW;
1279     else if (strcasecmp(arg, "deny") == 0)
1280         acl.action = IP_DENY;
1281     else {
1282         fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
1283                 filename, line_num, arg);
1284         errors++;
1285     }
1286
1287     get_arg(arg, sizeof(arg), &p);
1288
1289     if (resolve_host(&acl.first, arg) != 0) {
1290         fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
1291                 filename, line_num, arg);
1292         errors++;
1293     } else
1294         acl.last = acl.first;
1295
1296     get_arg(arg, sizeof(arg), &p);
1297
1298     if (arg[0]) {
1299         if (resolve_host(&acl.last, arg) != 0) {
1300             fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
1301                     filename, line_num, arg);
1302             errors++;
1303         }
1304     }
1305
1306     if (!errors) {
1307         IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
1308         IPAddressACL **naclp = 0;
1309
1310         acl.next = 0;
1311         *nacl = acl;
1312
1313         if (stream)
1314             naclp = &stream->acl;
1315         else if (feed)
1316             naclp = &feed->acl;
1317         else if (ext_acl)
1318             naclp = &ext_acl;
1319         else {
1320             fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
1321                     filename, line_num);
1322             errors++;
1323         }
1324
1325         if (naclp) {
1326             while (*naclp)
1327                 naclp = &(*naclp)->next;
1328
1329             *naclp = nacl;
1330         }
1331     }
1332 }
1333
1334
1335 static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
1336 {
1337     FILE* f;
1338     char line[1024];
1339     char  cmd[1024];
1340     IPAddressACL *acl = NULL;
1341     int line_num = 0;
1342     const char *p;
1343
1344     f = fopen(stream->dynamic_acl, "r");
1345     if (!f) {
1346         perror(stream->dynamic_acl);
1347         return NULL;
1348     }
1349
1350     acl = av_mallocz(sizeof(IPAddressACL));
1351
1352     /* Build ACL */
1353     for(;;) {
1354         if (fgets(line, sizeof(line), f) == NULL)
1355             break;
1356         line_num++;
1357         p = line;
1358         while (isspace(*p))
1359             p++;
1360         if (*p == '\0' || *p == '#')
1361             continue;
1362         get_arg(cmd, sizeof(cmd), &p);
1363
1364         if (!strcasecmp(cmd, "ACL"))
1365             parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
1366     }
1367     fclose(f);
1368     return acl;
1369 }
1370
1371
1372 static void free_acl_list(IPAddressACL *in_acl)
1373 {
1374     IPAddressACL *pacl,*pacl2;
1375
1376     pacl = in_acl;
1377     while(pacl) {
1378         pacl2 = pacl;
1379         pacl = pacl->next;
1380         av_freep(pacl2);
1381     }
1382 }
1383
1384 static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
1385 {
1386     enum IPAddressAction last_action = IP_DENY;
1387     IPAddressACL *acl;
1388     struct in_addr *src = &c->from_addr.sin_addr;
1389     unsigned long src_addr = src->s_addr;
1390
1391     for (acl = in_acl; acl; acl = acl->next) {
1392         if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
1393             return (acl->action == IP_ALLOW) ? 1 : 0;
1394         last_action = acl->action;
1395     }
1396
1397     /* Nothing matched, so return not the last action */
1398     return (last_action == IP_DENY) ? 1 : 0;
1399 }
1400
1401 static int validate_acl(FFStream *stream, HTTPContext *c)
1402 {
1403     int ret = 0;
1404     IPAddressACL *acl;
1405
1406
1407     /* if stream->acl is null validate_acl_list will return 1 */
1408     ret = validate_acl_list(stream->acl, c);
1409
1410     if (stream->dynamic_acl[0]) {
1411         acl = parse_dynamic_acl(stream, c);
1412
1413         ret = validate_acl_list(acl, c);
1414
1415         free_acl_list(acl);
1416     }
1417
1418     return ret;
1419 }
1420
1421 /* compute the real filename of a file by matching it without its
1422    extensions to all the stream filenames */
1423 static void compute_real_filename(char *filename, int max_size)
1424 {
1425     char file1[1024];
1426     char file2[1024];
1427     char *p;
1428     FFStream *stream;
1429
1430     /* compute filename by matching without the file extensions */
1431     av_strlcpy(file1, filename, sizeof(file1));
1432     p = strrchr(file1, '.');
1433     if (p)
1434         *p = '\0';
1435     for(stream = first_stream; stream != NULL; stream = stream->next) {
1436         av_strlcpy(file2, stream->filename, sizeof(file2));
1437         p = strrchr(file2, '.');
1438         if (p)
1439             *p = '\0';
1440         if (!strcmp(file1, file2)) {
1441             av_strlcpy(filename, stream->filename, max_size);
1442             break;
1443         }
1444     }
1445 }
1446
1447 enum RedirType {
1448     REDIR_NONE,
1449     REDIR_ASX,
1450     REDIR_RAM,
1451     REDIR_ASF,
1452     REDIR_RTSP,
1453     REDIR_SDP,
1454 };
1455
1456 /* parse http request and prepare header */
1457 static int http_parse_request(HTTPContext *c)
1458 {
1459     char *p;
1460     enum RedirType redir_type;
1461     char cmd[32];
1462     char info[1024], filename[1024];
1463     char url[1024], *q;
1464     char protocol[32];
1465     char msg[1024];
1466     const char *mime_type;
1467     FFStream *stream;
1468     int i;
1469     char ratebuf[32];
1470     char *useragent = 0;
1471
1472     p = c->buffer;
1473     get_word(cmd, sizeof(cmd), (const char **)&p);
1474     av_strlcpy(c->method, cmd, sizeof(c->method));
1475
1476     if (!strcmp(cmd, "GET"))
1477         c->post = 0;
1478     else if (!strcmp(cmd, "POST"))
1479         c->post = 1;
1480     else
1481         return -1;
1482
1483     get_word(url, sizeof(url), (const char **)&p);
1484     av_strlcpy(c->url, url, sizeof(c->url));
1485
1486     get_word(protocol, sizeof(protocol), (const char **)&p);
1487     if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
1488         return -1;
1489
1490     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
1491
1492     if (ffserver_debug)
1493         http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
1494
1495     /* find the filename and the optional info string in the request */
1496     p = strchr(url, '?');
1497     if (p) {
1498         av_strlcpy(info, p, sizeof(info));
1499         *p = '\0';
1500     } else
1501         info[0] = '\0';
1502
1503     av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
1504
1505     for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1506         if (strncasecmp(p, "User-Agent:", 11) == 0) {
1507             useragent = p + 11;
1508             if (*useragent && *useragent != '\n' && isspace(*useragent))
1509                 useragent++;
1510             break;
1511         }
1512         p = strchr(p, '\n');
1513         if (!p)
1514             break;
1515
1516         p++;
1517     }
1518
1519     redir_type = REDIR_NONE;
1520     if (av_match_ext(filename, "asx")) {
1521         redir_type = REDIR_ASX;
1522         filename[strlen(filename)-1] = 'f';
1523     } else if (av_match_ext(filename, "asf") &&
1524         (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) {
1525         /* if this isn't WMP or lookalike, return the redirector file */
1526         redir_type = REDIR_ASF;
1527     } else if (av_match_ext(filename, "rpm,ram")) {
1528         redir_type = REDIR_RAM;
1529         strcpy(filename + strlen(filename)-2, "m");
1530     } else if (av_match_ext(filename, "rtsp")) {
1531         redir_type = REDIR_RTSP;
1532         compute_real_filename(filename, sizeof(filename) - 1);
1533     } else if (av_match_ext(filename, "sdp")) {
1534         redir_type = REDIR_SDP;
1535         compute_real_filename(filename, sizeof(filename) - 1);
1536     }
1537
1538     // "redirect" / request to index.html
1539     if (!strlen(filename))
1540         av_strlcpy(filename, "index.html", sizeof(filename) - 1);
1541
1542     stream = first_stream;
1543     while (stream != NULL) {
1544         if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
1545             break;
1546         stream = stream->next;
1547     }
1548     if (stream == NULL) {
1549         snprintf(msg, sizeof(msg), "File '%s' not found", url);
1550         http_log("File '%s' not found\n", url);
1551         goto send_error;
1552     }
1553
1554     c->stream = stream;
1555     memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
1556     memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
1557
1558     if (stream->stream_type == STREAM_TYPE_REDIRECT) {
1559         c->http_error = 301;
1560         q = c->buffer;
1561         q += snprintf(q, c->buffer_size,
1562                       "HTTP/1.0 301 Moved\r\n"
1563                       "Location: %s\r\n"
1564                       "Content-type: text/html\r\n"
1565                       "\r\n"
1566                       "<html><head><title>Moved</title></head><body>\r\n"
1567                       "You should be <a href=\"%s\">redirected</a>.\r\n"
1568                       "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
1569         /* prepare output buffer */
1570         c->buffer_ptr = c->buffer;
1571         c->buffer_end = q;
1572         c->state = HTTPSTATE_SEND_HEADER;
1573         return 0;
1574     }
1575
1576     /* If this is WMP, get the rate information */
1577     if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1578         if (modify_current_stream(c, ratebuf)) {
1579             for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
1580                 if (c->switch_feed_streams[i] >= 0)
1581                     do_switch_stream(c, i);
1582             }
1583         }
1584     }
1585
1586     if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
1587         current_bandwidth += stream->bandwidth;
1588
1589     /* If already streaming this feed, do not let start another feeder. */
1590     if (stream->feed_opened) {
1591         snprintf(msg, sizeof(msg), "This feed is already being received.");
1592         http_log("Feed '%s' already being received\n", stream->feed_filename);
1593         goto send_error;
1594     }
1595
1596     if (c->post == 0 && max_bandwidth < current_bandwidth) {
1597         c->http_error = 503;
1598         q = c->buffer;
1599         q += snprintf(q, c->buffer_size,
1600                       "HTTP/1.0 503 Server too busy\r\n"
1601                       "Content-type: text/html\r\n"
1602                       "\r\n"
1603                       "<html><head><title>Too busy</title></head><body>\r\n"
1604                       "<p>The server is too busy to serve your request at this time.</p>\r\n"
1605                       "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
1606                       "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
1607                       "</body></html>\r\n", current_bandwidth, max_bandwidth);
1608         /* prepare output buffer */
1609         c->buffer_ptr = c->buffer;
1610         c->buffer_end = q;
1611         c->state = HTTPSTATE_SEND_HEADER;
1612         return 0;
1613     }
1614
1615     if (redir_type != REDIR_NONE) {
1616         char *hostinfo = 0;
1617
1618         for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1619             if (strncasecmp(p, "Host:", 5) == 0) {
1620                 hostinfo = p + 5;
1621                 break;
1622             }
1623             p = strchr(p, '\n');
1624             if (!p)
1625                 break;
1626
1627             p++;
1628         }
1629
1630         if (hostinfo) {
1631             char *eoh;
1632             char hostbuf[260];
1633
1634             while (isspace(*hostinfo))
1635                 hostinfo++;
1636
1637             eoh = strchr(hostinfo, '\n');
1638             if (eoh) {
1639                 if (eoh[-1] == '\r')
1640                     eoh--;
1641
1642                 if (eoh - hostinfo < sizeof(hostbuf) - 1) {
1643                     memcpy(hostbuf, hostinfo, eoh - hostinfo);
1644                     hostbuf[eoh - hostinfo] = 0;
1645
1646                     c->http_error = 200;
1647                     q = c->buffer;
1648                     switch(redir_type) {
1649                     case REDIR_ASX:
1650                         q += snprintf(q, c->buffer_size,
1651                                       "HTTP/1.0 200 ASX Follows\r\n"
1652                                       "Content-type: video/x-ms-asf\r\n"
1653                                       "\r\n"
1654                                       "<ASX Version=\"3\">\r\n"
1655                                       //"<!-- Autogenerated by ffserver -->\r\n"
1656                                       "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
1657                                       "</ASX>\r\n", hostbuf, filename, info);
1658                         break;
1659                     case REDIR_RAM:
1660                         q += snprintf(q, c->buffer_size,
1661                                       "HTTP/1.0 200 RAM Follows\r\n"
1662                                       "Content-type: audio/x-pn-realaudio\r\n"
1663                                       "\r\n"
1664                                       "# Autogenerated by ffserver\r\n"
1665                                       "http://%s/%s%s\r\n", hostbuf, filename, info);
1666                         break;
1667                     case REDIR_ASF:
1668                         q += snprintf(q, c->buffer_size,
1669                                       "HTTP/1.0 200 ASF Redirect follows\r\n"
1670                                       "Content-type: video/x-ms-asf\r\n"
1671                                       "\r\n"
1672                                       "[Reference]\r\n"
1673                                       "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
1674                         break;
1675                     case REDIR_RTSP:
1676                         {
1677                             char hostname[256], *p;
1678                             /* extract only hostname */
1679                             av_strlcpy(hostname, hostbuf, sizeof(hostname));
1680                             p = strrchr(hostname, ':');
1681                             if (p)
1682                                 *p = '\0';
1683                             q += snprintf(q, c->buffer_size,
1684                                           "HTTP/1.0 200 RTSP Redirect follows\r\n"
1685                                           /* XXX: incorrect mime type ? */
1686                                           "Content-type: application/x-rtsp\r\n"
1687                                           "\r\n"
1688                                           "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
1689                         }
1690                         break;
1691                     case REDIR_SDP:
1692                         {
1693                             uint8_t *sdp_data;
1694                             int sdp_data_size, len;
1695                             struct sockaddr_in my_addr;
1696
1697                             q += snprintf(q, c->buffer_size,
1698                                           "HTTP/1.0 200 OK\r\n"
1699                                           "Content-type: application/sdp\r\n"
1700                                           "\r\n");
1701
1702                             len = sizeof(my_addr);
1703                             getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
1704
1705                             /* XXX: should use a dynamic buffer */
1706                             sdp_data_size = prepare_sdp_description(stream,
1707                                                                     &sdp_data,
1708                                                                     my_addr.sin_addr);
1709                             if (sdp_data_size > 0) {
1710                                 memcpy(q, sdp_data, sdp_data_size);
1711                                 q += sdp_data_size;
1712                                 *q = '\0';
1713                                 av_free(sdp_data);
1714                             }
1715                         }
1716                         break;
1717                     default:
1718                         abort();
1719                         break;
1720                     }
1721
1722                     /* prepare output buffer */
1723                     c->buffer_ptr = c->buffer;
1724                     c->buffer_end = q;
1725                     c->state = HTTPSTATE_SEND_HEADER;
1726                     return 0;
1727                 }
1728             }
1729         }
1730
1731         snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
1732         goto send_error;
1733     }
1734
1735     stream->conns_served++;
1736
1737     /* XXX: add there authenticate and IP match */
1738
1739     if (c->post) {
1740         /* if post, it means a feed is being sent */
1741         if (!stream->is_feed) {
1742             /* However it might be a status report from WMP! Let us log the
1743              * data as it might come in handy one day. */
1744             char *logline = 0;
1745             int client_id = 0;
1746
1747             for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1748                 if (strncasecmp(p, "Pragma: log-line=", 17) == 0) {
1749                     logline = p;
1750                     break;
1751                 }
1752                 if (strncasecmp(p, "Pragma: client-id=", 18) == 0)
1753                     client_id = strtol(p + 18, 0, 10);
1754                 p = strchr(p, '\n');
1755                 if (!p)
1756                     break;
1757
1758                 p++;
1759             }
1760
1761             if (logline) {
1762                 char *eol = strchr(logline, '\n');
1763
1764                 logline += 17;
1765
1766                 if (eol) {
1767                     if (eol[-1] == '\r')
1768                         eol--;
1769                     http_log("%.*s\n", (int) (eol - logline), logline);
1770                     c->suppress_log = 1;
1771                 }
1772             }
1773
1774 #ifdef DEBUG_WMP
1775             http_log("\nGot request:\n%s\n", c->buffer);
1776 #endif
1777
1778             if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1779                 HTTPContext *wmpc;
1780
1781                 /* Now we have to find the client_id */
1782                 for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
1783                     if (wmpc->wmp_client_id == client_id)
1784                         break;
1785                 }
1786
1787                 if (wmpc && modify_current_stream(wmpc, ratebuf))
1788                     wmpc->switch_pending = 1;
1789             }
1790
1791             snprintf(msg, sizeof(msg), "POST command not handled");
1792             c->stream = 0;
1793             goto send_error;
1794         }
1795         if (http_start_receive_data(c) < 0) {
1796             snprintf(msg, sizeof(msg), "could not open feed");
1797             goto send_error;
1798         }
1799         c->http_error = 0;
1800         c->state = HTTPSTATE_RECEIVE_DATA;
1801         return 0;
1802     }
1803
1804 #ifdef DEBUG_WMP
1805     if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
1806         http_log("\nGot request:\n%s\n", c->buffer);
1807 #endif
1808
1809     if (c->stream->stream_type == STREAM_TYPE_STATUS)
1810         goto send_status;
1811
1812     /* open input stream */
1813     if (open_input_stream(c, info) < 0) {
1814         snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
1815         goto send_error;
1816     }
1817
1818     /* prepare http header */
1819     q = c->buffer;
1820     q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
1821     mime_type = c->stream->fmt->mime_type;
1822     if (!mime_type)
1823         mime_type = "application/x-octet-stream";
1824     q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n");
1825
1826     /* for asf, we need extra headers */
1827     if (!strcmp(c->stream->fmt->name,"asf_stream")) {
1828         /* Need to allocate a client id */
1829
1830         c->wmp_client_id = av_lfg_get(&random_state);
1831
1832         q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
1833     }
1834     q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type);
1835     q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1836
1837     /* prepare output buffer */
1838     c->http_error = 0;
1839     c->buffer_ptr = c->buffer;
1840     c->buffer_end = q;
1841     c->state = HTTPSTATE_SEND_HEADER;
1842     return 0;
1843  send_error:
1844     c->http_error = 404;
1845     q = c->buffer;
1846     q += snprintf(q, c->buffer_size,
1847                   "HTTP/1.0 404 Not Found\r\n"
1848                   "Content-type: text/html\r\n"
1849                   "\r\n"
1850                   "<html>\n"
1851                   "<head><title>404 Not Found</title></head>\n"
1852                   "<body>%s</body>\n"
1853                   "</html>\n", msg);
1854     /* prepare output buffer */
1855     c->buffer_ptr = c->buffer;
1856     c->buffer_end = q;
1857     c->state = HTTPSTATE_SEND_HEADER;
1858     return 0;
1859  send_status:
1860     compute_status(c);
1861     c->http_error = 200; /* horrible : we use this value to avoid
1862                             going to the send data state */
1863     c->state = HTTPSTATE_SEND_HEADER;
1864     return 0;
1865 }
1866
1867 static void fmt_bytecount(ByteIOContext *pb, int64_t count)
1868 {
1869     static const char *suffix = " kMGTP";
1870     const char *s;
1871
1872     for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
1873
1874     url_fprintf(pb, "%"PRId64"%c", count, *s);
1875 }
1876
1877 static void compute_status(HTTPContext *c)
1878 {
1879     HTTPContext *c1;
1880     FFStream *stream;
1881     char *p;
1882     time_t ti;
1883     int i, len;
1884     ByteIOContext *pb;
1885
1886     if (url_open_dyn_buf(&pb) < 0) {
1887         /* XXX: return an error ? */
1888         c->buffer_ptr = c->buffer;
1889         c->buffer_end = c->buffer;
1890         return;
1891     }
1892
1893     url_fprintf(pb, "HTTP/1.0 200 OK\r\n");
1894     url_fprintf(pb, "Content-type: %s\r\n", "text/html");
1895     url_fprintf(pb, "Pragma: no-cache\r\n");
1896     url_fprintf(pb, "\r\n");
1897
1898     url_fprintf(pb, "<html><head><title>%s Status</title>\n", program_name);
1899     if (c->stream->feed_filename[0])
1900         url_fprintf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
1901     url_fprintf(pb, "</head>\n<body>");
1902     url_fprintf(pb, "<h1>%s Status</h1>\n", program_name);
1903     /* format status */
1904     url_fprintf(pb, "<h2>Available Streams</h2>\n");
1905     url_fprintf(pb, "<table cellspacing=0 cellpadding=4>\n");
1906     url_fprintf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
1907     stream = first_stream;
1908     while (stream != NULL) {
1909         char sfilename[1024];
1910         char *eosf;
1911
1912         if (stream->feed != stream) {
1913             av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
1914             eosf = sfilename + strlen(sfilename);
1915             if (eosf - sfilename >= 4) {
1916                 if (strcmp(eosf - 4, ".asf") == 0)
1917                     strcpy(eosf - 4, ".asx");
1918                 else if (strcmp(eosf - 3, ".rm") == 0)
1919                     strcpy(eosf - 3, ".ram");
1920                 else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
1921                     /* generate a sample RTSP director if
1922                        unicast. Generate an SDP redirector if
1923                        multicast */
1924                     eosf = strrchr(sfilename, '.');
1925                     if (!eosf)
1926                         eosf = sfilename + strlen(sfilename);
1927                     if (stream->is_multicast)
1928                         strcpy(eosf, ".sdp");
1929                     else
1930                         strcpy(eosf, ".rtsp");
1931                 }
1932             }
1933
1934             url_fprintf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
1935                          sfilename, stream->filename);
1936             url_fprintf(pb, "<td align=right> %d <td align=right> ",
1937                         stream->conns_served);
1938             fmt_bytecount(pb, stream->bytes_served);
1939             switch(stream->stream_type) {
1940             case STREAM_TYPE_LIVE: {
1941                     int audio_bit_rate = 0;
1942                     int video_bit_rate = 0;
1943                     const char *audio_codec_name = "";
1944                     const char *video_codec_name = "";
1945                     const char *audio_codec_name_extra = "";
1946                     const char *video_codec_name_extra = "";
1947
1948                     for(i=0;i<stream->nb_streams;i++) {
1949                         AVStream *st = stream->streams[i];
1950                         AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
1951                         switch(st->codec->codec_type) {
1952                         case AVMEDIA_TYPE_AUDIO:
1953                             audio_bit_rate += st->codec->bit_rate;
1954                             if (codec) {
1955                                 if (*audio_codec_name)
1956                                     audio_codec_name_extra = "...";
1957                                 audio_codec_name = codec->name;
1958                             }
1959                             break;
1960                         case AVMEDIA_TYPE_VIDEO:
1961                             video_bit_rate += st->codec->bit_rate;
1962                             if (codec) {
1963                                 if (*video_codec_name)
1964                                     video_codec_name_extra = "...";
1965                                 video_codec_name = codec->name;
1966                             }
1967                             break;
1968                         case AVMEDIA_TYPE_DATA:
1969                             video_bit_rate += st->codec->bit_rate;
1970                             break;
1971                         default:
1972                             abort();
1973                         }
1974                     }
1975                     url_fprintf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
1976                                  stream->fmt->name,
1977                                  stream->bandwidth,
1978                                  video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
1979                                  audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
1980                     if (stream->feed)
1981                         url_fprintf(pb, "<td>%s", stream->feed->filename);
1982                     else
1983                         url_fprintf(pb, "<td>%s", stream->feed_filename);
1984                     url_fprintf(pb, "\n");
1985                 }
1986                 break;
1987             default:
1988                 url_fprintf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
1989                 break;
1990             }
1991         }
1992         stream = stream->next;
1993     }
1994     url_fprintf(pb, "</table>\n");
1995
1996     stream = first_stream;
1997     while (stream != NULL) {
1998         if (stream->feed == stream) {
1999             url_fprintf(pb, "<h2>Feed %s</h2>", stream->filename);
2000             if (stream->pid) {
2001                 url_fprintf(pb, "Running as pid %d.\n", stream->pid);
2002
2003 #if defined(linux) && !defined(CONFIG_NOCUTILS)
2004                 {
2005                     FILE *pid_stat;
2006                     char ps_cmd[64];
2007
2008                     /* This is somewhat linux specific I guess */
2009                     snprintf(ps_cmd, sizeof(ps_cmd),
2010                              "ps -o \"%%cpu,cputime\" --no-headers %d",
2011                              stream->pid);
2012
2013                     pid_stat = popen(ps_cmd, "r");
2014                     if (pid_stat) {
2015                         char cpuperc[10];
2016                         char cpuused[64];
2017
2018                         if (fscanf(pid_stat, "%10s %64s", cpuperc,
2019                                    cpuused) == 2) {
2020                             url_fprintf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
2021                                          cpuperc, cpuused);
2022                         }
2023                         fclose(pid_stat);
2024                     }
2025                 }
2026 #endif
2027
2028                 url_fprintf(pb, "<p>");
2029             }
2030             url_fprintf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
2031
2032             for (i = 0; i < stream->nb_streams; i++) {
2033                 AVStream *st = stream->streams[i];
2034                 AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
2035                 const char *type = "unknown";
2036                 char parameters[64];
2037
2038                 parameters[0] = 0;
2039
2040                 switch(st->codec->codec_type) {
2041                 case AVMEDIA_TYPE_AUDIO:
2042                     type = "audio";
2043                     snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
2044                     break;
2045                 case AVMEDIA_TYPE_VIDEO:
2046                     type = "video";
2047                     snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
2048                                 st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
2049                     break;
2050                 default:
2051                     abort();
2052                 }
2053                 url_fprintf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
2054                         i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
2055             }
2056             url_fprintf(pb, "</table>\n");
2057
2058         }
2059         stream = stream->next;
2060     }
2061
2062     /* connection status */
2063     url_fprintf(pb, "<h2>Connection Status</h2>\n");
2064
2065     url_fprintf(pb, "Number of connections: %d / %d<br>\n",
2066                  nb_connections, nb_max_connections);
2067
2068     url_fprintf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
2069                  current_bandwidth, max_bandwidth);
2070
2071     url_fprintf(pb, "<table>\n");
2072     url_fprintf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
2073     c1 = first_http_ctx;
2074     i = 0;
2075     while (c1 != NULL) {
2076         int bitrate;
2077         int j;
2078
2079         bitrate = 0;
2080         if (c1->stream) {
2081             for (j = 0; j < c1->stream->nb_streams; j++) {
2082                 if (!c1->stream->feed)
2083                     bitrate += c1->stream->streams[j]->codec->bit_rate;
2084                 else if (c1->feed_streams[j] >= 0)
2085                     bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
2086             }
2087         }
2088
2089         i++;
2090         p = inet_ntoa(c1->from_addr.sin_addr);
2091         url_fprintf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
2092                     i,
2093                     c1->stream ? c1->stream->filename : "",
2094                     c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
2095                     p,
2096                     c1->protocol,
2097                     http_state[c1->state]);
2098         fmt_bytecount(pb, bitrate);
2099         url_fprintf(pb, "<td align=right>");
2100         fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
2101         url_fprintf(pb, "<td align=right>");
2102         fmt_bytecount(pb, c1->data_count);
2103         url_fprintf(pb, "\n");
2104         c1 = c1->next;
2105     }
2106     url_fprintf(pb, "</table>\n");
2107
2108     /* date */
2109     ti = time(NULL);
2110     p = ctime(&ti);
2111     url_fprintf(pb, "<hr size=1 noshade>Generated at %s", p);
2112     url_fprintf(pb, "</body>\n</html>\n");
2113
2114     len = url_close_dyn_buf(pb, &c->pb_buffer);
2115     c->buffer_ptr = c->pb_buffer;
2116     c->buffer_end = c->pb_buffer + len;
2117 }
2118
2119 /* check if the parser needs to be opened for stream i */
2120 static void open_parser(AVFormatContext *s, int i)
2121 {
2122     AVStream *st = s->streams[i];
2123     AVCodec *codec;
2124
2125     if (!st->codec->codec) {
2126         codec = avcodec_find_decoder(st->codec->codec_id);
2127         if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) {
2128             st->codec->parse_only = 1;
2129             if (avcodec_open(st->codec, codec) < 0)
2130                 st->codec->parse_only = 0;
2131         }
2132     }
2133 }
2134
2135 static int open_input_stream(HTTPContext *c, const char *info)
2136 {
2137     char buf[128];
2138     char input_filename[1024];
2139     AVFormatContext *s;
2140     int buf_size, i, ret;
2141     int64_t stream_pos;
2142
2143     /* find file name */
2144     if (c->stream->feed) {
2145         strcpy(input_filename, c->stream->feed->feed_filename);
2146         buf_size = FFM_PACKET_SIZE;
2147         /* compute position (absolute time) */
2148         if (find_info_tag(buf, sizeof(buf), "date", info)) {
2149             stream_pos = parse_date(buf, 0);
2150             if (stream_pos == INT64_MIN)
2151                 return -1;
2152         } else if (find_info_tag(buf, sizeof(buf), "buffer", info)) {
2153             int prebuffer = strtol(buf, 0, 10);
2154             stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
2155         } else
2156             stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
2157     } else {
2158         strcpy(input_filename, c->stream->feed_filename);
2159         buf_size = 0;
2160         /* compute position (relative time) */
2161         if (find_info_tag(buf, sizeof(buf), "date", info)) {
2162             stream_pos = parse_date(buf, 1);
2163             if (stream_pos == INT64_MIN)
2164                 return -1;
2165         } else
2166             stream_pos = 0;
2167     }
2168     if (input_filename[0] == '\0')
2169         return -1;
2170
2171     /* open stream */
2172     if ((ret = av_open_input_file(&s, input_filename, c->stream->ifmt,
2173                                   buf_size, c->stream->ap_in)) < 0) {
2174         http_log("could not open %s: %d\n", input_filename, ret);
2175         return -1;
2176     }
2177     s->flags |= AVFMT_FLAG_GENPTS;
2178     c->fmt_in = s;
2179     if (strcmp(s->iformat->name, "ffm") && av_find_stream_info(c->fmt_in) < 0) {
2180         http_log("Could not find stream info '%s'\n", input_filename);
2181         av_close_input_file(s);
2182         return -1;
2183     }
2184
2185     /* open each parser */
2186     for(i=0;i<s->nb_streams;i++)
2187         open_parser(s, i);
2188
2189     /* choose stream as clock source (we favorize video stream if
2190        present) for packet sending */
2191     c->pts_stream_index = 0;
2192     for(i=0;i<c->stream->nb_streams;i++) {
2193         if (c->pts_stream_index == 0 &&
2194             c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
2195             c->pts_stream_index = i;
2196         }
2197     }
2198
2199 #if 1
2200     if (c->fmt_in->iformat->read_seek)
2201         av_seek_frame(c->fmt_in, -1, stream_pos, 0);
2202 #endif
2203     /* set the start time (needed for maxtime and RTP packet timing) */
2204     c->start_time = cur_time;
2205     c->first_pts = AV_NOPTS_VALUE;
2206     return 0;
2207 }
2208
2209 /* return the server clock (in us) */
2210 static int64_t get_server_clock(HTTPContext *c)
2211 {
2212     /* compute current pts value from system time */
2213     return (cur_time - c->start_time) * 1000;
2214 }
2215
2216 /* return the estimated time at which the current packet must be sent
2217    (in us) */
2218 static int64_t get_packet_send_clock(HTTPContext *c)
2219 {
2220     int bytes_left, bytes_sent, frame_bytes;
2221
2222     frame_bytes = c->cur_frame_bytes;
2223     if (frame_bytes <= 0)
2224         return c->cur_pts;
2225     else {
2226         bytes_left = c->buffer_end - c->buffer_ptr;
2227         bytes_sent = frame_bytes - bytes_left;
2228         return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
2229     }
2230 }
2231
2232
2233 static int http_prepare_data(HTTPContext *c)
2234 {
2235     int i, len, ret;
2236     AVFormatContext *ctx;
2237
2238     av_freep(&c->pb_buffer);
2239     switch(c->state) {
2240     case HTTPSTATE_SEND_DATA_HEADER:
2241         memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
2242         av_metadata_set2(&c->fmt_ctx.metadata, "author"   , c->stream->author   , 0);
2243         av_metadata_set2(&c->fmt_ctx.metadata, "comment"  , c->stream->comment  , 0);
2244         av_metadata_set2(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
2245         av_metadata_set2(&c->fmt_ctx.metadata, "title"    , c->stream->title    , 0);
2246
2247         for(i=0;i<c->stream->nb_streams;i++) {
2248             AVStream *st;
2249             AVStream *src;
2250             st = av_mallocz(sizeof(AVStream));
2251             c->fmt_ctx.streams[i] = st;
2252             /* if file or feed, then just take streams from FFStream struct */
2253             if (!c->stream->feed ||
2254                 c->stream->feed == c->stream)
2255                 src = c->stream->streams[i];
2256             else
2257                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2258
2259             *st = *src;
2260             st->priv_data = 0;
2261             st->codec->frame_number = 0; /* XXX: should be done in
2262                                            AVStream, not in codec */
2263         }
2264         /* set output format parameters */
2265         c->fmt_ctx.oformat = c->stream->fmt;
2266         c->fmt_ctx.nb_streams = c->stream->nb_streams;
2267
2268         c->got_key_frame = 0;
2269
2270         /* prepare header and save header data in a stream */
2271         if (url_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2272             /* XXX: potential leak */
2273             return -1;
2274         }
2275         c->fmt_ctx.pb->is_streamed = 1;
2276
2277         /*
2278          * HACK to avoid mpeg ps muxer to spit many underflow errors
2279          * Default value from FFmpeg
2280          * Try to set it use configuration option
2281          */
2282         c->fmt_ctx.preload   = (int)(0.5*AV_TIME_BASE);
2283         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2284
2285         av_set_parameters(&c->fmt_ctx, NULL);
2286         if (av_write_header(&c->fmt_ctx) < 0) {
2287             http_log("Error writing output header\n");
2288             return -1;
2289         }
2290         av_metadata_free(&c->fmt_ctx.metadata);
2291
2292         len = url_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2293         c->buffer_ptr = c->pb_buffer;
2294         c->buffer_end = c->pb_buffer + len;
2295
2296         c->state = HTTPSTATE_SEND_DATA;
2297         c->last_packet_sent = 0;
2298         break;
2299     case HTTPSTATE_SEND_DATA:
2300         /* find a new packet */
2301         /* read a packet from the input stream */
2302         if (c->stream->feed)
2303             ffm_set_write_index(c->fmt_in,
2304                                 c->stream->feed->feed_write_index,
2305                                 c->stream->feed->feed_size);
2306
2307         if (c->stream->max_time &&
2308             c->stream->max_time + c->start_time - cur_time < 0)
2309             /* We have timed out */
2310             c->state = HTTPSTATE_SEND_DATA_TRAILER;
2311         else {
2312             AVPacket pkt;
2313         redo:
2314             ret = av_read_frame(c->fmt_in, &pkt);
2315             if (ret < 0) {
2316                 if (c->stream->feed) {
2317                     /* if coming from feed, it means we reached the end of the
2318                        ffm file, so must wait for more data */
2319                     c->state = HTTPSTATE_WAIT_FEED;
2320                     return 1; /* state changed */
2321                 } else if (ret == AVERROR(EAGAIN)) {
2322                     /* input not ready, come back later */
2323                     return 0;
2324                 } else {
2325                     if (c->stream->loop) {
2326                         av_close_input_file(c->fmt_in);
2327                         c->fmt_in = NULL;
2328                         if (open_input_stream(c, "") < 0)
2329                             goto no_loop;
2330                         goto redo;
2331                     } else {
2332                     no_loop:
2333                         /* must send trailer now because eof or error */
2334                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2335                     }
2336                 }
2337             } else {
2338                 int source_index = pkt.stream_index;
2339                 /* update first pts if needed */
2340                 if (c->first_pts == AV_NOPTS_VALUE) {
2341                     c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
2342                     c->start_time = cur_time;
2343                 }
2344                 /* send it to the appropriate stream */
2345                 if (c->stream->feed) {
2346                     /* if coming from a feed, select the right stream */
2347                     if (c->switch_pending) {
2348                         c->switch_pending = 0;
2349                         for(i=0;i<c->stream->nb_streams;i++) {
2350                             if (c->switch_feed_streams[i] == pkt.stream_index)
2351                                 if (pkt.flags & AV_PKT_FLAG_KEY)
2352                                     do_switch_stream(c, i);
2353                             if (c->switch_feed_streams[i] >= 0)
2354                                 c->switch_pending = 1;
2355                         }
2356                     }
2357                     for(i=0;i<c->stream->nb_streams;i++) {
2358                         if (c->stream->feed_streams[i] == pkt.stream_index) {
2359                             AVStream *st = c->fmt_in->streams[source_index];
2360                             pkt.stream_index = i;
2361                             if (pkt.flags & AV_PKT_FLAG_KEY &&
2362                                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
2363                                  c->stream->nb_streams == 1))
2364                                 c->got_key_frame = 1;
2365                             if (!c->stream->send_on_key || c->got_key_frame)
2366                                 goto send_it;
2367                         }
2368                     }
2369                 } else {
2370                     AVCodecContext *codec;
2371                     AVStream *ist, *ost;
2372                 send_it:
2373                     ist = c->fmt_in->streams[source_index];
2374                     /* specific handling for RTP: we use several
2375                        output stream (one for each RTP
2376                        connection). XXX: need more abstract handling */
2377                     if (c->is_packetized) {
2378                         /* compute send time and duration */
2379                         c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
2380                         c->cur_pts -= c->first_pts;
2381                         c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
2382                         /* find RTP context */
2383                         c->packet_stream_index = pkt.stream_index;
2384                         ctx = c->rtp_ctx[c->packet_stream_index];
2385                         if(!ctx) {
2386                             av_free_packet(&pkt);
2387                             break;
2388                         }
2389                         codec = ctx->streams[0]->codec;
2390                         /* only one stream per RTP connection */
2391                         pkt.stream_index = 0;
2392                     } else {
2393                         ctx = &c->fmt_ctx;
2394                         /* Fudge here */
2395                         codec = ctx->streams[pkt.stream_index]->codec;
2396                     }
2397
2398                     if (c->is_packetized) {
2399                         int max_packet_size;
2400                         if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
2401                             max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
2402                         else
2403                             max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]);
2404                         ret = url_open_dyn_packet_buf(&ctx->pb, max_packet_size);
2405                     } else {
2406                         ret = url_open_dyn_buf(&ctx->pb);
2407                     }
2408                     if (ret < 0) {
2409                         /* XXX: potential leak */
2410                         return -1;
2411                     }
2412                     ost = ctx->streams[pkt.stream_index];
2413
2414                     ctx->pb->is_streamed = 1;
2415                     if (pkt.dts != AV_NOPTS_VALUE)
2416                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
2417                     if (pkt.pts != AV_NOPTS_VALUE)
2418                         pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
2419                     pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
2420                     if (av_write_frame(ctx, &pkt) < 0) {
2421                         http_log("Error writing frame to output\n");
2422                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2423                     }
2424
2425                     len = url_close_dyn_buf(ctx->pb, &c->pb_buffer);
2426                     c->cur_frame_bytes = len;
2427                     c->buffer_ptr = c->pb_buffer;
2428                     c->buffer_end = c->pb_buffer + len;
2429
2430                     codec->frame_number++;
2431                     if (len == 0) {
2432                         av_free_packet(&pkt);
2433                         goto redo;
2434                     }
2435                 }
2436                 av_free_packet(&pkt);
2437             }
2438         }
2439         break;
2440     default:
2441     case HTTPSTATE_SEND_DATA_TRAILER:
2442         /* last packet test ? */
2443         if (c->last_packet_sent || c->is_packetized)
2444             return -1;
2445         ctx = &c->fmt_ctx;
2446         /* prepare header */
2447         if (url_open_dyn_buf(&ctx->pb) < 0) {
2448             /* XXX: potential leak */
2449             return -1;
2450         }
2451         c->fmt_ctx.pb->is_streamed = 1;
2452         av_write_trailer(ctx);
2453         len = url_close_dyn_buf(ctx->pb, &c->pb_buffer);
2454         c->buffer_ptr = c->pb_buffer;
2455         c->buffer_end = c->pb_buffer + len;
2456
2457         c->last_packet_sent = 1;
2458         break;
2459     }
2460     return 0;
2461 }
2462
2463 /* should convert the format at the same time */
2464 /* send data starting at c->buffer_ptr to the output connection
2465    (either UDP or TCP connection) */
2466 static int http_send_data(HTTPContext *c)
2467 {
2468     int len, ret;
2469
2470     for(;;) {
2471         if (c->buffer_ptr >= c->buffer_end) {
2472             ret = http_prepare_data(c);
2473             if (ret < 0)
2474                 return -1;
2475             else if (ret != 0)
2476                 /* state change requested */
2477                 break;
2478         } else {
2479             if (c->is_packetized) {
2480                 /* RTP data output */
2481                 len = c->buffer_end - c->buffer_ptr;
2482                 if (len < 4) {
2483                     /* fail safe - should never happen */
2484                 fail1:
2485                     c->buffer_ptr = c->buffer_end;
2486                     return 0;
2487                 }
2488                 len = (c->buffer_ptr[0] << 24) |
2489                     (c->buffer_ptr[1] << 16) |
2490                     (c->buffer_ptr[2] << 8) |
2491                     (c->buffer_ptr[3]);
2492                 if (len > (c->buffer_end - c->buffer_ptr))
2493                     goto fail1;
2494                 if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
2495                     /* nothing to send yet: we can wait */
2496                     return 0;
2497                 }
2498
2499                 c->data_count += len;
2500                 update_datarate(&c->datarate, c->data_count);
2501                 if (c->stream)
2502                     c->stream->bytes_served += len;
2503
2504                 if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
2505                     /* RTP packets are sent inside the RTSP TCP connection */
2506                     ByteIOContext *pb;
2507                     int interleaved_index, size;
2508                     uint8_t header[4];
2509                     HTTPContext *rtsp_c;
2510
2511                     rtsp_c = c->rtsp_c;
2512                     /* if no RTSP connection left, error */
2513                     if (!rtsp_c)
2514                         return -1;
2515                     /* if already sending something, then wait. */
2516                     if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
2517                         break;
2518                     if (url_open_dyn_buf(&pb) < 0)
2519                         goto fail1;
2520                     interleaved_index = c->packet_stream_index * 2;
2521                     /* RTCP packets are sent at odd indexes */
2522                     if (c->buffer_ptr[1] == 200)
2523                         interleaved_index++;
2524                     /* write RTSP TCP header */
2525                     header[0] = '$';
2526                     header[1] = interleaved_index;
2527                     header[2] = len >> 8;
2528                     header[3] = len;
2529                     put_buffer(pb, header, 4);
2530                     /* write RTP packet data */
2531                     c->buffer_ptr += 4;
2532                     put_buffer(pb, c->buffer_ptr, len);
2533                     size = url_close_dyn_buf(pb, &c->packet_buffer);
2534                     /* prepare asynchronous TCP sending */
2535                     rtsp_c->packet_buffer_ptr = c->packet_buffer;
2536                     rtsp_c->packet_buffer_end = c->packet_buffer + size;
2537                     c->buffer_ptr += len;
2538
2539                     /* send everything we can NOW */
2540                     len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
2541                                 rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
2542                     if (len > 0)
2543                         rtsp_c->packet_buffer_ptr += len;
2544                     if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
2545                         /* if we could not send all the data, we will
2546                            send it later, so a new state is needed to
2547                            "lock" the RTSP TCP connection */
2548                         rtsp_c->state = RTSPSTATE_SEND_PACKET;
2549                         break;
2550                     } else
2551                         /* all data has been sent */
2552                         av_freep(&c->packet_buffer);
2553                 } else {
2554                     /* send RTP packet directly in UDP */
2555                     c->buffer_ptr += 4;
2556                     url_write(c->rtp_handles[c->packet_stream_index],
2557                               c->buffer_ptr, len);
2558                     c->buffer_ptr += len;
2559                     /* here we continue as we can send several packets per 10 ms slot */
2560                 }
2561             } else {
2562                 /* TCP data output */
2563                 len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
2564                 if (len < 0) {
2565                     if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
2566                         ff_neterrno() != FF_NETERROR(EINTR))
2567                         /* error : close connection */
2568                         return -1;
2569                     else
2570                         return 0;
2571                 } else
2572                     c->buffer_ptr += len;
2573
2574                 c->data_count += len;
2575                 update_datarate(&c->datarate, c->data_count);
2576                 if (c->stream)
2577                     c->stream->bytes_served += len;
2578                 break;
2579             }
2580         }
2581     } /* for(;;) */
2582     return 0;
2583 }
2584
2585 static int http_start_receive_data(HTTPContext *c)
2586 {
2587     int fd;
2588
2589     if (c->stream->feed_opened)
2590         return -1;
2591
2592     /* Don't permit writing to this one */
2593     if (c->stream->readonly)
2594         return -1;
2595
2596     /* open feed */
2597     fd = open(c->stream->feed_filename, O_RDWR);
2598     if (fd < 0) {
2599         http_log("Error opening feeder file: %s\n", strerror(errno));
2600         return -1;
2601     }
2602     c->feed_fd = fd;
2603
2604     if (c->stream->truncate) {
2605         /* truncate feed file */
2606         ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
2607         ftruncate(c->feed_fd, FFM_PACKET_SIZE);
2608         http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
2609     } else {
2610         if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
2611             http_log("Error reading write index from feed file: %s\n", strerror(errno));
2612             return -1;
2613         }
2614     }
2615
2616     c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
2617     c->stream->feed_size = lseek(fd, 0, SEEK_END);
2618     lseek(fd, 0, SEEK_SET);
2619
2620     /* init buffer input */
2621     c->buffer_ptr = c->buffer;
2622     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2623     c->stream->feed_opened = 1;
2624     c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2625     return 0;
2626 }
2627
2628 static int http_receive_data(HTTPContext *c)
2629 {
2630     HTTPContext *c1;
2631     int len, loop_run = 0;
2632
2633     while (c->chunked_encoding && !c->chunk_size &&
2634            c->buffer_end > c->buffer_ptr) {
2635         /* read chunk header, if present */
2636         len = recv(c->fd, c->buffer_ptr, 1, 0);
2637
2638         if (len < 0) {
2639             if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
2640                 ff_neterrno() != FF_NETERROR(EINTR))
2641                 /* error : close connection */
2642                 goto fail;
2643             return 0;
2644         } else if (len == 0) {
2645             /* end of connection : close it */
2646             goto fail;
2647         } else if (c->buffer_ptr - c->buffer >= 2 &&
2648                    !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2649             c->chunk_size = strtol(c->buffer, 0, 16);
2650             if (c->chunk_size == 0) // end of stream
2651                 goto fail;
2652             c->buffer_ptr = c->buffer;
2653             break;
2654         } else if (++loop_run > 10) {
2655             /* no chunk header, abort */
2656             goto fail;
2657         } else {
2658             c->buffer_ptr++;
2659         }
2660     }
2661
2662     if (c->buffer_end > c->buffer_ptr) {
2663         len = recv(c->fd, c->buffer_ptr,
2664                    FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2665         if (len < 0) {
2666             if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
2667                 ff_neterrno() != FF_NETERROR(EINTR))
2668                 /* error : close connection */
2669                 goto fail;
2670         } else if (len == 0)
2671             /* end of connection : close it */
2672             goto fail;
2673         else {
2674             c->chunk_size -= len;
2675             c->buffer_ptr += len;
2676             c->data_count += len;
2677             update_datarate(&c->datarate, c->data_count);
2678         }
2679     }
2680
2681     if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2682         if (c->buffer[0] != 'f' ||
2683             c->buffer[1] != 'm') {
2684             http_log("Feed stream has become desynchronized -- disconnecting\n");
2685             goto fail;
2686         }
2687     }
2688
2689     if (c->buffer_ptr >= c->buffer_end) {
2690         FFStream *feed = c->stream;
2691         /* a packet has been received : write it in the store, except
2692            if header */
2693         if (c->data_count > FFM_PACKET_SIZE) {
2694
2695             //            printf("writing pos=0x%"PRIx64" size=0x%"PRIx64"\n", feed->feed_write_index, feed->feed_size);
2696             /* XXX: use llseek or url_seek */
2697             lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
2698             if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
2699                 http_log("Error writing to feed file: %s\n", strerror(errno));
2700                 goto fail;
2701             }
2702
2703             feed->feed_write_index += FFM_PACKET_SIZE;
2704             /* update file size */
2705             if (feed->feed_write_index > c->stream->feed_size)
2706                 feed->feed_size = feed->feed_write_index;
2707
2708             /* handle wrap around if max file size reached */
2709             if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
2710                 feed->feed_write_index = FFM_PACKET_SIZE;
2711
2712             /* write index */
2713             if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
2714                 http_log("Error writing index to feed file: %s\n", strerror(errno));
2715                 goto fail;
2716             }
2717
2718             /* wake up any waiting connections */
2719             for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2720                 if (c1->state == HTTPSTATE_WAIT_FEED &&
2721                     c1->stream->feed == c->stream->feed)
2722                     c1->state = HTTPSTATE_SEND_DATA;
2723             }
2724         } else {
2725             /* We have a header in our hands that contains useful data */
2726             AVFormatContext *s = NULL;
2727             ByteIOContext *pb;
2728             AVInputFormat *fmt_in;
2729             int i;
2730
2731             /* use feed output format name to find corresponding input format */
2732             fmt_in = av_find_input_format(feed->fmt->name);
2733             if (!fmt_in)
2734                 goto fail;
2735
2736             url_open_buf(&pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY);
2737             pb->is_streamed = 1;
2738
2739             if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) {
2740                 av_free(pb);
2741                 goto fail;
2742             }
2743
2744             /* Now we have the actual streams */
2745             if (s->nb_streams != feed->nb_streams) {
2746                 av_close_input_stream(s);
2747                 av_free(pb);
2748                 http_log("Feed '%s' stream number does not match registered feed\n",
2749                          c->stream->feed_filename);
2750                 goto fail;
2751             }
2752
2753             for (i = 0; i < s->nb_streams; i++) {
2754                 AVStream *fst = feed->streams[i];
2755                 AVStream *st = s->streams[i];
2756                 avcodec_copy_context(fst->codec, st->codec);
2757             }
2758
2759             av_close_input_stream(s);
2760             av_free(pb);
2761         }
2762         c->buffer_ptr = c->buffer;
2763     }
2764
2765     return 0;
2766  fail:
2767     c->stream->feed_opened = 0;
2768     close(c->feed_fd);
2769     /* wake up any waiting connections to stop waiting for feed */
2770     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2771         if (c1->state == HTTPSTATE_WAIT_FEED &&
2772             c1->stream->feed == c->stream->feed)
2773             c1->state = HTTPSTATE_SEND_DATA_TRAILER;
2774     }
2775     return -1;
2776 }
2777
2778 /********************************************************************/
2779 /* RTSP handling */
2780
2781 static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
2782 {
2783     const char *str;
2784     time_t ti;
2785     struct tm *tm;
2786     char buf2[32];
2787
2788     switch(error_number) {
2789     case RTSP_STATUS_OK:
2790         str = "OK";
2791         break;
2792     case RTSP_STATUS_METHOD:
2793         str = "Method Not Allowed";
2794         break;
2795     case RTSP_STATUS_BANDWIDTH:
2796         str = "Not Enough Bandwidth";
2797         break;
2798     case RTSP_STATUS_SESSION:
2799         str = "Session Not Found";
2800         break;
2801     case RTSP_STATUS_STATE:
2802         str = "Method Not Valid in This State";
2803         break;
2804     case RTSP_STATUS_AGGREGATE:
2805         str = "Aggregate operation not allowed";
2806         break;
2807     case RTSP_STATUS_ONLY_AGGREGATE:
2808         str = "Only aggregate operation allowed";
2809         break;
2810     case RTSP_STATUS_TRANSPORT:
2811         str = "Unsupported transport";
2812         break;
2813     case RTSP_STATUS_INTERNAL:
2814         str = "Internal Server Error";
2815         break;
2816     case RTSP_STATUS_SERVICE:
2817         str = "Service Unavailable";
2818         break;
2819     case RTSP_STATUS_VERSION:
2820         str = "RTSP Version not supported";
2821         break;
2822     default:
2823         str = "Unknown Error";
2824         break;
2825     }
2826
2827     url_fprintf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
2828     url_fprintf(c->pb, "CSeq: %d\r\n", c->seq);
2829
2830     /* output GMT time */
2831     ti = time(NULL);
2832     tm = gmtime(&ti);
2833     strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
2834     url_fprintf(c->pb, "Date: %s GMT\r\n", buf2);
2835 }
2836
2837 static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
2838 {
2839     rtsp_reply_header(c, error_number);
2840     url_fprintf(c->pb, "\r\n");
2841 }
2842
2843 static int rtsp_parse_request(HTTPContext *c)
2844 {
2845     const char *p, *p1, *p2;
2846     char cmd[32];
2847     char url[1024];
2848     char protocol[32];
2849     char line[1024];
2850     int len;
2851     RTSPMessageHeader header1, *header = &header1;
2852
2853     c->buffer_ptr[0] = '\0';
2854     p = c->buffer;
2855
2856     get_word(cmd, sizeof(cmd), &p);
2857     get_word(url, sizeof(url), &p);
2858     get_word(protocol, sizeof(protocol), &p);
2859
2860     av_strlcpy(c->method, cmd, sizeof(c->method));
2861     av_strlcpy(c->url, url, sizeof(c->url));
2862     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
2863
2864     if (url_open_dyn_buf(&c->pb) < 0) {
2865         /* XXX: cannot do more */
2866         c->pb = NULL; /* safety */
2867         return -1;
2868     }
2869
2870     /* check version name */
2871     if (strcmp(protocol, "RTSP/1.0") != 0) {
2872         rtsp_reply_error(c, RTSP_STATUS_VERSION);
2873         goto the_end;
2874     }
2875
2876     /* parse each header line */
2877     memset(header, 0, sizeof(*header));
2878     /* skip to next line */
2879     while (*p != '\n' && *p != '\0')
2880         p++;
2881     if (*p == '\n')
2882         p++;
2883     while (*p != '\0') {
2884         p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
2885         if (!p1)