~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to httpget.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

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 (!(strncmp(url, "http://", 7)))
121
 
    url += 7;
122
 
 
123
 
  if( (pos = strchr(url,'@')) ) {
124
 
    int i;
125
 
    for(i=0;i<pos-url;i++) {
126
 
      if( url[i] == '/' )
127
 
         return 0;
128
 
    }
129
 
    strncpy(auth,url,pos-url);
130
 
    auth[pos-url] = 0;
131
 
    strcpy(url,pos+1);
132
 
    return 1;
133
 
  }
134
 
  return 0;
135
 
}
136
 
 
137
 
char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
138
 
{
139
 
        char *cptr;
140
 
        struct hostent *myhostent;
141
 
        struct in_addr myaddr;
142
 
        int isip = 1;
143
 
 
144
 
        if (!(strncmp(url, "http://", 7)))
145
 
                url += 7;
146
 
        cptr = url;
147
 
        while (*cptr && *cptr != ':' && *cptr != '/') {
148
 
                if ((*cptr < '0' || *cptr > '9') && *cptr != '.')
149
 
                        isip = 0;
150
 
                cptr++;
151
 
        }
152
 
        *hname = strdup(url); /* removed the strndup for better portability */
153
 
        if (!(*hname)) {
154
 
                *hname = NULL;
155
 
                return (NULL);
156
 
        }
157
 
        (*hname)[cptr - url] = 0;
158
 
        if (!isip) {
159
 
                if (!(myhostent = gethostbyname(*hname)))
160
 
                        return (NULL);
161
 
                memcpy (&myaddr, myhostent->h_addr, sizeof(myaddr));
162
 
                *hip = myaddr.s_addr;
163
 
        }
164
 
        else
165
 
                if ((*hip = inet_addr(*hname)) == INADDR_NONE)
166
 
                        return (NULL);
167
 
        if (!*cptr || *cptr == '/') {
168
 
                *port = 80;
169
 
                return (cptr);
170
 
        }
171
 
        *port = atoi(++cptr);
172
 
        while (*cptr && *cptr != '/')
173
 
                cptr++;
174
 
        return (cptr);
175
 
}
176
 
 
177
 
char *proxyurl = NULL;
178
 
unsigned long proxyip = 0;
179
 
unsigned int proxyport;
180
 
 
181
 
#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
182
 
 
183
 
char *httpauth = NULL;
184
 
char httpauth1[256];
185
 
 
186
 
int http_open (char *url)
187
 
{
188
 
        char *purl, *host, *request, *sptr;
189
 
        int linelength;
190
 
        unsigned long myip;
191
 
        unsigned int myport;
192
 
        int sock;
193
 
        int relocate, numrelocs = 0;
194
 
        struct sockaddr_in server;
195
 
        FILE *myfile;
196
 
 
197
 
        if (!proxyip) {
198
 
                if (!proxyurl)
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")) {
203
 
                        host = NULL;
204
 
                        if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport))) {
205
 
                                fprintf (stderr, "Unknown proxy host \"%s\".\n",
206
 
                                        host ? host : "");
207
 
                                exit (1);
208
 
                        }
209
 
                        if (host)
210
 
                                free (host);
211
 
                }
212
 
                else
213
 
                        proxyip = INADDR_NONE;
214
 
        }
215
 
        
216
 
        if ((linelength = strlen(url)+200) < 1024)
217
 
                linelength = 1024;
218
 
        if (!(request = malloc(linelength)) || !(purl = malloc(1024))) {
219
 
                fprintf (stderr, "malloc() failed, out of memory.\n");
220
 
                exit (1);
221
 
        }
222
 
        strncpy (purl, url, 1023);
223
 
        purl[1023] = '\0';
224
 
 
225
 
        getauthfromURL(purl,httpauth1);
226
 
 
227
 
        do {
228
 
                strcpy (request, "GET ");
229
 
                if (proxyip != INADDR_NONE) {
230
 
                        if (strncmp(url, "http://", 7))
231
 
                                strcat (request, "http://");
232
 
                        strcat (request, purl);
233
 
                        myport = proxyport;
234
 
                        myip = proxyip;
235
 
                }
236
 
                else {
237
 
                        host = NULL;
238
 
                        if (!(sptr = url2hostport(purl, &host, &myip, &myport))) {
239
 
                                fprintf (stderr, "Unknown host \"%s\".\n",
240
 
                                        host ? host : "");
241
 
                                exit (1);
242
 
                        }
243
 
                        strcat (request, sptr);
244
 
                }
245
 
                sprintf (request + strlen(request),
246
 
                        " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
247
 
                        prgName, prgVersion);
248
 
                if (host) {
249
 
                        sprintf(request + strlen(request),
250
 
                                "Host: %s:%u\r\n", host, myport);
251
 
                        free (host);
252
 
                }
253
 
 
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) {
259
 
                        perror ("socket");
260
 
                        exit (1);
261
 
                }
262
 
                if (connect(sock, (struct sockaddr *)&server, sizeof(server))) {
263
 
                        perror ("connect");
264
 
                        exit (1);
265
 
                }
266
 
 
267
 
                if (strlen(httpauth1) || httpauth) {
268
 
                        char buf[1023];
269
 
                        strcat (request,"Authorization: Basic ");
270
 
                        if(strlen(httpauth1))
271
 
                          encode64(httpauth1,buf);
272
 
                        else
273
 
                          encode64(httpauth,buf);
274
 
                        strcat (request,buf);
275
 
                        strcat (request,"\r\n");
276
 
                }
277
 
                strcat (request, "\r\n");
278
 
 
279
 
                writestring (sock, request);
280
 
                if (!(myfile = fdopen(sock, "rb"))) {
281
 
                        perror ("fdopen");
282
 
                        exit (1);
283
 
                };
284
 
                relocate = FALSE;
285
 
                purl[0] = '\0';
286
 
                readstring (request, linelength-1, myfile);
287
 
                if ((sptr = strchr(request, ' '))) {
288
 
                        switch (sptr[1]) {
289
 
                                case '3':
290
 
                                        relocate = TRUE;
291
 
                                case '2':
292
 
                                        break;
293
 
                                default:
294
 
                                        fprintf (stderr, "HTTP request failed: %s",
295
 
                                                sptr+1); /* '\n' is included */
296
 
                                        exit (1);
297
 
                        }
298
 
                }
299
 
                do {
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);
305
 
        if (relocate) {
306
 
                fprintf (stderr, "Too many HTTP relocations.\n");
307
 
                exit (1);
308
 
        }
309
 
        free (purl);
310
 
        free (request);
311
 
 
312
 
        return sock;
313
 
}
314
 
 
315
 
#else
316
 
#include <stdlib.h>
317
 
#include <stdio.h>
318
 
#include <string.h>
319
 
 
320
 
extern int errno;
321
 
 
322
 
#include "mpg123.h"
323
 
 
324
 
void writestring (int fd, char *string)
325
 
{
326
 
}
327
 
 
328
 
void readstring (char *string, int maxlen, FILE *f)
329
 
{
330
 
}
331
 
 
332
 
char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
333
 
{
334
 
}
335
 
 
336
 
char *proxyurl = NULL;
337
 
unsigned long proxyip = 0;
338
 
unsigned int proxyport;
339
 
 
340
 
#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
341
 
 
342
 
int http_open (char *url)
343
 
{
344
 
}
345
 
#endif
346
 
 
347
 
/* EOF */
348