~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to mpg123_artsplugin/mpg123/httpget.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
Import upstream version 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   httpget.c
 
3
 *
 
4
 *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
 
5
 *   Wed Apr  9 20:57:47 MET DST 1997
 
6
 */
 
7
 
 
8
#undef ALSA
 
9
 
 
10
#if !defined(WIN32) && !defined(GENERIC)
 
11
 
 
12
#include <stdlib.h>
 
13
#include <stdio.h>
 
14
#include <string.h>
 
15
#include <netdb.h>
 
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>
 
22
#include <ctype.h>
 
23
 
 
24
extern int errno;
 
25
 
 
26
#include "mpg123.h"
 
27
 
 
28
#ifndef INADDR_NONE
 
29
#define INADDR_NONE 0xffffffff
 
30
#endif
 
31
 
 
32
void writestring (int fd, char *string)
 
33
{
 
34
        int result, bytes = strlen(string);
 
35
 
 
36
        while (bytes) {
 
37
                if ((result = write(fd, string, bytes)) < 0 && errno != EINTR) {
 
38
                        perror ("write");
 
39
                        exit (1);
 
40
                }
 
41
                else if (result == 0) {
 
42
                        fprintf (stderr, "write: %s\n",
 
43
                                "socket closed unexpectedly");
 
44
                        exit (1);
 
45
                }
 
46
                string += result;
 
47
                bytes -= result;
 
48
        }
 
49
}
 
50
 
 
51
void readstring (char *string, int maxlen, FILE *f)
 
52
{
 
53
#if 0
 
54
        char *result;
 
55
#endif
 
56
        int pos = 0;
 
57
 
 
58
        while(1) {
 
59
                if( read(fileno(f),string+pos,1) == 1) {
 
60
                        pos++;
 
61
                        if(string[pos-1] == '\n') {
 
62
                                string[pos] = 0;
 
63
                                break;
 
64
                        }
 
65
                }
 
66
                else if(errno != EINTR) {
 
67
                        fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
 
68
                        exit(1);
 
69
                }
 
70
        }
 
71
#if 0
 
72
        do {
 
73
                result = fgets(string, maxlen, f);
 
74
        } while (!result  && errno == EINTR);
 
75
        if (!result) {
 
76
                fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
 
77
                exit (1);
 
78
        }
 
79
#endif
 
80
 
 
81
}
 
82
 
 
83
void encode64 (char *source,char *destination)
 
84
{
 
85
  static char *Base64Digits =
 
86
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
87
  int n = 0;
 
88
  int ssiz=strlen(source);
 
89
  int i;
 
90
 
 
91
  for (i = 0 ; i < ssiz ; i += 3) {
 
92
    unsigned int buf;
 
93
    buf = ((unsigned char *)source)[i] << 16;
 
94
    if (i+1 < ssiz)
 
95
      buf |= ((unsigned char *)source)[i+1] << 8;
 
96
    if (i+2 < ssiz)
 
97
      buf |= ((unsigned char *)source)[i+2];
 
98
 
 
99
    destination[n++] = Base64Digits[(buf >> 18) % 64];
 
100
    destination[n++] = Base64Digits[(buf >> 12) % 64];
 
101
    if (i+1 < ssiz)
 
102
      destination[n++] = Base64Digits[(buf >> 6) % 64];
 
103
    else
 
104
      destination[n++] = '=';
 
105
    if (i+2 < ssiz)
 
106
      destination[n++] = Base64Digits[buf % 64];
 
107
    else
 
108
      destination[n++] = '=';
 
109
  }
 
110
  destination[n++] = 0;
 
111
}
 
112
 
 
113
/* VERY  simple auth-from-URL grabber */
 
114
int getauthfromURL(char *url,char *auth)
 
115
{
 
116
  char *pos;
 
117
 
 
118
  *auth = 0;
 
119
 
 
120
  if (!(strncasecmp(url, "http://", 7)))
 
121
    url += 7;
 
122
 
 
123
  if (!(strncasecmp(url, "ftp://", 6)))
 
124
    url += 6;
 
125
 
 
126
  if( (pos = strchr(url,'@')) ) {
 
127
    int i;
 
128
    for(i=0;i<pos-url;i++) {
 
129
      if( url[i] == '/' )
 
130
         return 0;
 
131
    }
 
132
    strncpy(auth,url,pos-url);
 
133
    auth[pos-url] = 0;
 
134
    strcpy(url,pos+1);
 
135
    return 1;
 
136
  }
 
137
  return 0;
 
138
}
 
