http protocol now uses tcp: protocol (simpler)

Originally committed as revision 797 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Fabrice Bellard 23 years ago
parent abba3dd133
commit 0e2a219706
  1. 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;
}
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(port);
if ((inet_aton(hostname, &dest_addr.sin_addr)) == 0) {
hp = gethostbyname(hostname);
if (!hp)
goto fail;
memcpy (&dest_addr.sin_addr, hp->h_addr, sizeof(dest_addr.sin_addr));
} }
if (port < 0)
port = 80;
fd = socket(PF_INET, SOCK_STREAM, 0); snprintf(buf, sizeof(buf), "tcp://%s:%d", hostname, port);
if (fd < 0) err = url_open(&hd, buf, URL_RDWR);
if (err < 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,
}; };

Loading…
Cancel
Save