Exemple #1
0
int http_connect( http_t *conn, int proto, char *proxy, char *host, int port, char *user, char *pass )
{
	char base64_encode[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz0123456789+/";
	char auth[MAX_STRING], pauth[MAX_STRING];
	char *ppass, *puser;
	conn_t tconn[1];
	int i;
	
	strncpy( conn->host, host, MAX_STRING );
	conn->proto = proto;
	
	if( proxy != NULL ) { if( *proxy != 0 )
	{
		sprintf( conn->host, "%s:%i", host, port );
		if( !conn_set( tconn, proxy ) )
		{
			/* We'll put the message in conn->headers, not in request */
			sprintf( conn->headers, _("Invalid proxy string: %s\n"), proxy );
			return( 0 );
		}
		host = tconn->host;
		port = tconn->port;
		puser = tconn->user;
		ppass = tconn->pass;
		conn->proxy = 1;
	}
	else
	{
		conn->proxy = 0;
	} }
	
	if( ( conn->fd = tcp_connect( host, port, conn->local_if ) ) == -1 )
	{
		/* We'll put the message in conn->headers, not in request */
		sprintf( conn->headers, _("Unable to connect to server %s:%i\n"), host, port );
		return( 0 );
	}
	
	if( *user == 0 )
	{
		*conn->auth = 0;
	}
	else
	{
		memset( auth, 0, MAX_STRING );
		snprintf( auth, MAX_STRING, "%s:%s", user, pass );
		for( i = 0; auth[i*3]; i ++ )
		{
			conn->auth[i*4] = base64_encode[(auth[i*3]>>2)];
			conn->auth[i*4+1] = base64_encode[((auth[i*3]&3)<<4)|(auth[i*3+1]>>4)];
			conn->auth[i*4+2] = base64_encode[((auth[i*3+1]&15)<<2)|(auth[i*3+2]>>6)];
			conn->auth[i*4+3] = base64_encode[auth[i*3+2]&63];
			if( auth[i*3+2] == 0 ) conn->auth[i*4+3] = '=';
			if( auth[i*3+1] == 0 ) conn->auth[i*4+2] = '=';
		}
	}
	
	if( *puser == 0 )
	{
		*conn->proxy_auth = 0;
	}
	else
	{
		memset( pauth, 0, MAX_STRING );
		snprintf( pauth, MAX_STRING, "%s:%s", puser, ppass );
		for( i = 0; pauth[i*3]; i ++ )
		{
			conn->proxy_auth[i*4] = base64_encode[(pauth[i*3]>>2)];
			conn->proxy_auth[i*4+1] = base64_encode[((pauth[i*3]&3)<<4)|(pauth[i*3+1]>>4)];
			conn->proxy_auth[i*4+2] = base64_encode[((pauth[i*3+1]&15)<<2)|(pauth[i*3+2]>>6)];
			conn->proxy_auth[i*4+3] = base64_encode[pauth[i*3+2]&63];
			if( pauth[i*3+2] == 0 ) conn->proxy_auth[i*4+3] = '=';
			if( pauth[i*3+1] == 0 ) conn->proxy_auth[i*4+2] = '=';
		}
	}
	return( 1 );
}
Exemple #2
0
/* Main 'loop'								*/
void axel_do( axel_t *axel )
{
	fd_set fds[1];
	int hifd, i, j;
	long long int size;
	struct timeval timeval[1];
	
	/* Create statefile if necessary				*/
	if( gettime() > axel->next_state )
	{
		save_state( axel );
		axel->next_state = gettime() + axel->conf->save_state_interval;
	}
	
	/* Wait for data on (one of) the connections			*/
	FD_ZERO( fds );
	hifd = 0;
	for( i = 0; i < axel->conf->num_connections; i ++ )
	{
		if( axel->conn[i].enabled )
			FD_SET( axel->conn[i].fd, fds );
		hifd = max( hifd, axel->conn[i].fd );
	}
	if( hifd == 0 )
	{
		/* No connections yet. Wait...				*/
		usleep( 100000 );
		goto conn_check;
	}
	else
	{
		timeval->tv_sec = 0;
		timeval->tv_usec = 100000;
		/* A select() error probably means it was interrupted
		   by a signal, or that something else's very wrong...	*/
		if( select( hifd + 1, fds, NULL, NULL, timeval ) == -1 )
		{
			axel->ready = -1;
			return;
		}
	}
	
	/* Handle connections which need attention			*/
	for( i = 0; i < axel->conf->num_connections; i ++ )
	if( axel->conn[i].enabled ) {
	if( FD_ISSET( axel->conn[i].fd, fds ) )
	{
		axel->conn[i].last_transfer = gettime();
		size = read( axel->conn[i].fd, buffer, axel->conf->buffer_size );
		if( size == -1 )
		{
			if( axel->conf->verbose )
			{
				axel_message( axel, _("Error on connection %i! "
					"Connection closed"), i );
			}
			axel->conn[i].enabled = 0;
			conn_disconnect( &axel->conn[i] );
			continue;
		}
		else if( size == 0 )
		{
			if( axel->conf->verbose )
			{
				/* Only abnormal behaviour if:		*/
				if( axel->conn[i].currentbyte < axel->conn[i].lastbyte && axel->size != INT_MAX )
				{
					axel_message( axel, _("Connection %i unexpectedly closed"), i );
				}
				else
				{
					axel_message( axel, _("Connection %i finished"), i );
				}
			}
			if( !axel->conn[0].supported )
			{
				axel->ready = 1;
			}
			axel->conn[i].enabled = 0;
			conn_disconnect( &axel->conn[i] );
			continue;
		}
		/* j == Bytes to go					*/
		j = axel->conn[i].lastbyte - axel->conn[i].currentbyte + 1;
		if( j < size )
		{
			if( axel->conf->verbose )
			{
				axel_message( axel, _("Connection %i finished"), i );
			}
			axel->conn[i].enabled = 0;
			conn_disconnect( &axel->conn[i] );
			size = j;
			/* Don't terminate, still stuff to write!	*/
		}
		/* This should always succeed..				*/
		lseek( axel->outfd, axel->conn[i].currentbyte, SEEK_SET );
		if( write( axel->outfd, buffer, size ) != size )
		{
			
			axel_message( axel, _("Write error!") );
			axel->ready = -1;
			return;
		}
		axel->conn[i].currentbyte += size;
		axel->bytes_done += size;
	}
	else
	{
		if( gettime() > axel->conn[i].last_transfer + axel->conf->connection_timeout )
		{
			if( axel->conf->verbose )
				axel_message( axel, _("Connection %i timed out"), i );
			conn_disconnect( &axel->conn[i] );
			axel->conn[i].enabled = 0;
		}
	} }
	
	if( axel->ready )
		return;
	
conn_check:
	/* Look for aborted connections and attempt to restart them.	*/
	for( i = 0; i < axel->conf->num_connections; i ++ )
	{
		if( !axel->conn[i].enabled && axel->conn[i].currentbyte < axel->conn[i].lastbyte )
		{
			if( axel->conn[i].state == 0 )
			{
				conn_set( &axel->conn[i], axel->url->text );
				axel->url = axel->url->next;
				/* axel->conn[i].local_if = axel->conf->interfaces->text;
				axel->conf->interfaces = axel->conf->interfaces->next; */
				if( axel->conf->verbose >= 2 )
					axel_message( axel, _("Connection %i downloading from %s:%i using interface %s"),
				        	      i, axel->conn[i].host, axel->conn[i].port, axel->conn[i].local_if );
				if( pthread_create( axel->conn[i].setup_thread, NULL, setup_thread, &axel->conn[i] ) == 0 )
				{
					axel->conn[i].state = 1;
					axel->conn[i].last_transfer = gettime();
				}
				else
				{
					axel_message( axel, _("pthread error!!!") );
					axel->ready = -1;
				}
			}
			else
			{
				if( gettime() > axel->conn[i].last_transfer + axel->conf->reconnect_delay )
				{
					pthread_cancel( *axel->conn[i].setup_thread );
					axel->conn[i].state = 0;
				}
			}
		}
	}

	/* Calculate current average speed and finish_time		*/
	axel->bytes_per_second = (int) ( (double) ( axel->bytes_done - axel->start_byte ) / ( gettime() - axel->start_time ) );
	axel->finish_time = (int) ( axel->start_time + (double) ( axel->size - axel->start_byte ) / axel->bytes_per_second );

	/* Check speed. If too high, delay for some time to slow things
	   down a bit. I think a 5% deviation should be acceptable.	*/
	if( axel->conf->max_speed > 0 )
	{
		if( (float) axel->bytes_per_second / axel->conf->max_speed > 1.05 )
			axel->delay_time += 10000;
		else if( ( (float) axel->bytes_per_second / axel->conf->max_speed < 0.95 ) && ( axel->delay_time >= 10000 ) )
			axel->delay_time -= 10000;
		else if( ( (float) axel->bytes_per_second / axel->conf->max_speed < 0.95 ) )
			axel->delay_time = 0;
		usleep( axel->delay_time );
	}
	
	/* Ready?							*/
	if( axel->bytes_done == axel->size )
		axel->ready = 1;
}
Exemple #3
0
/* Create a new axel_t structure */
axel_t *axel_new(conf_t *conf, int count, void *url)
{
	search_t *res;
	axel_t *axel;
	url_t *u;
	char *s;
	int i;
#if WIN32
	WSADATA wsaData;
    if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) 
	{
#ifdef DEBUG
        printf("WSAStartup error\n");
#endif
        return NULL;
    }
#endif
	axel = malloc(sizeof(axel_t));
    if (NULL == axel) 
    {
        return NULL;
    }
	memset(axel, 0, sizeof(axel_t));
	*axel->conf = *conf;
	axel->conn = malloc(sizeof(conn_t) * axel->conf->num_connections);
    if (NULL == axel->conn) 
    {
        return NULL;
    }
	memset(axel->conn, 0, sizeof(conn_t) * axel->conf->num_connections);
	if (0 < axel->conf->max_speed)
	{
		if ((float)axel->conf->max_speed / axel->conf->buffer_size < 0.5)
		{
			if (2 <= axel->conf->verbose) 
			{
				axel_message(axel, _("Buffer resized for this speed."));
			}
			axel->conf->buffer_size = axel->conf->max_speed;
		}
		axel->delay_time = (int)((float)1000000 / axel->conf->max_speed * axel->conf->buffer_size * axel->conf->num_connections);
	}
	if (NULL == buffer) 
	{
		buffer = malloc(max(MAX_STRING, axel->conf->buffer_size));
        if (NULL == buffer) 
        {
            return NULL;
        }
	}	
	if (0 == count)
	{
		axel->url = malloc(sizeof(url_t));
        if (NULL == axel->url) 
        {
            return NULL;
        }
		axel->url->next = axel->url;
		strncpy(axel->url->text, (char *)url, MAX_STRING);
	}
	else
	{
		res = (search_t *)url;
		u = axel->url = malloc(sizeof(url_t));
		for (i = 0; i < count; i++)
		{
			strncpy(u->text, res[i].url, MAX_STRING);
			if (i < count - 1)
			{
				u->next = malloc(sizeof(url_t));
				u = u->next;
			}
			else
			{
				u->next = axel->url;
			}
		}
	}

	axel->conn[0].conf = axel->conf;
	if (!conn_set(&axel->conn[0], axel->url->text))
	{
		axel_message(axel, _("Could not parse URL.\n"));
		axel->ready = -1;
		return axel;
	}

	axel->conn[0].local_if = axel->conf->interfaces->text;
	axel->conf->interfaces = axel->conf->interfaces->next;
	
	strncpy(axel->filename, axel->conn[0].file, MAX_STRING);
	http_decode(axel->filename);
	if (0 == *axel->filename) 
	{	
		/* Index page == no fn */
		strncpy(axel->filename, axel->conf->default_filename, MAX_STRING);
	}
	if ((s = strchr(axel->filename, '?')) != NULL && axel->conf->strip_cgi_parameters) 
	{
		*s = 0;		/* Get rid of CGI parameters */
	}
	
	if (!conn_init(&axel->conn[0]))
	{
		axel_message(axel, axel->conn[0].message);
		axel->ready = -1;
		return axel;
	}
	
	/* This does more than just checking the file size, it all depends
	   on the protocol used. */
	if (!conn_info(&axel->conn[0]))
	{
		axel_message(axel, axel->conn[0].message);
		axel->ready = -1;
		return axel;
	}
	s = conn_url(axel->conn);
	strncpy(axel->url->text, s, MAX_STRING);
	if ((axel->size = axel->conn[0].size) != INT_MAX)
	{
		if (axel->conf->verbose > 0) 
		{
			axel_message(axel, _("File size: %lld bytes"), axel->size);
		}
	}
	
	/* Wildcards in URL --> Get complete filename			*/
	if (strchr(axel->filename, '*') || strchr(axel->filename, '?')) 
	{
		strncpy(axel->filename, axel->conn[0].file, MAX_STRING);
	}
	
	return axel;
}
Exemple #4
0
int search_makelist( search_t *results, char *url )
{
    int i, size = 8192, j = 0;
    char *s, *s1, *s2, *s3;
    conn_t conn[1];
    double t;
    
    memset( conn, 0, sizeof( conn_t ) );
    
    conn->conf = results->conf;
    t = gettime();
    if( !conn_set( conn, url ) )
        return( -1 );
    if( !conn_init( conn ) )
        return( -1 );
    if( !conn_info( conn ) )
        return( -1 );
    
    strcpy( results[0].url, url );
    results[0].speed = 1 + 1000 * ( gettime() - t );
    results[0].size = conn->size;
    
    s = malloc( size );
    
    sprintf( s, "http://www.filesearching.com/cgi-bin/s?q=%s&w=a&l=en&"
        "t=f&e=on&m=%i&o=n&s1=%lld&s2=%lld&x=15&y=15",
        conn->file, results->conf->search_amount,
        conn->size, conn->size );
    
    conn_disconnect( conn );
    memset( conn, 0, sizeof( conn_t ) );
    conn->conf = results->conf;
    
    if( !conn_set( conn, s ) )
    {
        free( s );
        return( 1 );
    }
    if( !conn_setup( conn ) )
    {
        free( s );
        return( 1 );
    }
    if( !conn_exec( conn ) )
    {
        free( s );
        return( 1 );
    }
    
    while( ( i = read( conn->fd, s + j, size - j ) ) > 0 )
    {
        j += i;
        if( j + 10 >= size )
        {
            size *= 2;
            s = realloc( s, size );
            memset( s + size / 2, 0, size / 2 );
        }
    }

    conn_disconnect( conn );
    
    s1 = strstr( s, "<pre class=list" );
    s1 = strchr( s1, '\n' ) + 1;
    if( strstr( s1, "</pre>" ) == NULL )
    {
        /* Incomplete list                    */
        free( s );
        return( 1 );
    }
    for( i = 1; strncmp( s1, "</pre>", 6 ) && i < results->conf->search_amount && *s1; i ++ )
    {
        s3 = strchr( s1, '\n' ); *s3 = 0;
        s2 = strrstr( s1, "<a href=" ) + 8;
        *s3 = '\n';
        s3 = strchr( s2, ' ' ); *s3 = 0;
        if( strcmp( results[0].url, s2 ) )
        {
            strncpy( results[i].url, s2, MAX_STRING );
            results[i].size = results[0].size;
            results[i].conf = results->conf;
        }
        else
        {
            /* The original URL might show up        */
            i --;
        }
        for( s1 = s3; *s1 != '\n'; s1 ++ );
        s1 ++;
    }
    
    free( s );
    
    return( i );
}
Exemple #5
0
/* Main 'loop' */
void axel_do(axel_t *axel)
{
#if WIN32
	WSAEVENT hEventObject = WSACreateEvent();
	DWORD byte;
#else
	fd_set fds[1];
	struct timeval timeval[1];
	int hifd;
#endif
	int i;
	long long int remaining, size;

	/* Create statefile if necessary */
	if (axel->next_state < gettime())
	{
		save_state(axel);
		axel->next_state = gettime() + axel->conf->save_state_interval;
	}

	/* Wait for data on (one of) the connections */
#if !WIN32
	FD_ZERO(fds);
	hifd = 0;
	for (i = 0; i < axel->conf->num_connections; i++)
	{
		if (axel->conn[i].enabled) 
		{
			FD_SET(axel->conn[i].fd, fds);
		}
		hifd = max(hifd, axel->conn[i].fd);
	}

	if (0 == hifd)
	{
#ifdef DEBUG
		printf("DEBUG no connection yet. Wait...\n");
#endif
		/* No connections yet. Wait... */
		usleep(100000);
		goto conn_check;
	}
	else
	{
		timeval->tv_sec = 0;
		timeval->tv_usec = 100000;
		/* A select() error probably means it was interrupted
		   by a signal, or that something else's very wrong...	*/
		if (-1 == select(hifd + 1, fds, NULL, NULL, timeval))
		{
			axel->ready = -1;
			return;
		}
	}
#endif

	/* Handle connections which need attention */
	for (i = 0; i < axel->conf->num_connections; i++) 
	{
		if (axel->conn[i].enabled) 
		{
#if WIN32
			if (is_readable(axel, axel->conn[i].fd, hEventObject))
#else
			if (FD_ISSET(axel->conn[i].fd, fds))
#endif
			{
				axel->conn[i].last_transfer = gettime();
#if WIN32
				memset(buffer, 0, max(MAX_STRING, axel->conf->buffer_size));
				size = recv(axel->conn[i].fd, buffer, axel->conf->buffer_size, 0);
#else
				size = read(axel->conn[i].fd, buffer, axel->conf->buffer_size);
#endif
#if WIN32
				if (SOCKET_ERROR == size)
#else
				if (-1 == size)
#endif
				{
#if !WIN32
					if (axel->conf->verbose)
					{
						axel_message( axel, _("Error on connection %i! "
							"Connection closed"), i );
					}
#endif
					axel->conn[i].enabled = 0;
					conn_disconnect(&axel->conn[i]);
					continue;
				}
				else if (0 == size)
				{
					if (axel->conf->verbose)
					{
						/* Only abnormal behaviour if: */
						if (axel->conn[i].currentbyte < axel->conn[i].lastbyte && axel->size != INT_MAX)
						{
							axel_message(axel, _("Connection %i unexpectedly closed"), i);
						}
						else
						{
							axel_message(axel, _("Connection %i finished"), i);
						}
					}
					if (!axel->conn[0].supported)
					{
						axel->ready = 1;
					}
					axel->conn[i].enabled = 0;
					conn_disconnect(&axel->conn[i]);
					continue;
				}
				/* remaining == Bytes to go */
				remaining = axel->conn[i].lastbyte - axel->conn[i].currentbyte + 1;
				if (remaining < size)
				{
					if (axel->conf->verbose)
					{
						axel_message(axel, _("Connection %i finished"), i);
					}
					axel->conn[i].enabled = 0;
					conn_disconnect(&axel->conn[i]);
					size = remaining;
					/* Don't terminate, still stuff to write!	*/
				}
				/* This should always succeed..				*/
#if WIN32
				SetFilePointer(axel->outfd, axel->conn[i].currentbyte, NULL, FILE_BEGIN);
				if (0 == WriteFile(axel->outfd, buffer, size, &byte, NULL))
#else
				lseek(axel->outfd, axel->conn[i].currentbyte, SEEK_SET);
				if (write(axel->outfd, buffer, size) != size)
#endif
				{
					axel_message(axel, _("Write error!"));
					axel->ready = -1;
					return;
				}
				axel->conn[i].currentbyte += size;
				axel->bytes_done += size;
			}
			else
			{
				if (gettime() > axel->conn[i].last_transfer + axel->conf->connection_timeout)
				{
					if (axel->conf->verbose) 
					{
						axel_message(axel, _("Connection %i timed out"), i);
					}
					conn_disconnect(&axel->conn[i]);
					axel->conn[i].enabled = 0;
				}
			}
		}
	}
	if (axel->ready) 
	{
		return;
	}
	
conn_check:
	/* Look for aborted connections and attempt to restart them. */
	for (i = 0; i < axel->conf->num_connections; i++)
	{
		if (!axel->conn[i].enabled 
            && axel->conn[i].currentbyte < axel->conn[i].lastbyte)
		{
			if (0 == axel->conn[i].state)
			{	
				// Wait for termination of this thread
#if WIN32
				WaitForSingleObject(axel->conn[i].setup_thread, INFINITE);
				CloseHandle(axel->conn[i].setup_thread);
#else
				pthread_join(*(axel->conn[i].setup_thread), NULL);
#endif	
				conn_set(&axel->conn[i], axel->url->text);
				axel->url = axel->url->next;
				if (axel->conf->verbose >= 2) 
				{
					axel_message(axel, _("Connection %i downloading from %s:%i using interface %s"), 
						i, axel->conn[i].host, axel->conn[i].port, axel->conn[i].local_if);
				}
				
				axel->conn[i].state = 1;
#if WIN32
				axel->conn[i].setup_thread = CreateThread(NULL, 0, setup_thread_cb, &axel->conn[i], 0, NULL);
				if (NULL != axel->conn[i].setup_thread) 
#else
				if (pthread_create(axel->conn[i].setup_thread, NULL, setup_thread_cb, &axel->conn[i]) == 0)
#endif
				{
					axel->conn[i].last_transfer = gettime();
				}
				else
				{
					axel_message(axel, _("thread error in axel_do!!!"));
					axel->ready = -1;
				}
			}
			else
			{
				if (gettime() > axel->conn[i].last_transfer + axel->conf->reconnect_delay)
				{
#if WIN32
					TerminateThread(axel->conn[i].setup_thread, 0);
                    CloseHandle(axel->conn[i].setup_thread);
#else
					pthread_cancel(*axel->conn[i].setup_thread);
#endif
					axel->conn[i].state = 0;
				}
			}
		}
	}

	/* Calculate current average speed and finish_time		*/
	axel->bytes_per_second = (int)((double)(axel->bytes_done - axel->start_byte) / (gettime() - axel->start_time));
	axel->finish_time = (int)(axel->start_time + (double)(axel->size - axel->start_byte) / axel->bytes_per_second);

	/* Check speed. If too high, delay for some time to slow things
	   down a bit. I think a 5% deviation should be acceptable.	*/
	if (0 < axel->conf->max_speed)
	{
		if (1.05 < (float) axel->bytes_per_second / axel->conf->max_speed) 
		{
			axel->delay_time += 10000;
		}
		else if (((float)axel->bytes_per_second / axel->conf->max_speed < 0.95) 
            && 10000 <= (axel->delay_time)) 
		{
			axel->delay_time -= 10000;
		}
		else if (((float)axel->bytes_per_second / axel->conf->max_speed < 0.95)) 
		{
			axel->delay_time = 0;
		}
		usleep(axel->delay_time);
	}
	
	/* Ready? */
	if (axel->bytes_done == axel->size) 
	{
		axel->ready = 1;
	}
}
Exemple #6
0
/* Get file size and other information					*/
int conn_info( conn_t *conn )
{
	/* It's all a bit messed up.. But it works.			*/
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		ftp_command( conn->ftp, "REST %lld", 1 );
		if( ftp_wait( conn->ftp ) / 100 == 3 ||
		    conn->ftp->status / 100 == 2 )
		{
			conn->supported = 1;
			ftp_command( conn->ftp, "REST %lld", 0 );
			ftp_wait( conn->ftp );
		}
		else
		{
			conn->supported = 0;
		}
		
		if( !ftp_cwd( conn->ftp, conn->dir ) )
			return( 0 );
		conn->size = ftp_size( conn->ftp, conn->file, MAX_REDIR );
		if( conn->size < 0 )
			conn->supported = 0;
		if( conn->size == -1 )
			return( 0 );
		else if( conn->size == -2 )
			conn->size = LLONG_MAX;
	}
	else
	{
		char s[MAX_STRING], *t;
		long long int i = 0;
		
		do
		{
			conn->currentbyte = 1;
			if( !conn_setup( conn ) )
				return( 0 );
			conn_exec( conn );
			conn_disconnect( conn );
			/* Code 3xx == redirect				*/
			if( conn->http->status / 100 != 3 )
				break;
			if( ( t = http_header( conn->http, "location:" ) ) == NULL )
				return( 0 );
			sscanf( t, "%1000s", s ); //this value is related to MAX_STRING
			if( strstr( s, "://" ) == NULL)
			{
				sprintf( conn->http->headers, "%s%s",
					conn_url( conn ), s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			else if( s[0] == '/' )
			{
				snprintf( conn->http->headers, MAX_QUERY, "http://%s:%i%s",
					conn->host, conn->port, s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			conn_set( conn, s );
			i ++;
		}
		while( conn->http->status / 100 == 3 && i < MAX_REDIR );
		
		if( i == MAX_REDIR )
		{
			sprintf( conn->message, _("Too many redirects.\n") );
			return( 0 );
		}
		
		conn->size = http_size( conn->http );
		if( conn->http->status == 206 && conn->size >= 0 )
		{
			conn->supported = 1;
			conn->size ++;
		}
		else if( conn->http->status == 200 || conn->http->status == 206 )
		{
			conn->supported = 0;
			conn->size = LLONG_MAX;
		}
		else
		{
			t = strchr( conn->message, '\n' );
			if( t == NULL )
				sprintf( conn->message, _("Unknown HTTP error.\n") );
			else
				*t = 0;
			return( 0 );
		}
	}
	
	return( 1 );
}
Exemple #7
0
/* Get file size and other information */
int conn_info(conn_t *conn)
{
	/* It's all a bit messed up.. But it works. */
	if (conn->proto == PROTO_FTP && !conn->proxy)
	{
		ftp_command(conn->ftp, "REST %lld", 1);
		if (ftp_wait(conn->ftp) / 100 == 3 
			|| conn->ftp->status / 100 == 2)
		{
			conn->supported = 1;
			ftp_command(conn->ftp, "REST %lld", 0);
			ftp_wait(conn->ftp);
		}
		else
		{
			conn->supported = 0;
		}
		
		if (!ftp_cwd(conn->ftp, conn->dir)) 
		{
			return 0;
		}
		conn->size = ftp_size(conn->ftp, conn->file, MAX_REDIR);
		if (conn->size < 0) 
		{
			conn->supported = 0;
		}
		if (-1 == conn->size) 
		{
			return 0;
		}
		else if (-2 == conn->size) 
		{
			conn->size = INT_MAX;
		}
	}
	else
	{
		char s[MAX_STRING], *t;
		long long int i = 0;
		
		do
		{
			conn->currentbyte = 1;
			if (!conn_setup(conn)) 
			{
				return 0;
			}
			conn_exec(conn);
			conn_disconnect(conn);
			/* Code 3xx == redirect */
			if (3 != conn->http->status / 100) 
			{
				break;
			}
			if (NULL == (t = http_header(conn->http, "location:"))) 
			{
				return 0;
			}
			sscanf(t, "%255s", s);
			if (NULL == strstr(s, "://"))
			{
				sprintf(conn->http->headers, "%s%s", conn_url(conn), s);
				strncpy(s, conn->http->headers, MAX_STRING);
			}
			else if ('/' == s[0])
			{
				sprintf(conn->http->headers, "http://%s:%i%s", conn->host, conn->port, s);
				strncpy(s, conn->http->headers, MAX_STRING);
			}
			conn_set(conn, s);
			i++;
		}
		while (conn->http->status / 100 == 3 && i < MAX_REDIR);
		
		if (i == MAX_REDIR)
		{
			sprintf(conn->message, _("Too many redirects.\n"));
			return 0;
		}
		
		conn->size = http_size(conn->http);
		if (conn->http->status == 206 && conn->size >= 0)
		{
			conn->supported = 1;
			conn->size ++;
		}
		else if (conn->http->status == 200 || conn->http->status == 206)
		{
			conn->supported = 0;
			conn->size = INT_MAX;
		}
		else
		{
			t = strchr(conn->message, '\n');
			if (t == NULL) 
			{
				sprintf(conn->message, _("Unknown HTTP error.\n"));
			}
			else 
			{
				*t = 0;
			}
			return 0;
		}
	}
	
	return 1;
}
Exemple #8
0
/* Create a new axel_t structure					*/
axel_t *axel_new( conf_t *conf, int count, void *url )
{
    SSL_library_init();
    g_ssl_ctx = SSL_CTX_new(SSLv23_client_method());

	search_t *res;
	axel_t *axel;
	url_t *u;
	char *s;
	int i;
	
	axel = malloc( sizeof( axel_t ) );
	memset( axel, 0, sizeof( axel_t ) );
	*axel->conf = *conf;
	axel->conn = malloc( sizeof( conn_t ) * axel->conf->num_connections );
	memset( axel->conn, 0, sizeof( conn_t ) * axel->conf->num_connections );
	if( axel->conf->max_speed > 0 )
	{
		if( (float) axel->conf->max_speed / axel->conf->buffer_size < 0.5 )
		{
			if( axel->conf->verbose >= 2 )
				axel_message( axel, _("Buffer resized for this speed.") );
			axel->conf->buffer_size = axel->conf->max_speed;
		}
		axel->delay_time = (int) ( (float) 1000000 / axel->conf->max_speed * axel->conf->buffer_size * axel->conf->num_connections );
	}
	if( buffer == NULL )
		buffer = malloc( max( MAX_STRING, axel->conf->buffer_size ) );
	
	if( count == 0 )
	{
		axel->url = malloc( sizeof( url_t ) );
		axel->url->next = axel->url;
		strncpy( axel->url->text, (char *) url, MAX_STRING );
	}
	else
	{
		res = (search_t *) url;
		u = axel->url = malloc( sizeof( url_t ) );
		for( i = 0; i < count; i ++ )
		{
			strncpy( u->text, res[i].url, MAX_STRING );
			if( i < count - 1 )
			{
				u->next = malloc( sizeof( url_t ) );
				u = u->next;
			}
			else
			{
				u->next = axel->url;
			}
		}
	}
	
	axel->conn[0].conf = axel->conf;
	if( !conn_set( &axel->conn[0], axel->url->text ) )
	{
		axel_message( axel, _("Could not parse URL.\n") );
		axel->ready = -1;
		return( axel );
	}

	axel->conn[0].local_if = axel->conf->interfaces->text;
	axel->conf->interfaces = axel->conf->interfaces->next;
	
	strncpy( axel->filename, axel->conn[0].file, MAX_STRING );
	http_decode( axel->filename );
	if( *axel->filename == 0 )	/* Index page == no fn		*/
		strncpy( axel->filename, axel->conf->default_filename, MAX_STRING );
	if( ( s = strchr( axel->filename, '?' ) ) != NULL && axel->conf->strip_cgi_parameters )
		*s = 0;		/* Get rid of CGI parameters		*/
	
	if( !conn_init( &axel->conn[0] ) )
	{
		axel_message( axel, axel->conn[0].message );
		axel->ready = -1;
		return( axel );
	}
	
	/* This does more than just checking the file size, it all depends
	   on the protocol used.					*/
	if( !conn_info( &axel->conn[0] ) )
	{
		axel_message( axel, axel->conn[0].message );
		axel->ready = -1;
		return( axel );
	}
	s = conn_url( axel->conn );
	strncpy( axel->url->text, s, MAX_STRING );
	if( ( axel->size = axel->conn[0].size ) != INT_MAX )
	{
		if( axel->conf->verbose > 0 )
			axel_message( axel, _("File size: %lld bytes"), axel->size );
	}
	
	/* Wildcards in URL --> Get complete filename			*/
	if( strchr( axel->filename, '*' ) || strchr( axel->filename, '?' ) )
		strncpy( axel->filename, axel->conn[0].file, MAX_STRING );
	
	return( axel );
}
Exemple #9
0
/* Get file size and other information					*/
int conn_info( conn_t *conn )
{
	/* It's all a bit messed up.. But it works.			*/
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		ftp_command( conn->ftp, "REST %lld", 1 );
		if( ftp_wait( conn->ftp ) / 100 == 3 ||
		    conn->ftp->status / 100 == 2 )
		{
			conn->supported = 1;
			ftp_command( conn->ftp, "REST %lld", 0 );
			ftp_wait( conn->ftp );
		}
		else
		{
			conn->supported = 0;
		}
		
		if( !ftp_cwd( conn->ftp, conn->dir ) )
			return( 0 );
		conn->size = ftp_size( conn->ftp, conn->file, MAX_REDIR );
		if( conn->size < 0 )
			conn->supported = 0;
		if( conn->size == -1 )
			return( 0 );
		else if( conn->size == -2 )
			conn->size = INT_MAX;
	}
	else
	{
		char s[MAX_STRING], *t;
		long long int i = 0;

		// redirections
		do
		{
			conn->currentbyte = 1;
			if( !conn_setup( conn ) )
				return( 0 );
			conn_exec( conn );
			conn_disconnect( conn );
			/* Code 3xx == redirect				*/
			if( conn->http->status / 100 != 3 )
				break;
			if( ( t = http_header( conn->http, "location:" ) ) == NULL )
				return( 0 );
			// 255 is a little bit small
			sscanf( t, "%1023s", s );
			if( strstr( s, "://" ) == NULL)
			{
				sprintf( conn->http->headers, "%s%s",
					conn_url( conn ), s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			else if( s[0] == '/' )
			{
				sprintf( conn->http->headers, "http://%s:%i%s",
					conn->host, conn->port, s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}

			conn_set( conn, s );
			i ++;
			//printf("***************** Redirect %d : %s\n", (int)i, s);
		}
		while( conn->http->status / 100 == 3 && i < MAX_REDIR );
		
		if( i == MAX_REDIR )
		{
			sprintf( conn->message, _("Too many redirects.\n") );
			return( 0 );
		}
		
		conn->size = http_size( conn->http );
		if( conn->http->status == 206 && conn->size >= 0 )
		{
			conn->supported = 1;
			conn->size ++;
		}
		else if( conn->http->status == 200 || conn->http->status == 206 )
		{
			// 在限速的情况下,此处如果supported设为0的话只能起一个线程
			// 为了不限速(添加unlimit参数),这里supported改为1
			// added by liuyan
			conn->supported = 1;
			//conn->supported = 0;
			//conn->size = INT_MAX;
		}
		else
		{
			t = strchr( conn->message, '\n' );
			if( t == NULL )
				sprintf( conn->message, _("Unknown HTTP error.\n") );
			else
				*t = 0;
			return( 0 );
		}
	}
	
	return( 1 );
}