139
 
 
140
static char *defaultportstr = "80";
 
141
 
 
142
char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned char **port)
 
143
{
 
144
        char *h, *p;
 
145
        char *hostptr;
 
146
        char *r_hostptr;
 
147
        char *pathptr;
 
148
        char *portptr;
 
149
        char *p0;
 
150
        size_t stringlength;
 
151
 
 
152
        p = url;
 
153
        if (strncasecmp(p, "http://", 7) == 0)
 
154
                p += 7;
 
155
 
 
156
        if (strncasecmp(p, "ftp://", 6) == 0)
 
157
               p += 6;
 
158
 
 
159
        hostptr = p;
 
160
        while (*p && *p != '/')
 
161
                p++;
 
162
        pathptr = p;
 
163
 
 
164
        r_hostptr = --p;
 
165
        while (*p && hostptr < p && *p != ':' && *p != ']')
 
166
                p--;
 
167
 
 
168
        if (!*p || p < hostptr || *p != ':') {
 
169
                portptr = NULL;
 
170
        }
 
171
        else{
 
172
                portptr = p + 1;
 
173
                r_hostptr = p - 1;
 
174
        }
 
175
        if (*hostptr == '[' && *r_hostptr == ']') {
 
176
                hostptr++;
 
177
                r_hostptr--;
 
178
        }
 
179
 
 
180
        stringlength = r_hostptr - hostptr + 1;
 
181
        h = malloc(stringlength + 1); /* removed the strndup for better portability */
 
182
        if (h == NULL) {
 
183
                *hname = NULL;
 
184
                *port = NULL;
 
185
                return NULL;
 
186
        }
 
187
        strncpy(h, hostptr, stringlength);
 
188
        *(h+stringlength) = '\0';
 
189
        *hname = h;
 
190
 
 
191
        if (portptr) {
 
192
                stringlength = (pathptr - portptr);
 
193
                if(!stringlength) portptr = NULL;
 
194
        }
 
195
        if (portptr == NULL) {
 
196
                portptr = defaultportstr;
 
197
                stringlength = strlen(defaultportstr);
 
198
        }
 
199
        p0 = malloc(stringlength + 1);
 
200
        if (p0 == NULL) {
 
201
                free(h);
 
202
                *hname = NULL;
 
203
                *port = NULL;
 
204
                return NULL;
 
205
        }
 
206
        strncpy(p0, portptr, stringlength);
 
207
        *(p0 + stringlength) = '\0';
 
208
 
 
209
        for (p = p0; *p && isdigit((unsigned char) *p); p++) ;
 
210
 
 
211
        *p = '\0';
 
212
        *port = (unsigned char *) p0;
 
213
 
 
214
        return pathptr;
 
215
}
 
216
 
 
217
char *proxyurl = NULL;
 
218
unsigned long proxyip = 0;
 
219
unsigned char *proxyport;
 
220
 
 
221
#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
 
222
 
 
223
char *httpauth = NULL;
 
224
char httpauth1[256];
 
225
 
 
226
int http_open (const char *url)
 
227
{
 
228
        char *purl, *host, *request, *sptr;
 
229
        int linelength;
 
230
        unsigned long myip;
 
231
        unsigned char *myport;
 
232
        int sock;
 
233
        int relocate, numrelocs = 0;
 
234
        FILE *myfile;
 
235
#ifdef INET6
 
236
        struct addrinfo hints, *res, *res0;
 
237
        int error;
 
238
#else
 
239
        struct hostent *hp;
 
240
        struct sockaddr_in sin;
 
241
#endif
 
242
 
 
243
        host = NULL;
 
244
        proxyport = NULL;
 
245
        myport = NULL;
 
246
        if (!proxyip) {
 
247
                if (!proxyurl)
 
248
                        if (!(proxyurl = getenv("MP3_HTTP_PROXY")))
 
249
                                if (!(proxyurl = getenv("http_proxy")))
 
250
                                        proxyurl = getenv("HTTP_PROXY");
 
251
                if (proxyurl && proxyurl[0] && strcmp(proxyurl, "none")) {
 
252
                        if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport))) {
 
253
                                fprintf (stderr, "Unknown proxy host \"%s\".\n",
 
254
                                        host ? host : "");
 
255
                                exit (1);
 
256
                        }
 
