You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
http protocol now uses tcp: protocol (simpler)
Originally committed as revision 797 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
116
libav/http.c
116
libav/http.c
@@ -36,25 +36,27 @@
|
|||||||
#define URL_SIZE 4096
|
#define URL_SIZE 4096
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
URLContext *hd;
|
||||||
unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end;
|
unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end;
|
||||||
int line_count;
|
int line_count;
|
||||||
int http_code;
|
int http_code;
|
||||||
char location[URL_SIZE];
|
char location[URL_SIZE];
|
||||||
} HTTPContext;
|
} HTTPContext;
|
||||||
|
|
||||||
static int http_connect(URLContext *h, const char *path);
|
static int http_connect(URLContext *h, const char *path, const char *hoststr);
|
||||||
static int http_write(URLContext *h, UINT8 *buf, int size);
|
static int http_write(URLContext *h, UINT8 *buf, int size);
|
||||||
|
|
||||||
|
|
||||||
/* return non zero if error */
|
/* return non zero if error */
|
||||||
static int http_open(URLContext *h, const char *uri, int flags)
|
static int http_open(URLContext *h, const char *uri, int flags)
|
||||||
{
|
{
|
||||||
struct sockaddr_in dest_addr;
|
const char *path, *proxy_path;
|
||||||
const char *p, *path, *proxy_path;
|
char hostname[1024], hoststr[1024];
|
||||||
char hostname[1024], *q;
|
char path1[1024];
|
||||||
int port, fd = -1, use_proxy;
|
char buf[1024];
|
||||||
struct hostent *hp;
|
int port, use_proxy, err;
|
||||||
HTTPContext *s;
|
HTTPContext *s;
|
||||||
|
URLContext *hd = NULL;
|
||||||
|
|
||||||
h->is_streamed = 1;
|
h->is_streamed = 1;
|
||||||
|
|
||||||
@@ -65,70 +67,51 @@ static int http_open(URLContext *h, const char *uri, int flags)
|
|||||||
h->priv_data = s;
|
h->priv_data = s;
|
||||||
|
|
||||||
proxy_path = getenv("http_proxy");
|
proxy_path = getenv("http_proxy");
|
||||||
use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && (strncmp(proxy_path, "http://", 7) == 0);
|
use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
|
||||||
|
strstart(proxy_path, "http://", NULL);
|
||||||
|
|
||||||
/* fill the dest addr */
|
/* fill the dest addr */
|
||||||
redo:
|
redo:
|
||||||
if (use_proxy) {
|
/* needed in any case to build the host string */
|
||||||
p = proxy_path;
|
url_split(NULL, 0, hostname, sizeof(hostname), &port,
|
||||||
|
path1, sizeof(path1), uri);
|
||||||
|
if (port > 0) {
|
||||||
|
snprintf(hoststr, sizeof(hoststr), "%s:%d", hostname, port);
|
||||||
} else {
|
} else {
|
||||||
p = uri;
|
pstrcpy(hoststr, sizeof(hoststr), hostname);
|
||||||
}
|
}
|
||||||
if (!strstart(p, "http://", &p))
|
|
||||||
goto fail;
|
|
||||||
q = hostname;
|
|
||||||
while (*p != ':' && *p != '/' && *p != '\0') {
|
|
||||||
if ((q - hostname) < sizeof(hostname) - 1)
|
|
||||||
*q++ = *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
*q = '\0';
|
|
||||||
port = 80;
|
|
||||||
if (*p == ':') {
|
|
||||||
p++;
|
|
||||||
port = strtoul(p, (char **)&p, 10);
|
|
||||||
}
|
|
||||||
if (port <= 0)
|
|
||||||
goto fail;
|
|
||||||
if (use_proxy) {
|
if (use_proxy) {
|
||||||
|
url_split(NULL, 0, hostname, sizeof(hostname), &port,
|
||||||
|
NULL, 0, proxy_path);
|
||||||
path = uri;
|
path = uri;
|
||||||
} else {
|
} else {
|
||||||
if (*p == '\0')
|
if (path1[0] == '\0')
|
||||||
path = "/";
|
path = "/";
|
||||||
else
|
else
|
||||||
path = p;
|
path = path1;
|
||||||
}
|
}
|
||||||
|
if (port < 0)
|
||||||
|
port = 80;
|
||||||
|
|
||||||
dest_addr.sin_family = AF_INET;
|
snprintf(buf, sizeof(buf), "tcp://%s:%d", hostname, port);
|
||||||
dest_addr.sin_port = htons(port);
|
err = url_open(&hd, buf, URL_RDWR);
|
||||||
if ((inet_aton(hostname, &dest_addr.sin_addr)) == 0) {
|
if (err < 0)
|
||||||
hp = gethostbyname(hostname);
|
|
||||||
if (!hp)
|
|
||||||
goto fail;
|
|
||||||
memcpy (&dest_addr.sin_addr, hp->h_addr, sizeof(dest_addr.sin_addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (connect(fd, (struct sockaddr *)&dest_addr,
|
s->hd = hd;
|
||||||
sizeof(dest_addr)) < 0)
|
if (http_connect(h, path, hoststr) < 0)
|
||||||
goto fail;
|
|
||||||
|
|
||||||
s->fd = fd;
|
|
||||||
if (http_connect(h, path) < 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 */
|
||||||
uri = s->location;
|
uri = s->location;
|
||||||
|
url_close(hd);
|
||||||
goto redo;
|
goto redo;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
if (fd >= 0)
|
if (hd)
|
||||||
close(fd);
|
url_close(hd);
|
||||||
av_free(s);
|
av_free(s);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@@ -137,11 +120,8 @@ static int http_getc(HTTPContext *s)
|
|||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
if (s->buf_ptr >= s->buf_end) {
|
if (s->buf_ptr >= s->buf_end) {
|
||||||
redo:
|
len = url_read(s->hd, s->buffer, BUFFER_SIZE);
|
||||||
len = read(s->fd, s->buffer, BUFFER_SIZE);
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
|
||||||
goto redo;
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
} else if (len == 0) {
|
} else if (len == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -189,7 +169,7 @@ static int process_line(HTTPContext *s, char *line, int line_count)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_connect(URLContext *h, const char *path)
|
static int http_connect(URLContext *h, const char *path, const char *hoststr)
|
||||||
{
|
{
|
||||||
HTTPContext *s = h->priv_data;
|
HTTPContext *s = h->priv_data;
|
||||||
int post, err, ch;
|
int post, err, ch;
|
||||||
@@ -203,11 +183,12 @@ static int http_connect(URLContext *h, const char *path)
|
|||||||
"%s %s HTTP/1.0\n"
|
"%s %s HTTP/1.0\n"
|
||||||
"User-Agent: FFmpeg %s\n"
|
"User-Agent: FFmpeg %s\n"
|
||||||
"Accept: */*\n"
|
"Accept: */*\n"
|
||||||
|
"Host: %s\n"
|
||||||
"\n",
|
"\n",
|
||||||
post ? "POST" : "GET",
|
post ? "POST" : "GET",
|
||||||
path,
|
path,
|
||||||
FFMPEG_VERSION
|
FFMPEG_VERSION,
|
||||||
);
|
hoststr);
|
||||||
|
|
||||||
if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
|
if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@@ -266,12 +247,9 @@ static int http_read(URLContext *h, UINT8 *buf, int size)
|
|||||||
memcpy(buf, s->buf_ptr, len);
|
memcpy(buf, s->buf_ptr, len);
|
||||||
s->buf_ptr += len;
|
s->buf_ptr += len;
|
||||||
} else {
|
} else {
|
||||||
len = read (s->fd, buf, size);
|
len = url_read (s->hd, buf, size);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (errno != EINTR && errno != EAGAIN)
|
return len;
|
||||||
return -errno;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
} else if (len == 0) {
|
} else if (len == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -286,23 +264,14 @@ static int http_read(URLContext *h, UINT8 *buf, int size)
|
|||||||
static int http_write(URLContext *h, UINT8 *buf, int size)
|
static int http_write(URLContext *h, UINT8 *buf, int size)
|
||||||
{
|
{
|
||||||
HTTPContext *s = h->priv_data;
|
HTTPContext *s = h->priv_data;
|
||||||
int ret, size1;
|
return url_write(s->hd, buf, size);
|
||||||
|
|
||||||
size1 = size;
|
|
||||||
while (size > 0) {
|
|
||||||
ret = write (s->fd, buf, size);
|
|
||||||
if (ret < 0 && errno != EINTR && errno != EAGAIN)
|
|
||||||
return -errno;
|
|
||||||
size -= ret;
|
|
||||||
buf += ret;
|
|
||||||
}
|
|
||||||
return size1 - size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_close(URLContext *h)
|
static int http_close(URLContext *h)
|
||||||
{
|
{
|
||||||
HTTPContext *s = h->priv_data;
|
HTTPContext *s = h->priv_data;
|
||||||
close(s->fd);
|
url_close(s->hd);
|
||||||
|
av_free(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,3 +283,4 @@ URLProtocol http_protocol = {
|
|||||||
NULL, /* seek */
|
NULL, /* seek */
|
||||||
http_close,
|
http_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user