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

Contents of /trunk/http.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 67 - (show annotations) (download)
Mon Dec 1 16:53:43 2008 UTC (4 years, 6 months ago) by phihag-guest
File MIME type: text/plain
File size: 5847 byte(s)
Revert previous commit because it would disable parallel downloads for compliant servers

1 /********************************************************************\
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 /* We'll put the message in conn->headers, not in request */
45 sprintf( conn->headers, _("Invalid proxy string: %s\n"), proxy );
46 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 /* 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 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 http_addheader( conn, "Range: bytes=%lld-%lld", conn->firstbyte, conn->lastbyte );
112 else
113 http_addheader( conn, "Range: bytes=%lld-", conn->firstbyte );
114 }
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 /* We'll put the message in conn->headers, not in request */
150 sprintf( conn->headers, _("Connection gone.\n") );
151 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 long long int http_size( http_t *conn )
199 {
200 char *i;
201 long long int j;
202
203 if( ( i = http_header( conn, "Content-Length:" ) ) == NULL )
204 return( -2 );
205
206 sscanf( i, "%lld", &j );
207 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 /* Fix buffer overflow */
239 if (j >= MAX_STRING - 1) {
240 break;
241 }
242
243 t[j] = s[i];
244 if( s[i] == ' ' )
245 {
246 /* Fix buffer overflow */
247 if (j >= MAX_STRING - 3) {
248 break;
249 }
250
251 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