257
#if 0
 
258
                        if (host)
 
259
                                free (host);
 
260
#endif
 
261
                }
 
262
                else
 
263
                        proxyip = INADDR_NONE;
 
264
        }
 
265
 
 
266
 
 
267
       if (proxyip == INADDR_NONE)
 
268
               if (strncasecmp(url, "ftp://", 6) == 0){
 
269
                       fprintf(stderr,"Downloading from ftp servers without PROXY not allowed\n");
 
270
                       exit(1);
 
271
               }
 
272
 
 
273
        
 
274
        if ((linelength = strlen(url)+200) < 1024)
 
275
                linelength = 1024;
 
276
        if (!(request = malloc(linelength)) || !(purl = malloc(1024))) {
 
277
                fprintf (stderr, "malloc() failed, out of memory.\n");
 
278
                exit (1);
 
279
        }
 
280
       /*
 
281
        * 2000-10-21:
 
282
        * We would like spaces to be automatically converted to %20's when
 
283
        * fetching via HTTP.
 
284
        * -- Martin Sj�gren <md9ms@mdstud.chalmers.se>
 
285
        */
 
286
       if ((sptr = strchr(url, ' ')) == NULL) {
 
287
               strncpy (purl, url, 1023);
 
288
               purl[1023] = '\0';
 
289
       }
 
290
       else {
 
291
               int purllength = 0;
 
292
               char *urlptr = url;
 
293
               purl[0] = '\0';
 
294
               do {
 
295
                       purllength += sptr-urlptr + 3;
 
296
                       if (purllength >= 1023)
 
297
                               break;
 
298
                       strncat (purl, urlptr, sptr-urlptr);
 
299
                       /*purl[sptr-url] = '\0';*/
 
300
                       strcat (purl, "%20");
 
301
                       urlptr = sptr + 1;
 
302
               }
 
303
               while ((sptr = strchr (urlptr, ' ')) != NULL);
 
304
               strcat (purl, urlptr);
 
305
       }
 
306
 
 
307
 
 
308
        getauthfromURL(purl,httpauth1);
 
309
 
 
310
        do {
 
311
                strcpy (request, "GET ");
 
312
                if (proxyip != INADDR_NONE) {
 
313
                        if (strncasecmp(url, "http://", 7) != 0 && strncasecmp(url,"ftp://", 6) != 0)
 
314
                                strcat (request, "http://");
 
315
                        strcat (request, purl);
 
316
                        myport = proxyport;
 
317
                        myip = proxyip;
 
318
                }
 
319
                else {
 
320
                        if (host) {
 
321
                                free(host);
 
322
                                host=NULL;
 
323
                        }
 
324
                        if (proxyport) {
 
325
                                free(proxyport);
 
326
                                proxyport=NULL;
 
327
                        }
 
328
                        if (!(sptr = url2hostport(purl, &host, &myip, &myport))) {
 
329
                                fprintf (stderr, "Unknown host \"%s\".\n",
 
330
                                        host ? host : "");
 
331
                                exit (1);
 
332
                        }
 
333
                        strcat (request, sptr);
 
334
                }
 
335
                sprintf (request + strlen(request),
 
336
                        " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
 
337
                        prgName, prgVersion);
 
338
                if (host) {
 
339
                        sprintf(request + strlen(request),
 
340
                                "Host: %s:%s\r\n", host, myport);
 
341
#if 0
 
342
                        free (host);
 
343
#endif
 
344
                }
 
345
                strcat (request, ACCEPT_HEAD);
 
346
 
 
347
#ifdef INET6
 
348
                memset(&hints, 0, sizeof(hints));
 
349
                hints.ai_socktype = SOCK_STREAM;
 
350
                error = getaddrinfo(host, (char *)myport, &hints, &res0);
 
351
                if (error) {
 
352
                        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
 
353
                        exit(1);
 
354
                }
 
355
 
 
356
                sock = -1;
 
357
                for (res = res0; res; res = res->ai_next) {
 
358
                        if ((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
 
359
                                continue;
 
360
                        }
 
361
                        if (connect(sock, res->ai_addr, res->ai_addrlen)) {
 
362
                                close(sock);
 
363
                                sock = -1;
 
364
                                continue;
 
365
                        }
 
366
                        break;
 
367
                }
 
368
 
 
369
                freeaddrinfo(res0);
 
370
#else
 
371
                sock = -1;
 
372
                hp = gethostbyname(host);
 
373
                if (!hp)
 
374
                        goto fail;
 
375
                if (hp->h_length != sizeof(sin.sin_addr))
 
376
                        goto fail;
 
377
                sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 
378
                if (sock < 0)
 
379
                        goto fail;
 
380
                memset(&sin, 0, sizeof(sin));
 
381
                sin.sin_family = AF_INET;
 
382
                /* sin.sin_len = sizeof(struct sockaddr_in); */
 
383
                memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
 
384
                sin.sin_port = htons(atoi( (char *) myport));
 
385
                if (connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in) ) < 0) {
 
386
                        close(sock);
 
387
                        sock = -1;
 
388
                }
 
