mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-29 22:00:58 +02:00
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
tested and submitted by (Torsten Spindler <spindler at hbt dot arch dot ethz dot ch>) Originally committed as revision 3381 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
1477ec35dd
commit
6ba5cbc699
@ -2714,7 +2714,7 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url)
|
|||||||
struct sockaddr_in my_addr;
|
struct sockaddr_in my_addr;
|
||||||
|
|
||||||
/* find which url is asked */
|
/* find which url is asked */
|
||||||
url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
|
url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
|
||||||
path = path1;
|
path = path1;
|
||||||
if (*path == '/')
|
if (*path == '/')
|
||||||
path++;
|
path++;
|
||||||
@ -2788,7 +2788,7 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
|
|||||||
RTSPActionServerSetup setup;
|
RTSPActionServerSetup setup;
|
||||||
|
|
||||||
/* find which url is asked */
|
/* find which url is asked */
|
||||||
url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
|
url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
|
||||||
path = path1;
|
path = path1;
|
||||||
if (*path == '/')
|
if (*path == '/')
|
||||||
path++;
|
path++;
|
||||||
@ -2943,7 +2943,7 @@ static HTTPContext *find_rtp_session_with_url(const char *url,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* find which url is asked */
|
/* find which url is asked */
|
||||||
url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
|
url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
|
||||||
path = path1;
|
path = path1;
|
||||||
if (*path == '/')
|
if (*path == '/')
|
||||||
path++;
|
path++;
|
||||||
|
@ -627,6 +627,7 @@ struct in_addr;
|
|||||||
int resolve_host(struct in_addr *sin_addr, const char *hostname);
|
int resolve_host(struct in_addr *sin_addr, const char *hostname);
|
||||||
|
|
||||||
void url_split(char *proto, int proto_size,
|
void url_split(char *proto, int proto_size,
|
||||||
|
char *authorization, int authorization_size,
|
||||||
char *hostname, int hostname_size,
|
char *hostname, int hostname_size,
|
||||||
int *port_ptr,
|
int *port_ptr,
|
||||||
char *path, int path_size,
|
char *path, int path_size,
|
||||||
|
@ -46,8 +46,10 @@ typedef struct {
|
|||||||
char location[URL_SIZE];
|
char location[URL_SIZE];
|
||||||
} HTTPContext;
|
} HTTPContext;
|
||||||
|
|
||||||
static int http_connect(URLContext *h, const char *path, const char *hoststr);
|
static int http_connect(URLContext *h, const char *path, const char *hoststr,
|
||||||
|
const char *auth);
|
||||||
static int http_write(URLContext *h, uint8_t *buf, int size);
|
static int http_write(URLContext *h, uint8_t *buf, int size);
|
||||||
|
static char *b64_encode( unsigned char *src );
|
||||||
|
|
||||||
|
|
||||||
/* return non zero if error */
|
/* return non zero if error */
|
||||||
@ -55,6 +57,7 @@ static int http_open(URLContext *h, const char *uri, int flags)
|
|||||||
{
|
{
|
||||||
const char *path, *proxy_path;
|
const char *path, *proxy_path;
|
||||||
char hostname[1024], hoststr[1024];
|
char hostname[1024], hoststr[1024];
|
||||||
|
char auth[1024];
|
||||||
char path1[1024];
|
char path1[1024];
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int port, use_proxy, err;
|
int port, use_proxy, err;
|
||||||
@ -76,7 +79,7 @@ static int http_open(URLContext *h, const char *uri, int flags)
|
|||||||
/* fill the dest addr */
|
/* fill the dest addr */
|
||||||
redo:
|
redo:
|
||||||
/* needed in any case to build the host string */
|
/* needed in any case to build the host string */
|
||||||
url_split(NULL, 0, hostname, sizeof(hostname), &port,
|
url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
|
||||||
path1, sizeof(path1), uri);
|
path1, sizeof(path1), uri);
|
||||||
if (port > 0) {
|
if (port > 0) {
|
||||||
snprintf(hoststr, sizeof(hoststr), "%s:%d", hostname, port);
|
snprintf(hoststr, sizeof(hoststr), "%s:%d", hostname, port);
|
||||||
@ -85,7 +88,7 @@ static int http_open(URLContext *h, const char *uri, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (use_proxy) {
|
if (use_proxy) {
|
||||||
url_split(NULL, 0, hostname, sizeof(hostname), &port,
|
url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
|
||||||
NULL, 0, proxy_path);
|
NULL, 0, proxy_path);
|
||||||
path = uri;
|
path = uri;
|
||||||
} else {
|
} else {
|
||||||
@ -103,7 +106,7 @@ static int http_open(URLContext *h, const char *uri, int flags)
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
s->hd = hd;
|
s->hd = hd;
|
||||||
if (http_connect(h, path, hoststr) < 0)
|
if (http_connect(h, path, hoststr, auth) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (s->http_code == 303 && s->location[0] != '\0') {
|
if (s->http_code == 303 && s->location[0] != '\0') {
|
||||||
/* url moved, get next */
|
/* url moved, get next */
|
||||||
@ -172,7 +175,8 @@ static int process_line(HTTPContext *s, char *line, int line_count)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_connect(URLContext *h, const char *path, const char *hoststr)
|
static int http_connect(URLContext *h, const char *path, const char *hoststr,
|
||||||
|
const char *auth)
|
||||||
{
|
{
|
||||||
HTTPContext *s = h->priv_data;
|
HTTPContext *s = h->priv_data;
|
||||||
int post, err, ch;
|
int post, err, ch;
|
||||||
@ -187,11 +191,13 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr)
|
|||||||
"User-Agent: %s\r\n"
|
"User-Agent: %s\r\n"
|
||||||
"Accept: */*\r\n"
|
"Accept: */*\r\n"
|
||||||
"Host: %s\r\n"
|
"Host: %s\r\n"
|
||||||
|
"Authorization: Basic %s\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
post ? "POST" : "GET",
|
post ? "POST" : "GET",
|
||||||
path,
|
path,
|
||||||
LIBAVFORMAT_IDENT,
|
LIBAVFORMAT_IDENT,
|
||||||
hoststr);
|
hoststr,
|
||||||
|
b64_encode(auth));
|
||||||
|
|
||||||
if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
|
if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
|
||||||
return AVERROR_IO;
|
return AVERROR_IO;
|
||||||
@ -277,3 +283,46 @@ URLProtocol http_protocol = {
|
|||||||
http_close,
|
http_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* b64_encode: stolen from VLC's http.c
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static char *b64_encode( unsigned char *src )
|
||||||
|
{
|
||||||
|
static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
char *dst = av_malloc( strlen( src ) * 4 / 3 + 12 );
|
||||||
|
char *ret = dst;
|
||||||
|
unsigned i_bits = 0;
|
||||||
|
unsigned i_shift = 0;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( *src )
|
||||||
|
{
|
||||||
|
i_bits = ( i_bits << 8 )|( *src++ );
|
||||||
|
i_shift += 8;
|
||||||
|
}
|
||||||
|
else if( i_shift > 0 )
|
||||||
|
{
|
||||||
|
i_bits <<= 6 - i_shift;
|
||||||
|
i_shift = 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*dst++ = '=';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( i_shift >= 6 )
|
||||||
|
{
|
||||||
|
i_shift -= 6;
|
||||||
|
*dst++ = b64[(i_bits >> i_shift)&0x3f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst++ = '\0';
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ int rtp_set_remote_url(URLContext *h, const char *uri)
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
char path[1024];
|
char path[1024];
|
||||||
|
|
||||||
url_split(NULL, 0, hostname, sizeof(hostname), &port,
|
url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
|
||||||
path, sizeof(path), uri);
|
path, sizeof(path), uri);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "udp://%s:%d%s", hostname, port, path);
|
snprintf(buf, sizeof(buf), "udp://%s:%d%s", hostname, port, path);
|
||||||
@ -122,7 +122,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
h->priv_data = s;
|
h->priv_data = s;
|
||||||
|
|
||||||
url_split(NULL, 0, hostname, sizeof(hostname), &port,
|
url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
|
||||||
path, sizeof(path), uri);
|
path, sizeof(path), uri);
|
||||||
/* extract parameters */
|
/* extract parameters */
|
||||||
is_multicast = 0;
|
is_multicast = 0;
|
||||||
|
@ -339,7 +339,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
|
|||||||
rtsp_st = st->priv_data;
|
rtsp_st = st->priv_data;
|
||||||
|
|
||||||
/* XXX: may need to add full url resolution */
|
/* XXX: may need to add full url resolution */
|
||||||
url_split(proto, sizeof(proto), NULL, 0, NULL, NULL, 0, p);
|
url_split(proto, sizeof(proto), NULL, 0, NULL, 0, NULL, NULL, 0, p);
|
||||||
if (proto[0] == '\0') {
|
if (proto[0] == '\0') {
|
||||||
/* relative control URL */
|
/* relative control URL */
|
||||||
pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), "/");
|
pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), "/");
|
||||||
@ -723,7 +723,7 @@ static int rtsp_read_header(AVFormatContext *s,
|
|||||||
AVStream *st;
|
AVStream *st;
|
||||||
|
|
||||||
/* extract hostname and port */
|
/* extract hostname and port */
|
||||||
url_split(NULL, 0,
|
url_split(NULL, 0, NULL, 0,
|
||||||
host, sizeof(host), &port, path, sizeof(path), s->filename);
|
host, sizeof(host), &port, path, sizeof(path), s->filename);
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
port = RTSP_DEFAULT_PORT;
|
port = RTSP_DEFAULT_PORT;
|
||||||
|
@ -63,25 +63,18 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
int fd_max, ret;
|
int fd_max, ret;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
socklen_t optlen;
|
socklen_t optlen;
|
||||||
|
char proto[1024],path[1024],tmp[1024]; // PETR: protocol and path strings
|
||||||
|
|
||||||
|
url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
|
||||||
|
&port, path, sizeof(path), uri); // PETR: use url_split
|
||||||
|
if (strcmp(proto,"tcp")) goto fail; // PETR: check protocol
|
||||||
|
if ((q = strchr(hostname,'@'))) { strcpy(tmp,q+1); strcpy(hostname,tmp); } // PETR: take only the part after '@' for tcp protocol
|
||||||
|
|
||||||
s = av_malloc(sizeof(TCPContext));
|
s = av_malloc(sizeof(TCPContext));
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
h->priv_data = s;
|
h->priv_data = s;
|
||||||
p = uri;
|
|
||||||
if (!strstart(p, "tcp://", &p))
|
|
||||||
goto fail;
|
|
||||||
q = hostname;
|
|
||||||
while (*p != ':' && *p != '/' && *p != '\0') {
|
|
||||||
if ((q - hostname) < sizeof(hostname) - 1)
|
|
||||||
*q++ = *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
*q = '\0';
|
|
||||||
if (*p != ':')
|
|
||||||
goto fail;
|
|
||||||
p++;
|
|
||||||
port = strtoul(p, (char **)&p, 10);
|
|
||||||
if (port <= 0 || port >= 65536)
|
if (port <= 0 || port >= 65536)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ int udp_set_remote_url(URLContext *h, const char *uri)
|
|||||||
char hostname[256];
|
char hostname[256];
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
url_split(NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
|
url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
|
||||||
|
|
||||||
/* set the destination address */
|
/* set the destination address */
|
||||||
if (resolve_host(&s->dest_addr.sin_addr, hostname) < 0)
|
if (resolve_host(&s->dest_addr.sin_addr, hostname) < 0)
|
||||||
@ -132,7 +132,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fill the dest addr */
|
/* fill the dest addr */
|
||||||
url_split(NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
|
url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
|
||||||
|
|
||||||
/* XXX: fix url_split */
|
/* XXX: fix url_split */
|
||||||
if (hostname[0] == '\0' || hostname[0] == '?') {
|
if (hostname[0] == '\0' || hostname[0] == '?') {
|
||||||
|
@ -2499,6 +2499,7 @@ void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void url_split(char *proto, int proto_size,
|
void url_split(char *proto, int proto_size,
|
||||||
|
char *authorization, int authorization_size,
|
||||||
char *hostname, int hostname_size,
|
char *hostname, int hostname_size,
|
||||||
int *port_ptr,
|
int *port_ptr,
|
||||||
char *path, int path_size,
|
char *path, int path_size,
|
||||||
@ -2519,6 +2520,8 @@ void url_split(char *proto, int proto_size,
|
|||||||
}
|
}
|
||||||
if (proto_size > 0)
|
if (proto_size > 0)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
|
if (authorization_size > 0)
|
||||||
|
authorization[0] = '\0';
|
||||||
if (*p == '\0') {
|
if (*p == '\0') {
|
||||||
if (proto_size > 0)
|
if (proto_size > 0)
|
||||||
proto[0] = '\0';
|
proto[0] = '\0';
|
||||||
@ -2526,15 +2529,32 @@ void url_split(char *proto, int proto_size,
|
|||||||
hostname[0] = '\0';
|
hostname[0] = '\0';
|
||||||
p = url;
|
p = url;
|
||||||
} else {
|
} else {
|
||||||
|
char *at,*slash; // PETR: position of '@' character and '/' character
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
p++;
|
p++;
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
p++;
|
p++;
|
||||||
q = hostname;
|
at = strchr(p,'@'); // PETR: get the position of '@'
|
||||||
while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
|
slash = strchr(p,'/'); // PETR: get position of '/' - end of hostname
|
||||||
if ((q - hostname) < hostname_size - 1)
|
if (at && slash && at > slash) at = NULL; // PETR: not interested in '@' behind '/'
|
||||||
|
|
||||||
|
q = at ? authorization : hostname; // PETR: if '@' exists starting with auth.
|
||||||
|
|
||||||
|
while ((at || *p != ':') && *p != '/' && *p != '?' && *p != '\0') { // PETR:
|
||||||
|
if (*p == '@') { // PETR: passed '@'
|
||||||
|
if (authorization_size > 0)
|
||||||
|
*q = '\0';
|
||||||
|
q = hostname;
|
||||||
|
at = NULL;
|
||||||
|
} else if (!at) { // PETR: hostname
|
||||||
|
if ((q - hostname) < hostname_size - 1)
|
||||||
|
*q++ = *p;
|
||||||
|
} else {
|
||||||
|
if ((q - authorization) < authorization_size - 1)
|
||||||
*q++ = *p;
|
*q++ = *p;
|
||||||
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if (hostname_size > 0)
|
if (hostname_size > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user