Originally committed as revision 821 to svn://svn.ffmpeg.org/ffmpeg/trunk
Philip Gladstone authored on 2002/07/27 12:03:04... | ... |
@@ -154,6 +154,18 @@ enum StreamType { |
154 | 154 |
STREAM_TYPE_REDIRECT, |
155 | 155 |
}; |
156 | 156 |
|
157 |
+enum IPAddressAction { |
|
158 |
+ IP_ALLOW = 1, |
|
159 |
+ IP_DENY, |
|
160 |
+}; |
|
161 |
+ |
|
162 |
+typedef struct IPAddressACL { |
|
163 |
+ struct IPAddressACL *next; |
|
164 |
+ enum IPAddressAction action; |
|
165 |
+ struct in_addr first; |
|
166 |
+ struct in_addr last; |
|
167 |
+} IPAddressACL; |
|
168 |
+ |
|
157 | 169 |
/* description of each stream of the ffserver.conf file */ |
158 | 170 |
typedef struct FFStream { |
159 | 171 |
enum StreamType stream_type; |
... | ... |
@@ -161,6 +173,7 @@ typedef struct FFStream { |
161 | 161 |
struct FFStream *feed; /* feed we are using (can be null if |
162 | 162 |
coming from file) */ |
163 | 163 |
AVOutputFormat *fmt; |
164 |
+ IPAddressACL *acl; |
|
164 | 165 |
int nb_streams; |
165 | 166 |
int prebuffer; /* Number of millseconds early to start */ |
166 | 167 |
long max_time; /* Number of milliseconds to run */ |
... | ... |
@@ -957,6 +970,23 @@ static void get_word(char *buf, int buf_size, const char **pp) |
957 | 957 |
*pp = p; |
958 | 958 |
} |
959 | 959 |
|
960 |
+static int validate_acl(FFStream *stream, HTTPContext *c) |
|
961 |
+{ |
|
962 |
+ enum IPAddressAction last_action = IP_DENY; |
|
963 |
+ IPAddressACL *acl; |
|
964 |
+ struct in_addr *src = &c->from_addr.sin_addr; |
|
965 |
+ |
|
966 |
+ for (acl = stream->acl; acl; acl = acl->next) { |
|
967 |
+ if (src->s_addr >= acl->first.s_addr && src->s_addr <= acl->last.s_addr) { |
|
968 |
+ return (acl->action == IP_ALLOW) ? 1 : 0; |
|
969 |
+ } |
|
970 |
+ last_action = acl->action; |
|
971 |
+ } |
|
972 |
+ |
|
973 |
+ /* Nothing matched, so return not the last action */ |
|
974 |
+ return (last_action == IP_DENY) ? 1 : 0; |
|
975 |
+} |
|
976 |
+ |
|
960 | 977 |
/* parse http request and prepare header */ |
961 | 978 |
static int http_parse_request(HTTPContext *c) |
962 | 979 |
{ |
... | ... |
@@ -1077,7 +1107,7 @@ static int http_parse_request(HTTPContext *c) |
1077 | 1077 |
|
1078 | 1078 |
stream = first_stream; |
1079 | 1079 |
while (stream != NULL) { |
1080 |
- if (!strcmp(stream->filename, filename)) |
|
1080 |
+ if (!strcmp(stream->filename, filename) && validate_acl(stream, c)) |
|
1081 | 1081 |
break; |
1082 | 1082 |
stream = stream->next; |
1083 | 1083 |
} |
... | ... |
@@ -1342,14 +1372,10 @@ static int http_parse_request(HTTPContext *c) |
1342 | 1342 |
q += sprintf(q, "Pragma: no-cache\r\n"); |
1343 | 1343 |
|
1344 | 1344 |
/* for asf, we need extra headers */ |
1345 |
- if (!strcmp(c->stream->fmt->name,"asf")) { |
|
1345 |
+ if (!strcmp(c->stream->fmt->name,"asf_stream")) { |
|
1346 | 1346 |
/* Need to allocate a client id */ |
1347 |
- static int wmp_session; |
|
1348 | 1347 |
|
1349 |
- if (!wmp_session) |
|
1350 |
- wmp_session = time(0) & 0xffffff; |
|
1351 |
- |
|
1352 |
- c->wmp_client_id = ++wmp_session; |
|
1348 |
+ c->wmp_client_id = random() & 0x7fffffff; |
|
1353 | 1349 |
|
1354 | 1350 |
q += sprintf(q, "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); |
1355 | 1351 |
mime_type = "application/octet-stream"; |
... | ... |
@@ -1719,6 +1745,12 @@ static int open_input_stream(HTTPContext *c, const char *info) |
1719 | 1719 |
if (input_filename[0] == '\0') |
1720 | 1720 |
return -1; |
1721 | 1721 |
|
1722 |
+#if 0 |
|
1723 |
+ { time_t when = stream_pos / 1000000; |
|
1724 |
+ http_log("Stream pos = %lld, time=%s", stream_pos, ctime(&when)); |
|
1725 |
+ } |
|
1726 |
+#endif |
|
1727 |
+ |
|
1722 | 1728 |
/* open stream */ |
1723 | 1729 |
if (av_open_input_file(&s, input_filename, NULL, buf_size, NULL) < 0) { |
1724 | 1730 |
http_log("%s not found", input_filename); |
... | ... |
@@ -3447,7 +3479,7 @@ int parse_ffconfig(const char *filename) |
3447 | 3447 |
q = strrchr(stream->filename, '>'); |
3448 | 3448 |
if (*q) |
3449 | 3449 |
*q = '\0'; |
3450 |
- stream->fmt = guess_format(NULL, stream->filename, NULL); |
|
3450 |
+ stream->fmt = guess_stream_format(NULL, stream->filename, NULL); |
|
3451 | 3451 |
memset(&audio_enc, 0, sizeof(AVCodecContext)); |
3452 | 3452 |
memset(&video_enc, 0, sizeof(AVCodecContext)); |
3453 | 3453 |
audio_id = CODEC_ID_NONE; |
... | ... |
@@ -3485,7 +3517,7 @@ int parse_ffconfig(const char *filename) |
3485 | 3485 |
/* jpeg cannot be used here, so use single frame jpeg */ |
3486 | 3486 |
if (!strcmp(arg, "jpeg")) |
3487 | 3487 |
strcpy(arg, "singlejpeg"); |
3488 |
- stream->fmt = guess_format(arg, NULL, NULL); |
|
3488 |
+ stream->fmt = guess_stream_format(arg, NULL, NULL); |
|
3489 | 3489 |
if (!stream->fmt) { |
3490 | 3490 |
fprintf(stderr, "%s:%d: Unknown Format: %s\n", |
3491 | 3491 |
filename, line_num, arg); |
... | ... |
@@ -3523,7 +3555,7 @@ int parse_ffconfig(const char *filename) |
3523 | 3523 |
} else if (!strcasecmp(cmd, "Preroll")) { |
3524 | 3524 |
get_arg(arg, sizeof(arg), &p); |
3525 | 3525 |
if (stream) { |
3526 |
- stream->prebuffer = atoi(arg) * 1000; |
|
3526 |
+ stream->prebuffer = atof(arg) * 1000; |
|
3527 | 3527 |
} |
3528 | 3528 |
} else if (!strcasecmp(cmd, "StartSendOnKey")) { |
3529 | 3529 |
if (stream) { |
... | ... |
@@ -3548,7 +3580,7 @@ int parse_ffconfig(const char *filename) |
3548 | 3548 |
} else if (!strcasecmp(cmd, "MaxTime")) { |
3549 | 3549 |
get_arg(arg, sizeof(arg), &p); |
3550 | 3550 |
if (stream) { |
3551 |
- stream->max_time = atoi(arg) * 1000; |
|
3551 |
+ stream->max_time = atof(arg) * 1000; |
|
3552 | 3552 |
} |
3553 | 3553 |
} else if (!strcasecmp(cmd, "AudioBitRate")) { |
3554 | 3554 |
get_arg(arg, sizeof(arg), &p); |
... | ... |
@@ -3630,6 +3662,72 @@ int parse_ffconfig(const char *filename) |
3630 | 3630 |
video_id = CODEC_ID_NONE; |
3631 | 3631 |
} else if (!strcasecmp(cmd, "NoAudio")) { |
3632 | 3632 |
audio_id = CODEC_ID_NONE; |
3633 |
+ } else if (!strcasecmp(cmd, "ACL")) { |
|
3634 |
+ IPAddressACL acl; |
|
3635 |
+ struct hostent *he; |
|
3636 |
+ |
|
3637 |
+ get_arg(arg, sizeof(arg), &p); |
|
3638 |
+ if (strcasecmp(arg, "allow") == 0) { |
|
3639 |
+ acl.action = IP_ALLOW; |
|
3640 |
+ } else if (strcasecmp(arg, "deny") == 0) { |
|
3641 |
+ acl.action = IP_DENY; |
|
3642 |
+ } else { |
|
3643 |
+ fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n", |
|
3644 |
+ filename, line_num, arg); |
|
3645 |
+ errors++; |
|
3646 |
+ } |
|
3647 |
+ |
|
3648 |
+ get_arg(arg, sizeof(arg), &p); |
|
3649 |
+ |
|
3650 |
+ he = gethostbyname(arg); |
|
3651 |
+ if (!he) { |
|
3652 |
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n", |
|
3653 |
+ filename, line_num, arg); |
|
3654 |
+ errors++; |
|
3655 |
+ } else { |
|
3656 |
+ /* Only take the first */ |
|
3657 |
+ acl.first = *(struct in_addr *) he->h_addr_list[0]; |
|
3658 |
+ acl.last = acl.first; |
|
3659 |
+ } |
|
3660 |
+ |
|
3661 |
+ get_arg(arg, sizeof(arg), &p); |
|
3662 |
+ |
|
3663 |
+ if (arg[0]) { |
|
3664 |
+ he = gethostbyname(arg); |
|
3665 |
+ if (!he) { |
|
3666 |
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n", |
|
3667 |
+ filename, line_num, arg); |
|
3668 |
+ errors++; |
|
3669 |
+ } else { |
|
3670 |
+ /* Only take the first */ |
|
3671 |
+ acl.last = *(struct in_addr *) he->h_addr_list[0]; |
|
3672 |
+ } |
|
3673 |
+ } |
|
3674 |
+ |
|
3675 |
+ if (!errors) { |
|
3676 |
+ IPAddressACL *nacl = (IPAddressACL *) av_mallocz(sizeof(*nacl)); |
|
3677 |
+ IPAddressACL **naclp = 0; |
|
3678 |
+ |
|
3679 |
+ *nacl = acl; |
|
3680 |
+ nacl->next = 0; |
|
3681 |
+ |
|
3682 |
+ if (stream) { |
|
3683 |
+ naclp = &stream->acl; |
|
3684 |
+ } else if (feed) { |
|
3685 |
+ naclp = &feed->acl; |
|
3686 |
+ } else { |
|
3687 |
+ fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n", |
|
3688 |
+ filename, line_num); |
|
3689 |
+ errors++; |
|
3690 |
+ } |
|
3691 |
+ |
|
3692 |
+ if (naclp) { |
|
3693 |
+ while (*naclp) |
|
3694 |
+ naclp = &(*naclp)->next; |
|
3695 |
+ |
|
3696 |
+ *naclp = nacl; |
|
3697 |
+ } |
|
3698 |
+ } |
|
3633 | 3699 |
} else if (!strcasecmp(cmd, "RTSPOption")) { |
3634 | 3700 |
get_arg(arg, sizeof(arg), &p); |
3635 | 3701 |
if (stream) { |
... | ... |
@@ -3830,6 +3928,8 @@ int main(int argc, char **argv) |
3830 | 3830 |
|
3831 | 3831 |
putenv("http_proxy"); /* Kill the http_proxy */ |
3832 | 3832 |
|
3833 |
+ srandom(gettime_ms() + (getpid() << 16)); |
|
3834 |
+ |
|
3833 | 3835 |
/* address on which the server will handle HTTP connections */ |
3834 | 3836 |
my_http_addr.sin_family = AF_INET; |
3835 | 3837 |
my_http_addr.sin_port = htons (8080); |
... | ... |
@@ -3875,10 +3975,12 @@ int main(int argc, char **argv) |
3875 | 3875 |
setsid(); |
3876 | 3876 |
chdir("/"); |
3877 | 3877 |
close(0); |
3878 |
- close(1); |
|
3879 |
- close(2); |
|
3880 | 3878 |
open("/dev/null", O_RDWR); |
3881 |
- dup(0); |
|
3879 |
+ if (!strcmp(logfilename, "-")) { |
|
3880 |
+ close(1); |
|
3881 |
+ dup(0); |
|
3882 |
+ } |
|
3883 |
+ close(2); |
|
3882 | 3884 |
dup(0); |
3883 | 3885 |
} |
3884 | 3886 |
} |