4
* Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
5
* Wed Apr 9 20:57:47 MET DST 1997
10
#if !defined(WIN32) && !defined(GENERIC)
16
#include <sys/param.h>
17
#include <sys/types.h>
18
#include <sys/socket.h>
19
#include <netinet/in.h>
20
#include <arpa/inet.h>
21
#include <sys/errno.h>
29
#define INADDR_NONE 0xffffffff
32
void writestring (int fd, char *string)
34
int result, bytes = strlen(string);
37
if ((result = write(fd, string, bytes)) < 0 && errno != EINTR) {
41
else if (result == 0) {
42
fprintf (stderr, "write: %s\n",
43
"socket closed unexpectedly");
51
void readstring (char *string, int maxlen, FILE *f)
59
if( read(fileno(f),string+pos,1) == 1) {
61
if(string[pos-1] == '\n') {
66
else if(errno != EINTR) {
67
fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
73
result = fgets(string, maxlen, f);
74
} while (!result && errno == EINTR);
76
fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
83
void encode64 (char *source,char *destination)
85
static char *Base64Digits =
86
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
88
int ssiz=strlen(source);
91
for (i = 0 ; i < ssiz ; i += 3) {
93
buf = ((unsigned char *)source)[i] << 16;
95
buf |= ((unsigned char *)source)[i+1] << 8;
97
buf |= ((unsigned char *)source)[i+2];
99
destination[n++] = Base64Digits[(buf >> 18) % 64];
100
destination[n++] = Base64Digits[(buf >> 12) % 64];
102
destination[n++] = Base64Digits[(buf >> 6) % 64];
104
destination[n++] = '=';
106
destination[n++] = Base64Digits[buf % 64];
108
destination[n++] = '=';
110
destination[n++] = 0;
113
/* VERY simple auth-from-URL grabber */
114
int getauthfromURL(char *url,char *auth)
120
if (!(strncmp(url, "http://", 7)))
123
if( (pos = strchr(url,'@')) ) {
125
for(i=0;i<pos-url;i++) {
129
strncpy(auth,url,pos-url);
137
char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
140
struct hostent *myhostent;
141
struct in_addr myaddr;
144
if (!(strncmp(url, "http://", 7)))
147
while (*cptr && *cptr != ':' && *cptr != '/') {
148
if ((*cptr < '0' || *cptr > '9') && *cptr != '.')
152
*hname = strdup(url); /* removed the strndup for better portability */
157
(*hname)[cptr - url] = 0;
159
if (!(myhostent = gethostbyname(*hname)))
161
memcpy (&myaddr, myhostent->h_addr, sizeof(myaddr));
162
*hip = myaddr.s_addr;
165
if ((*hip = inet_addr(*hname)) == INADDR_NONE)
167
if (!*cptr || *cptr == '/') {
171
*port = atoi(++cptr);
172
while (*cptr && *cptr != '/')
177
char *proxyurl = NULL;
178
unsigned long proxyip = 0;
179
unsigned int proxyport;
181
#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
183
char *httpauth = NULL;
186
int http_open (char *url)
188
char *purl, *host, *request, *sptr;
193
int relocate, numrelocs = 0;
194
struct sockaddr_in server;
199
if (!(proxyurl = getenv("MP3_HTTP_PROXY")))
200
if (!(proxyurl = getenv("http_proxy")))
201
proxyurl = getenv("HTTP_PROXY");
202
if (proxyurl && proxyurl[0] && strcmp(proxyurl, "none")) {
204
if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport))) {
205
fprintf (stderr, "Unknown proxy host \"%s\".\n",
213
proxyip = INADDR_NONE;
216
if ((linelength = strlen(url)+200) < 1024)
218
if (!(request = malloc(linelength)) || !(purl = malloc(1024))) {
219
fprintf (stderr, "malloc() failed, out of memory.\n");
222
strncpy (purl, url, 1023);
225
getauthfromURL(purl,httpauth1);
228
strcpy (request, "GET ");
229
if (proxyip != INADDR_NONE) {
230
if (strncmp(url, "http://", 7))
231
strcat (request, "http://");
232
strcat (request, purl);
238
if (!(sptr = url2hostport(purl, &host, &myip, &myport))) {
239
fprintf (stderr, "Unknown host \"%s\".\n",
243
strcat (request, sptr);
245
sprintf (request + strlen(request),
246
" HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
247
prgName, prgVersion);
249
sprintf(request + strlen(request),
250
"Host: %s:%u\r\n", host, myport);
254
strcat (request, ACCEPT_HEAD);
255
server.sin_family = AF_INET;
256
server.sin_port = htons(myport);
257
server.sin_addr.s_addr = myip;
258
if ((sock = socket(PF_INET, SOCK_STREAM, 6)) < 0) {
262
if (connect(sock, (struct sockaddr *)&server, sizeof(server))) {
267
if (strlen(httpauth1) || httpauth) {
269
strcat (request,"Authorization: Basic ");
270
if(strlen(httpauth1))
271
encode64(httpauth1,buf);
273
encode64(httpauth,buf);
274
strcat (request,buf);
275
strcat (request,"\r\n");
277
strcat (request, "\r\n");
279
writestring (sock, request);
280
if (!(myfile = fdopen(sock, "rb"))) {
286
readstring (request, linelength-1, myfile);
287
if ((sptr = strchr(request, ' '))) {
294
fprintf (stderr, "HTTP request failed: %s",
295
sptr+1); /* '\n' is included */
300
readstring (request, linelength-1, myfile);
301
if (!strncmp(request, "Location:", 9))
302
strncpy (purl, request+10, 1023);
303
} while (request[0] != '\r' && request[0] != '\n');
304
} while (relocate && purl[0] && numrelocs++ < 5);
306
fprintf (stderr, "Too many HTTP relocations.\n");
324
void writestring (int fd, char *string)
328
void readstring (char *string, int maxlen, FILE *f)
332
char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
336
char *proxyurl = NULL;
337
unsigned long proxyip = 0;
338
unsigned int proxyport;
340
#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
342
int http_open (char *url)