389
fail:
 
390
#endif
 
391
 
 
392
                if (sock < 0) {
 
393
                        perror("socket");
 
394
                        exit(1);
 
395
                }
 
396
 
 
397
                if (strlen(httpauth1) || httpauth) {
 
398
                        char buf[1023];
 
399
                        strcat (request,"Authorization: Basic ");
 
400
                        if(strlen(httpauth1))
 
401
                          encode64(httpauth1,buf);
 
402
                        else
 
403
                          encode64(httpauth,buf);
 
404
                        strcat (request,buf);
 
405
                        strcat (request,"\r\n");
 
406
                }
 
407
                strcat (request, "\r\n");
 
408
 
 
409
                writestring (sock, request);
 
410
                if (!(myfile = fdopen(sock, "rb"))) {
 
411
                        perror ("fdopen");
 
412
                        exit (1);
 
413
                };
 
414
                relocate = FALSE;
 
415
                purl[0] = '\0';
 
416
                readstring (request, linelength-1, myfile);
 
417
                if ((sptr = strchr(request, ' '))) {
 
418
                        switch (sptr[1]) {
 
419
                                case '3':
 
420
                                        relocate = TRUE;
 
421
                                case '2':
 
422
                                        break;
 
423
                                default:
 
424
                                        fprintf (stderr, "HTTP request failed: %s",
 
425
                                                sptr+1); /* '\n' is included */
 
426
                                        exit (1);
 
427
                        }
 
428
                }
 
429
                do {
 
430
                        readstring (request, linelength-1, myfile);
 
431
                        if (!strncmp(request, "Location:", 9))
 
432
                                strncpy (purl, request+10, 1023);
 
433
                } while (request[0] != '\r' && request[0] != '\n');
 
434
        } while (relocate && purl[0] && numrelocs++ < 5);
 
435
        if (relocate) {
 
436
                fprintf (stderr, "Too many HTTP relocations.\n");
 
437
                exit (1);
 
438
        }
 
439
        free (purl);
 
440
        free (request);
 
441
        free(host);
 
442
        free(proxyport);
 
443
        free(myport);
 
444
 
 
445
        return sock;
 
446
}
 
447
 
 
448
#else
 
449
#include <stdlib.h>
 
450
#include <stdio.h>
 
451
#include <string.h>
 
452
 
 
453
extern int errno;
 
454
 
 
455
#include "mpg123.h"
 
456
 
 
457
void writestring (int fd, char *string)
 
458
{
 
459
}
 
460
 
 
461
void readstring (char *string, int maxlen, FILE *f)
 
462
{
 
463
}
 
464
 
 
465
char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
 
466
{
 
467
}
 
468
 
 
469
char *proxyurl = NULL;
 
470
unsigned long proxyip = 0;
 
471
unsigned int proxyport;
 
472
 
 
473
#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
 
474
 
 
475
int http_open (char *url)
 
476
{
 
477
}
 
478
#endif
 
479
 
 
480
/* EOF */
 
481