00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #ifndef HAVE_CLOSESOCKET
00024 #define closesocket close
00025 #endif
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include "libavutil/random.h"
00029 #include "libavutil/avstring.h"
00030 #include "libavformat/avformat.h"
00031 #include "libavformat/network.h"
00032 #include "libavformat/os_support.h"
00033 #include "libavformat/rtp.h"
00034 #include "libavformat/rtsp.h"
00035 #include "libavcodec/opt.h"
00036 #include <stdarg.h>
00037 #include <unistd.h>
00038 #include <fcntl.h>
00039 #include <sys/ioctl.h>
00040 #ifdef HAVE_POLL_H
00041 #include <poll.h>
00042 #endif
00043 #include <errno.h>
00044 #include <sys/time.h>
00045 #undef time //needed because HAVE_AV_CONFIG_H is defined on top
00046 #include <time.h>
00047 #include <sys/wait.h>
00048 #include <signal.h>
00049 #ifdef HAVE_DLFCN_H
00050 #include <dlfcn.h>
00051 #endif
00052
00053 #include "cmdutils.h"
00054
00055 #undef exit
00056
00057 const char program_name[] = "FFserver";
00058 const int program_birth_year = 2000;
00059
00060 static const OptionDef options[];
00061
00062
00063 #define HTTP_MAX_CONNECTIONS 2000
00064
00065 enum HTTPState {
00066 HTTPSTATE_WAIT_REQUEST,
00067 HTTPSTATE_SEND_HEADER,
00068 HTTPSTATE_SEND_DATA_HEADER,
00069 HTTPSTATE_SEND_DATA,
00070 HTTPSTATE_SEND_DATA_TRAILER,
00071 HTTPSTATE_RECEIVE_DATA,
00072 HTTPSTATE_WAIT_FEED,
00073 HTTPSTATE_READY,
00074
00075 RTSPSTATE_WAIT_REQUEST,
00076 RTSPSTATE_SEND_REPLY,
00077 RTSPSTATE_SEND_PACKET,
00078 };
00079
00080 static const char *http_state[] = {
00081 "HTTP_WAIT_REQUEST",
00082 "HTTP_SEND_HEADER",
00083
00084 "SEND_DATA_HEADER",
00085 "SEND_DATA",
00086 "SEND_DATA_TRAILER",
00087 "RECEIVE_DATA",
00088 "WAIT_FEED",
00089 "READY",
00090
00091 "RTSP_WAIT_REQUEST",
00092 "RTSP_SEND_REPLY",
00093 "RTSP_SEND_PACKET",
00094 };
00095
00096 #define IOBUFFER_INIT_SIZE 8192
00097
00098
00099 #define HTTP_REQUEST_TIMEOUT (15 * 1000)
00100 #define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
00101
00102 #define SYNC_TIMEOUT (10 * 1000)
00103
00104 typedef struct {
00105 int64_t count1, count2;
00106 int64_t time1, time2;
00107 } DataRateData;
00108
00109
00110 typedef struct HTTPContext {
00111 enum HTTPState state;
00112 int fd;
00113 struct sockaddr_in from_addr;
00114 struct pollfd *poll_entry;
00115 int64_t timeout;
00116 uint8_t *buffer_ptr, *buffer_end;
00117 int http_error;
00118 int post;
00119 struct HTTPContext *next;
00120 int got_key_frame;
00121 int64_t data_count;
00122
00123 int feed_fd;
00124
00125 AVFormatContext *fmt_in;
00126 int64_t start_time;
00127 int64_t first_pts;
00128 int64_t cur_pts;
00129 int64_t cur_frame_duration;
00130 int cur_frame_bytes;
00131
00132
00133 int pts_stream_index;
00134 int64_t cur_clock;
00135
00136 struct FFStream *stream;
00137
00138 int feed_streams[MAX_STREAMS];
00139 int switch_feed_streams[MAX_STREAMS];
00140 int switch_pending;
00141 AVFormatContext fmt_ctx;
00142 int last_packet_sent;
00143 int suppress_log;
00144 DataRateData datarate;
00145 int wmp_client_id;
00146 char protocol[16];
00147 char method[16];
00148 char url[128];
00149 int buffer_size;
00150 uint8_t *buffer;
00151 int is_packetized;
00152 int packet_stream_index;
00153
00154
00155 uint8_t *pb_buffer;
00156 ByteIOContext *pb;
00157 int seq;
00158
00159
00160 enum RTSPProtocol rtp_protocol;
00161 char session_id[32];
00162 AVFormatContext *rtp_ctx[MAX_STREAMS];
00163
00164
00165 URLContext *rtp_handles[MAX_STREAMS];
00166
00167
00168 struct HTTPContext *rtsp_c;
00169 uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
00170 } HTTPContext;
00171
00172
00173 enum StreamType {
00174 STREAM_TYPE_LIVE,
00175 STREAM_TYPE_STATUS,
00176 STREAM_TYPE_REDIRECT,
00177 };
00178
00179 enum IPAddressAction {
00180 IP_ALLOW = 1,
00181 IP_DENY,
00182 };
00183
00184 typedef struct IPAddressACL {
00185 struct IPAddressACL *next;
00186 enum IPAddressAction action;
00187
00188 struct in_addr first;
00189 struct in_addr last;
00190 } IPAddressACL;
00191
00192
00193 typedef struct FFStream {
00194 enum StreamType stream_type;
00195 char filename[1024];
00196 struct FFStream *feed;
00197
00198 AVFormatParameters *ap_in;
00199 AVInputFormat *ifmt;
00200 AVOutputFormat *fmt;
00201 IPAddressACL *acl;
00202 int nb_streams;
00203 int prebuffer;
00204 int64_t max_time;
00205 int send_on_key;
00206 AVStream *streams[MAX_STREAMS];
00207 int feed_streams[MAX_STREAMS];
00208 char feed_filename[1024];
00209
00210 char author[512];
00211 char title[512];
00212 char copyright[512];
00213 char comment[512];
00214 pid_t pid;
00215 time_t pid_start;
00216 char **child_argv;
00217 struct FFStream *next;
00218 unsigned bandwidth;
00219
00220 char *rtsp_option;
00221
00222 int is_multicast;
00223 struct in_addr multicast_ip;
00224 int multicast_port;
00225 int multicast_ttl;
00226 int loop;
00227
00228
00229 int feed_opened;
00230 int is_feed;
00231 int readonly;
00232 int conns_served;
00233 int64_t bytes_served;
00234 int64_t feed_max_size;
00235 int64_t feed_write_index;
00236 int64_t feed_size;
00237 struct FFStream *next_feed;
00238 } FFStream;
00239
00240 typedef struct FeedData {
00241 long long data_count;
00242 float avg_frame_size;
00243 } FeedData;
00244
00245 static struct sockaddr_in my_http_addr;
00246 static struct sockaddr_in my_rtsp_addr;
00247
00248 static char logfilename[1024];
00249 static HTTPContext *first_http_ctx;
00250 static FFStream *first_feed;
00251 static FFStream *first_stream;
00252
00253 static void new_connection(int server_fd, int is_rtsp);
00254 static void close_connection(HTTPContext *c);
00255
00256
00257 static int handle_connection(HTTPContext *c);
00258 static int http_parse_request(HTTPContext *c);
00259 static int http_send_data(HTTPContext *c);
00260 static void compute_status(HTTPContext *c);
00261 static int open_input_stream(HTTPContext *c, const char *info);
00262 static int http_start_receive_data(HTTPContext *c);
00263 static int http_receive_data(HTTPContext *c);
00264
00265
00266 static int rtsp_parse_request(HTTPContext *c);
00267 static void rtsp_cmd_describe(HTTPContext *c, const char *url);
00268 static void rtsp_cmd_options(HTTPContext *c, const char *url);
00269 static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPHeader *h);
00270 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPHeader *h);
00271 static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h);
00272 static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPHeader *h);
00273
00274
00275 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
00276 struct in_addr my_ip);
00277
00278
00279 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
00280 FFStream *stream, const char *session_id,
00281 enum RTSPProtocol rtp_protocol);
00282 static int rtp_new_av_stream(HTTPContext *c,
00283 int stream_index, struct sockaddr_in *dest_addr,
00284 HTTPContext *rtsp_c);
00285
00286 static const char *my_program_name;
00287 static const char *my_program_dir;
00288
00289 static const char *config_filename;
00290 static int ffserver_debug;
00291 static int ffserver_daemon;
00292 static int no_launch;
00293 static int need_to_start_children;
00294
00295 static int nb_max_connections = 5;
00296 static int nb_connections;
00297
00298 static uint64_t max_bandwidth = 1000;
00299 static uint64_t current_bandwidth;
00300
00301 static int64_t cur_time;
00302
00303 static AVRandomState random_state;
00304
00305 static FILE *logfile = NULL;
00306
00307 static char *ctime1(char *buf2)
00308 {
00309 time_t ti;
00310 char *p;
00311
00312 ti = time(NULL);
00313 p = ctime(&ti);
00314 strcpy(buf2, p);
00315 p = buf2 + strlen(p) - 1;
00316 if (*p == '\n')
00317 *p = '\0';
00318 return buf2;
00319 }
00320
00321 static void http_vlog(const char *fmt, va_list vargs)
00322 {
00323 static int print_prefix = 1;
00324 if (logfile) {
00325 if (print_prefix) {
00326 char buf[32];
00327 ctime1(buf);
00328 fprintf(logfile, "%s ", buf);
00329 }
00330 print_prefix = strstr(fmt, "\n") != NULL;
00331 vfprintf(logfile, fmt, vargs);
00332 fflush(logfile);
00333 }
00334 }
00335
00336 void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...)
00337 {
00338 va_list vargs;
00339 va_start(vargs, fmt);
00340 http_vlog(fmt, vargs);
00341 va_end(vargs);
00342 }
00343
00344 static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs)
00345 {
00346 static int print_prefix = 1;
00347 AVClass *avc = ptr ? *(AVClass**)ptr : NULL;
00348 if (level > av_log_level)
00349 return;
00350 if (print_prefix && avc)
00351 http_log("[%s @ %p]", avc->item_name(ptr), ptr);
00352 print_prefix = strstr(fmt, "\n") != NULL;
00353 http_vlog(fmt, vargs);
00354 }
00355
00356 static void log_connection(HTTPContext *c)
00357 {
00358 if (c->suppress_log)
00359 return;
00360
00361 http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n",
00362 inet_ntoa(c->from_addr.sin_addr), c->method, c->url,
00363 c->protocol, (c->http_error ? c->http_error : 200), c->data_count);
00364 }
00365
00366 static void update_datarate(DataRateData *drd, int64_t count)
00367 {
00368 if (!drd->time1 && !drd->count1) {
00369 drd->time1 = drd->time2 = cur_time;
00370 drd->count1 = drd->count2 = count;
00371 } else if (cur_time - drd->time2 > 5000) {
00372 drd->time1 = drd->time2;
00373 drd->count1 = drd->count2;
00374 drd->time2 = cur_time;
00375 drd->count2 = count;
00376 }
00377 }
00378
00379
00380 static int compute_datarate(DataRateData *drd, int64_t count)
00381 {
00382 if (cur_time == drd->time1)
00383 return 0;
00384
00385 return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
00386 }
00387
00388
00389 static void start_children(FFStream *feed)
00390 {
00391 if (no_launch)
00392 return;
00393
00394 for (; feed; feed = feed->next) {
00395 if (feed->child_argv && !feed->pid) {
00396 feed->pid_start = time(0);
00397
00398 feed->pid = fork();
00399
00400 if (feed->pid < 0) {
00401 http_log("Unable to create children\n");
00402 exit(1);
00403 }
00404 if (!feed->pid) {
00405
00406 char pathname[1024];
00407 char *slash;
00408 int i;
00409
00410 av_strlcpy(pathname, my_program_name, sizeof(pathname));
00411
00412 slash = strrchr(pathname, '/');
00413 if (!slash)
00414 slash = pathname;
00415 else
00416 slash++;
00417 strcpy(slash, "ffmpeg");
00418
00419 http_log("Launch commandline: ");
00420 http_log("%s ", pathname);
00421 for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++)
00422 http_log("%s ", feed->child_argv[i]);
00423 http_log("\n");
00424
00425 for (i = 3; i < 256; i++)
00426 close(i);
00427
00428 if (!ffserver_debug) {
00429 i = open("/dev/null", O_RDWR);
00430 if (i != -1) {
00431 dup2(i, 0);
00432 dup2(i, 1);
00433 dup2(i, 2);
00434 close(i);
00435 }
00436 }
00437
00438
00439 chdir(my_program_dir);
00440
00441 signal(SIGPIPE, SIG_DFL);
00442
00443 execvp(pathname, feed->child_argv);
00444
00445 _exit(1);
00446 }
00447 }
00448 }
00449 }
00450
00451
00452 static int socket_open_listen(struct sockaddr_in *my_addr)
00453 {
00454 int server_fd, tmp;
00455
00456 server_fd = socket(AF_INET,SOCK_STREAM,0);
00457 if (server_fd < 0) {
00458 perror ("socket");
00459 return -1;
00460 }
00461
00462 tmp = 1;
00463 setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
00464
00465 if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
00466 char bindmsg[32];
00467 snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
00468 perror (bindmsg);
00469 closesocket(server_fd);
00470 return -1;
00471 }
00472
00473 if (listen (server_fd, 5) < 0) {
00474 perror ("listen");
00475 closesocket(server_fd);
00476 return -1;
00477 }
00478 ff_socket_nonblock(server_fd, 1);
00479
00480 return server_fd;
00481 }
00482
00483
00484 static void start_multicast(void)
00485 {
00486 FFStream *stream;
00487 char session_id[32];
00488 HTTPContext *rtp_c;
00489 struct sockaddr_in dest_addr;
00490 int default_port, stream_index;
00491
00492 default_port = 6000;
00493 for(stream = first_stream; stream != NULL; stream = stream->next) {
00494 if (stream->is_multicast) {
00495
00496 snprintf(session_id, sizeof(session_id), "%08x%08x",
00497 av_random(&random_state), av_random(&random_state));
00498
00499
00500 if (stream->multicast_port == 0) {
00501 stream->multicast_port = default_port;
00502 default_port += 100;
00503 }
00504
00505 dest_addr.sin_family = AF_INET;
00506 dest_addr.sin_addr = stream->multicast_ip;
00507 dest_addr.sin_port = htons(stream->multicast_port);
00508
00509 rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
00510 RTSP_PROTOCOL_RTP_UDP_MULTICAST);
00511 if (!rtp_c)
00512 continue;
00513
00514 if (open_input_stream(rtp_c, "") < 0) {
00515 http_log("Could not open input stream for stream '%s'\n",
00516 stream->filename);
00517 continue;
00518 }
00519
00520
00521 for(stream_index = 0; stream_index < stream->nb_streams;
00522 stream_index++) {
00523 dest_addr.sin_port = htons(stream->multicast_port +
00524 2 * stream_index);
00525 if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
00526 http_log("Could not open output stream '%s/streamid=%d'\n",
00527 stream->filename, stream_index);
00528 exit(1);
00529 }
00530 }
00531
00532
00533 rtp_c->state = HTTPSTATE_SEND_DATA;
00534 }
00535 }
00536 }
00537
00538
00539 static int http_server(void)
00540 {
00541 int server_fd = 0, rtsp_server_fd = 0;
00542 int ret, delay, delay1;
00543 struct pollfd poll_table[HTTP_MAX_CONNECTIONS + 2], *poll_entry;
00544 HTTPContext *c, *c_next;
00545
00546 if (my_http_addr.sin_port) {
00547 server_fd = socket_open_listen(&my_http_addr);
00548 if (server_fd < 0)
00549 return -1;
00550 }
00551
00552 if (my_rtsp_addr.sin_port) {
00553 rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
00554 if (rtsp_server_fd < 0)
00555 return -1;
00556 }
00557
00558 if (!rtsp_server_fd && !server_fd) {
00559 http_log("HTTP and RTSP disabled.\n");
00560 return -1;
00561 }
00562
00563 http_log("ffserver started.\n");
00564
00565 start_children(first_feed);
00566
00567 start_multicast();
00568
00569 for(;;) {
00570 poll_entry = poll_table;
00571 if (server_fd) {
00572 poll_entry->fd = server_fd;
00573 poll_entry->events = POLLIN;
00574 poll_entry++;
00575 }
00576 if (rtsp_server_fd) {
00577 poll_entry->fd = rtsp_server_fd;
00578 poll_entry->events = POLLIN;
00579 poll_entry++;
00580 }
00581
00582
00583 c = first_http_ctx;
00584 delay = 1000;
00585 while (c != NULL) {
00586 int fd;
00587 fd = c->fd;
00588 switch(c->state) {
00589 case HTTPSTATE_SEND_HEADER:
00590 case RTSPSTATE_SEND_REPLY:
00591 case RTSPSTATE_SEND_PACKET:
00592 c->poll_entry = poll_entry;
00593 poll_entry->fd = fd;
00594 poll_entry->events = POLLOUT;
00595 poll_entry++;
00596 break;
00597 case HTTPSTATE_SEND_DATA_HEADER:
00598 case HTTPSTATE_SEND_DATA:
00599 case HTTPSTATE_SEND_DATA_TRAILER:
00600 if (!c->is_packetized) {
00601
00602 c->poll_entry = poll_entry;
00603 poll_entry->fd = fd;
00604 poll_entry->events = POLLOUT;
00605 poll_entry++;
00606 } else {
00607
00608
00609
00610 delay1 = 10;
00611 if (delay1 < delay)
00612 delay = delay1;
00613 }
00614 break;
00615 case HTTPSTATE_WAIT_REQUEST:
00616 case HTTPSTATE_RECEIVE_DATA:
00617 case HTTPSTATE_WAIT_FEED:
00618 case RTSPSTATE_WAIT_REQUEST:
00619
00620 c->poll_entry = poll_entry;
00621 poll_entry->fd = fd;
00622 poll_entry->events = POLLIN;
00623 poll_entry++;
00624 break;
00625 default:
00626 c->poll_entry = NULL;
00627 break;
00628 }
00629 c = c->next;
00630 }
00631
00632
00633
00634 do {
00635 ret = poll(poll_table, poll_entry - poll_table, delay);
00636 if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
00637 ff_neterrno() != FF_NETERROR(EINTR))
00638 return -1;
00639 } while (ret < 0);
00640
00641 cur_time = av_gettime() / 1000;
00642
00643 if (need_to_start_children) {
00644 need_to_start_children = 0;
00645 start_children(first_feed);
00646 }
00647
00648
00649 for(c = first_http_ctx; c != NULL; c = c_next) {
00650 c_next = c->next;
00651 if (handle_connection(c) < 0) {
00652
00653 log_connection(c);
00654 close_connection(c);
00655 }
00656 }
00657
00658 poll_entry = poll_table;
00659 if (server_fd) {
00660
00661 if (poll_entry->revents & POLLIN)
00662 new_connection(server_fd, 0);
00663 poll_entry++;
00664 }
00665 if (rtsp_server_fd) {
00666
00667 if (poll_entry->revents & POLLIN)
00668 new_connection(rtsp_server_fd, 1);
00669 }
00670 }
00671 }
00672
00673
00674 static void start_wait_request(HTTPContext *c, int is_rtsp)
00675 {
00676 c->buffer_ptr = c->buffer;
00677 c->buffer_end = c->buffer + c->buffer_size - 1;
00678
00679 if (is_rtsp) {
00680 c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
00681 c->state = RTSPSTATE_WAIT_REQUEST;
00682 } else {
00683 c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
00684 c->state = HTTPSTATE_WAIT_REQUEST;
00685 }
00686 }
00687
00688 static void new_connection(int server_fd, int is_rtsp)
00689 {
00690 struct sockaddr_in from_addr;
00691 int fd, len;
00692 HTTPContext *c = NULL;
00693
00694 len = sizeof(from_addr);
00695 fd = accept(server_fd, (struct sockaddr *)&from_addr,
00696 &len);
00697 if (fd < 0) {
00698 http_log("error during accept %s\n", strerror(errno));
00699 return;
00700 }
00701 ff_socket_nonblock(fd, 1);
00702
00703
00704
00705 if (nb_connections >= nb_max_connections)
00706 goto fail;
00707
00708
00709 c = av_mallocz(sizeof(HTTPContext));
00710 if (!c)
00711 goto fail;
00712
00713 c->fd = fd;
00714 c->poll_entry = NULL;
00715 c->from_addr = from_addr;
00716 c->buffer_size = IOBUFFER_INIT_SIZE;
00717 c->buffer = av_malloc(c->buffer_size);
00718 if (!c->buffer)
00719 goto fail;
00720
00721 c->next = first_http_ctx;
00722 first_http_ctx = c;
00723 nb_connections++;
00724
00725 start_wait_request(c, is_rtsp);
00726
00727 return;
00728
00729 fail:
00730 if (c) {
00731 av_free(c->buffer);
00732 av_free(c);
00733 }
00734 closesocket(fd);
00735 }
00736
00737 static void close_connection(HTTPContext *c)
00738 {
00739 HTTPContext **cp, *c1;
00740 int i, nb_streams;
00741 AVFormatContext *ctx;
00742 URLContext *h;
00743 AVStream *st;
00744
00745
00746 cp = &first_http_ctx;
00747 while ((*cp) != NULL) {
00748 c1 = *cp;
00749 if (c1 == c)
00750 *cp = c->next;
00751 else
00752 cp = &c1->next;
00753 }
00754
00755
00756 for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
00757 if (c1->rtsp_c == c)
00758 c1->rtsp_c = NULL;
00759 }
00760
00761
00762 if (c->fd >= 0)
00763 closesocket(c->fd);
00764 if (c->fmt_in) {
00765
00766 for(i=0;i<c->fmt_in->nb_streams;i++) {
00767 st = c->fmt_in->streams[i];
00768 if (st->codec->codec)
00769 avcodec_close(st->codec);
00770 }
00771 av_close_input_file(c->fmt_in);
00772 }
00773
00774
00775 nb_streams = 0;
00776 if (c->stream)
00777 nb_streams = c->stream->nb_streams;
00778
00779 for(i=0;i<nb_streams;i++) {
00780 ctx = c->rtp_ctx[i];
00781 if (ctx) {
00782 av_write_trailer(ctx);
00783 av_free(ctx);
00784 }
00785 h = c->rtp_handles[i];
00786 if (h)
00787 url_close(h);
00788 }
00789
00790 ctx = &c->fmt_ctx;
00791
00792 if (!c->last_packet_sent) {
00793 if (ctx->oformat) {
00794
00795 if (url_open_dyn_buf(&ctx->pb) >= 0) {
00796 av_write_trailer(ctx);
00797 av_freep(&c->pb_buffer);
00798 url_close_dyn_buf(ctx->pb, &c->pb_buffer);
00799 }
00800 }
00801 }
00802
00803 for(i=0; i<ctx->nb_streams; i++)
00804 av_free(ctx->streams[i]);
00805
00806 if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
00807 current_bandwidth -= c->stream->bandwidth;
00808
00809
00810 if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
00811 c->stream->feed_opened = 0;
00812 close(c->feed_fd);
00813 }
00814
00815 av_freep(&c->pb_buffer);
00816 av_freep(&c->packet_buffer);
00817 av_free(c->buffer);
00818 av_free(c);
00819 nb_connections--;
00820 }
00821
00822 static int handle_connection(HTTPContext *c)
00823 {
00824 int len, ret;
00825
00826 switch(c->state) {
00827 case HTTPSTATE_WAIT_REQUEST:
00828 case RTSPSTATE_WAIT_REQUEST:
00829
00830 if ((c->timeout - cur_time) < 0)
00831 return -1;
00832 if (c->poll_entry->revents & (POLLERR | POLLHUP))
00833 return -1;
00834
00835
00836 if (!(c->poll_entry->revents & POLLIN))
00837 return 0;
00838
00839 read_loop:
00840 len = recv(c->fd, c->buffer_ptr, 1, 0);
00841 if (len < 0) {
00842 if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
00843 ff_neterrno() != FF_NETERROR(EINTR))
00844 return -1;
00845 } else if (len == 0) {
00846 return -1;
00847 } else {
00848
00849 uint8_t *ptr;
00850 c->buffer_ptr += len;
00851 ptr = c->buffer_ptr;
00852 if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
00853 (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
00854
00855 if (c->state == HTTPSTATE_WAIT_REQUEST) {
00856 ret = http_parse_request(c);
00857 } else {
00858 ret = rtsp_parse_request(c);
00859 }
00860 if (ret < 0)
00861 return -1;
00862 } else if (ptr >= c->buffer_end) {
00863
00864 return -1;
00865 } else goto read_loop;
00866 }
00867 break;
00868
00869 case HTTPSTATE_SEND_HEADER:
00870 if (c->poll_entry->revents & (POLLERR | POLLHUP))
00871 return -1;
00872
00873
00874 if (!(c->poll_entry->revents & POLLOUT))
00875 return 0;
00876 len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
00877 if (len < 0) {
00878 if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
00879 ff_neterrno() != FF_NETERROR(EINTR)) {
00880
00881 av_freep(&c->pb_buffer);
00882 return -1;
00883 }
00884 } else {
00885 c->buffer_ptr += len;
00886 if (c->stream)
00887 c->stream->bytes_served += len;
00888 c->data_count += len;
00889 if (c->buffer_ptr >= c->buffer_end) {
00890 av_freep(&c->pb_buffer);
00891
00892 if (c->http_error)
00893 return -1;
00894
00895 c->state = HTTPSTATE_SEND_DATA_HEADER;
00896 c->buffer_ptr = c->buffer_end = c->buffer;
00897 }
00898 }
00899 break;
00900
00901 case HTTPSTATE_SEND_DATA:
00902 case HTTPSTATE_SEND_DATA_HEADER:
00903 case HTTPSTATE_SEND_DATA_TRAILER:
00904
00905
00906