/[axel]/trunk/http.c
ViewVC logotype

Contents of /trunk/http.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 66 - (hide annotations) (download)
Mon Dec 1 16:42:05 2008 UTC (4 years, 5 months ago) by phihag-guest
File MIME type: text/plain
File size: 5872 byte(s)
Evade download accelerator blocking and save bandwidth

1 appaji-guest 2 /********************************************************************\
2     * Axel -- A lighter download accelerator for Linux and other Unices. *
3     * *
4     * Copyright 2001 Wilmer van der Gaast *
5     \********************************************************************/
6    
7     /* HTTP control file */
8    
9     /*
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU General Public License for more details.
19    
20     You should have received a copy of the GNU General Public License with
21     the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL;
22     if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23     Suite 330, Boston, MA 02111-1307 USA
24     */
25    
26     #include "axel.h"
27    
28     int http_connect( http_t *conn, int proto, char *proxy, char *host, int port, char *user, char *pass )
29     {
30     char base64_encode[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
31     "abcdefghijklmnopqrstuvwxyz0123456789+/";
32     char auth[MAX_STRING];
33     conn_t tconn[1];
34     int i;
35    
36     strncpy( conn->host, host, MAX_STRING );
37     conn->proto = proto;
38    
39     if( proxy != NULL ) { if( *proxy != 0 )
40     {
41     sprintf( conn->host, "%s:%i", host, port );
42     if( !conn_set( tconn, proxy ) )
43     {
44 appaji-guest 6 /* We'll put the message in conn->headers, not in request */
45     sprintf( conn->headers, _("Invalid proxy string: %s\n"), proxy );
46 appaji-guest 2 return( 0 );
47     }
48     host = tconn->host;
49     port = tconn->port;
50     conn->proxy = 1;
51     }
52     else
53     {
54     conn->proxy = 0;
55     } }
56    
57     if( ( conn->fd = tcp_connect( host, port, conn->local_if ) ) == -1 )
58     {
59 appaji-guest 6 /* We'll put the message in conn->headers, not in request */
60     sprintf( conn->headers, _("Unable to connect to server %s:%i\n"), host, port );
61 appaji-guest 2 return( 0 );
62     }
63    
64     if( *user == 0 )
65     {
66     *conn->auth = 0;
67     }
68     else
69     {
70     memset( auth, 0, MAX_STRING );
71     snprintf( auth, MAX_STRING, "%s:%s", user, pass );
72     for( i = 0; auth[i*3]; i ++ )
73     {
74     conn->auth[i*4] = base64_encode[(auth[i*3]>>2)];
75     conn->auth[i*4+1] = base64_encode[((auth[i*3]&3)<<4)|(auth[i*3+1]>>4)];
76     conn->auth[i*4+2] = base64_encode[((auth[i*3+1]&15)<<2)|(auth[i*3+2]>>6)];
77     conn->auth[i*4+3] = base64_encode[auth[i*3+2]&63];
78     if( auth[i*3+2] == 0 ) conn->auth[i*4+3] = '=';
79     if( auth[i*3+1] == 0 ) conn->auth[i*4+2] = '=';
80     }
81     }
82    
83     return( 1 );
84     }
85    
86     void http_disconnect( http_t *conn )
87     {
88     if( conn->fd > 0 )
89     close( conn->fd );
90     conn->fd = -1;
91     }
92    
93     void http_get( http_t *conn, char *lurl )
94     {
95     *conn->request = 0;
96     if( conn->proxy )
97     {
98     http_addheader( conn, "GET %s://%s%s HTTP/1.0",
99     conn->proto == PROTO_HTTP ? "http" : "ftp", conn->host, lurl );
100     }
101     else
102     {
103     http_addheader( conn, "GET %s HTTP/1.0", lurl );
104     http_addheader( conn, "Host: %s", conn->host );
105     }
106     if( *conn->auth )
107     http_addheader( conn, "Authorization: Basic %s", conn->auth );
108     if( conn->firstbyte )
109     {
110     if( conn->lastbyte )
111 appaji-guest 25 http_addheader( conn, "Range: bytes=%lld-%lld", conn->firstbyte, conn->lastbyte );
112 phihag-guest 66 else if (conn->firstbyte > 1)
113 appaji-guest 25 http_addheader( conn, "Range: bytes=%lld-", conn->firstbyte );
114 appaji-guest 2 }
115     }
116    
117     void http_addheader( http_t *conn, char *format, ... )
118     {
119     char s[MAX_STRING];
120     va_list params;
121    
122     va_start( params, format );
123     vsnprintf( s, MAX_STRING - 3, format, params );
124     strcat( s, "\r\n" );
125     va_end( params );
126    
127     strncat( conn->request, s, MAX_QUERY );
128     }
129    
130     int http_exec( http_t *conn )
131     {
132     int i = 0;
133     char s[2] = " ", *s2;
134    
135     #ifdef DEBUG
136     fprintf( stderr, "--- Sending request ---\n%s--- End of request ---\n", conn->request );
137     #endif
138    
139     http_addheader( conn, "" );
140     write( conn->fd, conn->request, strlen( conn->request ) );
141    
142     *conn->headers = 0;
143     /* Read the headers byte by byte to make sure we don't touch the
144     actual data */
145     while( 1 )
146     {
147     if( read( conn->fd, s, 1 ) <= 0 )
148     {
149 appaji-guest 6 /* We'll put the message in conn->headers, not in request */
150     sprintf( conn->headers, _("Connection gone.\n") );
151 appaji-guest 2 return( 0 );
152     }
153     if( *s == '\r' )
154     {
155     continue;
156     }
157     else if( *s == '\n' )
158     {
159     if( i == 0 )
160     break;
161     i = 0;
162     }
163     else
164     {
165     i ++;
166     }
167     strncat( conn->headers, s, MAX_QUERY );
168     }
169    
170     #ifdef DEBUG
171     fprintf( stderr, "--- Reply headers ---\n%s--- End of headers ---\n", conn->headers );
172     #endif
173    
174     sscanf( conn->headers, "%*s %3i", &conn->status );
175     s2 = strchr( conn->headers, '\n' ); *s2 = 0;
176     strcpy( conn->request, conn->headers );
177     *s2 = '\n';
178    
179     return( 1 );
180     }
181    
182     char *http_header( http_t *conn, char *header )
183     {
184     char s[32];
185     int i;
186    
187     for( i = 1; conn->headers[i]; i ++ )
188     if( conn->headers[i-1] == '\n' )
189     {
190     sscanf( &conn->headers[i], "%31s", s );
191     if( strcasecmp( s, header ) == 0 )
192     return( &conn->headers[i+strlen(header)] );
193     }
194    
195     return( NULL );
196     }
197    
198 appaji-guest 25 long long int http_size( http_t *conn )
199 appaji-guest 2 {
200     char *i;
201 appaji-guest 25 long long int j;
202 appaji-guest 2
203     if( ( i = http_header( conn, "Content-Length:" ) ) == NULL )
204     return( -2 );
205    
206 appaji-guest 25 sscanf( i, "%lld", &j );
207 appaji-guest 2 return( j );
208     }
209    
210     /* Decode%20a%20file%20name */
211     void http_decode( char *s )
212     {
213     char t[MAX_STRING];
214     int i, j, k;
215    
216     for( i = j = 0; s[i]; i ++, j ++ )
217     {
218     t[j] = s[i];
219     if( s[i] == '%' )
220     if( sscanf( s + i + 1, "%2x", &k ) )
221     {
222     t[j] = k;
223     i += 2;
224     }
225     }
226     t[j] = 0;
227    
228     strcpy( s, t );
229     }
230    
231     void http_encode( char *s )
232     {
233     char t[MAX_STRING];
234     int i, j;
235    
236     for( i = j = 0; s[i]; i ++, j ++ )
237     {
238 phihag-guest 54 /* Fix buffer overflow */
239     if (j >= MAX_STRING - 1) {
240     break;
241     }
242    
243 appaji-guest 2 t[j] = s[i];
244     if( s[i] == ' ' )
245     {
246 phihag-guest 54 /* Fix buffer overflow */
247     if (j >= MAX_STRING - 3) {
248     break;
249     }
250    
251 appaji-guest 2 strcpy( t + j, "%20" );
252     j += 2;
253     }
254     }
255     t[j] = 0;
256    
257     strcpy( s, t );
258     }

  ViewVC Help
Powered by ViewVC 1.1.5