summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-11-06 10:08:48 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-11-06 10:08:48 +0000
commit633473a3ef0ae4641b460508734abf832810d1c4 (patch)
tree133108bfbb24f39e832ad26ef7d3b42cd71fd482 /src
parenta1a237955272fd8de70f88cc98ce4b4dfa046f8b (diff)
downloadxine-lib-633473a3ef0ae4641b460508734abf832810d1c4.tar.gz
xine-lib-633473a3ef0ae4641b460508734abf832810d1c4.tar.bz2
input_http updates by Damien Clermonte
CVS patchset: 964 CVS date: 2001/11/06 10:08:48
Diffstat (limited to 'src')
-rw-r--r--src/input/input_http.c337
1 files changed, 303 insertions, 34 deletions
diff --git a/src/input/input_http.c b/src/input/input_http.c
index f755b4060..acf08f9b9 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -42,6 +42,8 @@
#define BUFSIZE 1024
+#define DEFAULT_HTTP_PORT 80
+
static uint32_t xine_debug;
typedef struct {
@@ -52,14 +54,29 @@ typedef struct {
config_values_t *config;
off_t curpos;
-
- char buf[BUFSIZE];
- char mrlbuf[BUFSIZE];
+ off_t contentlength;
+
+ char buf[BUFSIZE];
+ char mrlbuf[BUFSIZE];
+ char proxybuf[BUFSIZE];
+ char auth[BUFSIZE];
+ char proxyauth[BUFSIZE];
+
+ char *user;
+ char *password;
+ char *host;
+ int port;
+ char *filename;
+
+ char *proxyuser;
+ char *proxypassword;
+ char *proxyhost;
+ int proxyport;
} http_input_plugin_t;
-static int host_connect_attempt(struct in_addr ia, int port) {
+static int http_plugin_host_connect_attempt(struct in_addr ia, int port) {
int s;
struct sockaddr_in sin;
@@ -84,7 +101,7 @@ static int host_connect_attempt(struct in_addr ia, int port) {
return s;
}
-static int host_connect(const char *host, int port) {
+static int http_plugin_host_connect(const char *host, int port) {
struct hostent *h;
int i;
int s;
@@ -97,8 +114,8 @@ static int host_connect(const char *host, int port) {
for(i=0; h->h_addr_list[i]; i++) {
struct in_addr ia;
- memcpy(&ia, h->h_addr_list[i],4);
- s=host_connect_attempt(ia, port);
+ memcpy(&ia, h->h_addr_list[i], 4);
+ s=http_plugin_host_connect_attempt(ia, port);
if(s != -1)
return s;
}
@@ -107,46 +124,245 @@ static int host_connect(const char *host, int port) {
return -1;
}
+static int http_plugin_parse_url (char *urlbuf, char **user, char **password,
+ char** host, int *port, char **filename) {
+ char *start = NULL;
+ char *authcolon = NULL;
+ char *at = NULL;
+ char *portcolon = NULL;
+ char *slash = NULL;
+
+ if (user != NULL)
+ *user = NULL;
+
+ if (password != NULL)
+ *password = NULL;
+
+ if (host != NULL)
+ *host = NULL;
+
+ if (filename != NULL)
+ *filename = NULL;
+
+ if (port != NULL)
+ *port = 0;
+
+ start = strstr(urlbuf, "://");
+ if (start != NULL)
+ start += 3;
+ else
+ start = urlbuf;
+
+ at = strchr(start, '@');
+ slash = strchr(start, '/');
+
+ if (at != NULL && slash != NULL && at > slash)
+ at = NULL;
+
+ if (at != NULL)
+ {
+ authcolon = strchr(start, ':');
+ if(authcolon != NULL && authcolon > at)
+ authcolon = NULL;
+
+ portcolon = strchr(at, ':');
+ } else
+ portcolon = strchr(start, ':');
+
+ if (portcolon != NULL && slash != NULL && portcolon > slash)
+ portcolon = NULL;
+
+ if (at != NULL)
+ {
+ *at = '\0';
+
+ if (user != NULL)
+ *user = start;
+
+ if (authcolon != NULL)
+ {
+ *authcolon = '\0';
+
+ if (password != NULL)
+ *password = authcolon + 1;
+ }
+
+ if (host != NULL)
+ *host = at + 1;
+ } else
+ if (host != NULL)
+ *host = start;
+
+ if (slash != 0)
+ {
+ *slash = '\0';
+
+ if (filename != NULL)
+ *filename = slash + 1;
+ } else
+ *filename = urlbuf + strlen(urlbuf);
+
+ if (portcolon != NULL)
+ {
+ *portcolon = '\0';
+
+ if (port != NULL)
+ *port = atoi(portcolon + 1);
+ }
+
+ return 0;
+}
+
+static int http_plugin_basicauth (const char *user, const char *password,
+ char* dest, int len) {
+ static char *enctable="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ char *tmp;
+ char *sptr;
+ char *dptr;
+ int totlen;
+ int enclen;
+ int count;
+
+ totlen = strlen (user) + 1;
+ if(password != NULL)
+ totlen += strlen (password);
+
+ enclen = ((totlen + 2) / 3 ) * 4 + 1;
+
+ if (len < enclen)
+ return -1;
+
+ tmp = malloc (sizeof(char) * (totlen + 1));
+ strcpy (tmp, user);
+ strcat (tmp, ":");
+ if (password != NULL)
+ strcat (tmp, password);
+
+ count = strlen(tmp);
+ sptr = tmp;
+ dptr = dest;
+ while (count >= 3) {
+ dptr[0] = enctable[(sptr[0] & 0xFC) >> 2];
+ dptr[1] = enctable[((sptr[0] & 0x3) << 4) | ((sptr[1] & 0xF0) >> 4)];
+ dptr[2] = enctable[((sptr[1] & 0x0F) << 2) | ((sptr[2] & 0xC0) >> 6)];
+ dptr[3] = enctable[sptr[2] & 0x3F];
+ count -= 3;
+ sptr += 3;
+ dptr += 4;
+ }
+
+ if (count > 0) {
+ dptr[0] = enctable[(sptr[0] & 0xFC) >> 2];
+ dptr[1] = enctable[(sptr[0] & 0x3) << 4];
+ dptr[2] = '=';
+
+ if (count > 1) {
+ dptr[1] = enctable[((sptr[0] & 0x3) << 4) | ((sptr[1] & 0xF0) >> 4)];
+ dptr[2] = enctable[(sptr[1] & 0x0F) << 2];
+ }
+
+ dptr[3] = '=';
+ dptr += 4;
+ }
+
+ dptr[0] = '\0';
+
+ free(tmp);
+ return 0;
+}
+
static int http_plugin_open (input_plugin_t *this_gen, char *mrl) {
http_input_plugin_t *this = (http_input_plugin_t *) this_gen;
- char *filename, *host;
- char *pstr;
- int port = 80;
- int done,len;
+ char *proxy;
+ int done,len,linenum;
- strncpy(this->mrlbuf, mrl, 1024);
+ strncpy (this->mrlbuf, mrl, BUFSIZE);
this->mrl = mrl;
- /* parse url */
-
- if (!strncasecmp (this->mrlbuf, "http:",5))
- host = (char *) &this->mrlbuf[7];
- else
+ if (strncasecmp (this->mrlbuf, "http://", 7))
return 0;
- if (! (filename = strchr (host, '/')) )
+ this->proxybuf[0] = '\0';
+ proxy = getenv("http_proxy");
+
+ if (proxy != NULL)
+ {
+ strncpy(this->proxybuf, proxy, BUFSIZE);
+
+ if (http_plugin_parse_url (this->proxybuf, &this->proxyuser,
+ &this->proxypassword, &this->proxyhost, &this->proxyport, NULL))
+ return 0;
+
+ if (this->proxyport == 0)
+ this->proxyport = DEFAULT_HTTP_PORT;
+
+ if (this->proxyuser != NULL)
+ if (http_plugin_basicauth (this->proxyuser, this->proxypassword,
+ this->proxyauth, BUFSIZE))
+ return 0;
+ }
+
+ if(http_plugin_parse_url (this->mrlbuf, &this->user, &this->password,
+ &this->host, &this->port, &this->filename))
return 0;
- *filename=0;
- filename++;
-
- printf ("input_http: opening >%s< on host >%s<\n", filename, host);
+ if(this->port == 0)
+ this->port = DEFAULT_HTTP_PORT;
+
+ if (this->user != NULL)
+ if (http_plugin_basicauth (this->user, this->password, this->auth, BUFSIZE))
+ return 0;
+
+ printf ("input_http: opening >/%s< on host >%s<", this->filename, this->host);
+ if(proxy != NULL)
+ printf (" via proxy >%s<", this->proxyhost);
- pstr=strrchr(host, ':');
- if (pstr) {
- *pstr++=0;
- sscanf(pstr,"%d", &port);
- }
+ printf ("\n");
+
+ if (proxy != NULL)
+ this->fh = http_plugin_host_connect (this->proxyhost, this->proxyport);
+ else
+ this->fh = http_plugin_host_connect (this->host, this->port);
- this->fh = host_connect(host, port);
this->curpos = 0;
if (this->fh == -1) {
return 0;
}
- sprintf (this->buf, "GET http://%s:%d/%s HTTP/1.0\r\n\r\n", host,port,filename);
+ if (proxy != NULL)
+ if (this->port != DEFAULT_HTTP_PORT)
+ sprintf (this->buf, "GET http://%s:%d/%s HTTP/1.0\015\012",
+ this->host, this->port, this->filename);
+ else
+ sprintf (this->buf, "GET http://%s/%s HTTP/1.0\015\012",
+ this->host, this->filename);
+ else
+ sprintf (this->buf, "GET /%s HTTP/1.0\015\012", this->filename);
+
+ if (this->port != DEFAULT_HTTP_PORT)
+ sprintf (this->buf + strlen(this->buf), "Host: %s:%d\015\012",
+ this->host, this->port);
+ else
+ sprintf (this->buf + strlen(this->buf), "Host: %s\015\012",
+ this->host);
+
+ if (this->proxyuser != NULL)
+ sprintf (this->buf + strlen(this->buf), "Proxy-Authorization: Basic %s\015\012",
+ this->proxyauth);
+
+ if (this->user != NULL)
+ sprintf (this->buf + strlen(this->buf), "Authorization: Basic %s\015\012",
+ this->auth);
+
+ sprintf (this->buf + strlen(this->buf), "User-Agent: xine/%s\015\012",
+ VERSION);
+
+ strcat (this->buf, "Accept: */*\015\012");
+
+ strcat (this->buf, "\015\012");
+
if (write (this->fh, this->buf, strlen(this->buf)) != strlen(this->buf)) {
printf ("input_http: couldn't send request\n");
return 0 ;
@@ -156,7 +372,8 @@ static int http_plugin_open (input_plugin_t *this_gen, char *mrl) {
this->buf);
/* read and parse reply */
- done = 0; len = 0;
+ done = 0; len = 0; linenum = 0;
+ this->contentlength = 0;
while (!done) {
@@ -176,13 +393,60 @@ static int http_plugin_open (input_plugin_t *this_gen, char *mrl) {
}
}
- if (this->buf[len] == '\n') {
+ if (this->buf[len] == '\012') {
- this->buf[len] = 0;
+ this->buf[len] = '\0';
+ len--;
+
+ if (len >= 0 && this->buf[len] == '\015') {
+ this->buf[len] = '\0';
+ len--;
+ }
+ linenum++;
+
printf ("input_http: answer: >%s<\n", this->buf);
- if (len == 1)
+ if (linenum == 1)
+ {
+ int httpver, httpsub, httpcode;
+ char httpstatus[BUFSIZE];
+
+ if (sscanf(this->buf, "HTTP/%d.%d %d %[^\015\012]", &httpver, &httpsub,
+ &httpcode, httpstatus) != 4)
+ {
+ printf ("input_http: invalid http answer\n");
+ return 0;
+ }
+
+ if (httpcode >= 300 && httpcode < 400) {
+ printf ("input_http: 3xx redirection not implemented: >%d %s<\n",
+ httpcode, httpstatus);
+ return 0;
+ }
+ if (httpcode < 200 || httpcode >= 300) {
+ printf ("input_http: http status not 2xx: >%d %s<\n", httpcode,
+ httpstatus);
+ return 0;
+ }
+ } else {
+ if (this->contentlength == 0) {
+ off_t contentlength;
+
+ if (sscanf(this->buf, "Content-Length: %ld", &contentlength) == 1) {
+ printf ("input_http: content length = %ld bytes\n", contentlength);
+ this->contentlength = contentlength;
+ }
+ }
+
+ if (!strncasecmp(this->buf, "Location: ", 10))
+ {
+ printf ("input_http: Location redirection not implemented\n");
+ return 0;
+ }
+ }
+
+ if (len == -1)
done = 1;
else
len = 0;
@@ -190,6 +454,8 @@ static int http_plugin_open (input_plugin_t *this_gen, char *mrl) {
len ++;
}
+ printf ("input_http: end of headers\n");
+
return 1;
}
@@ -217,6 +483,7 @@ static off_t http_plugin_read (input_plugin_t *this_gen,
}
num_bytes += n;
+ this->curpos += n;
}
return num_bytes;
}
@@ -254,6 +521,7 @@ static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buf
break;
}
total_bytes += num_bytes;
+ this->curpos += num_bytes;
}
if (buf != NULL)
@@ -266,8 +534,9 @@ static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buf
}
static off_t http_plugin_get_length (input_plugin_t *this_gen) {
+ http_input_plugin_t *this = (http_input_plugin_t *) this_gen;
- return 0;
+ return this->contentlength;
}
static uint32_t http_plugin_get_capabilities (input_plugin_t *this_gen) {