⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http_get.c

📁 使用纯C编写的http get请求
💻 C
📖 第 1 页 / 共 2 页
字号:
/* http_get - fetch the contents of an http URL**** Originally based on a simple version by Al Globus <globus@nas.nasa.gov>.** Debugged and prettified by Jef Poskanzer <jef@mail.acme.com>.  Also includes** ifdefs to handle https via OpenSSL.*/#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#ifdef USE_SSL#include <openssl/ssl.h>#endif/* Forwards. */static void usage();static int getURL( char* url, char* referer, char* user_agent, char* auth_token, int ncookies, char** cookies );static int getURLbyParts( int protocol, char* host, unsigned short port, char* file, char* referer, char* user_agent, char* auth_token, int ncookies, char** cookies );static int open_client_socket( char* hostname, unsigned short port );static void show_error( char* cause );static void sigcatch( int sig );static int b64_encode( unsigned char* ptr, int len, char* space, int size );/* Globals. */static char* argv0;static int verbose;static int timeout;static char* url;/* Protocol symbols. */#define PROTO_HTTP 0#ifdef USE_SSL#define PROTO_HTTPS 1#endif/* Header FSM states. */#define HDST_LINE1_PROTOCOL 0#define HDST_LINE1_WHITESPACE 1#define HDST_LINE1_STATUS 2#define HDST_BOL 10#define HDST_TEXT 11#define HDST_LF 12#define HDST_CR 13#define HDST_CRLF 14#define HDST_CRLFCR 15#define MAX_COOKIES 20intmain( int argc, char** argv )    {    int argn;    char* referer;    char* user_agent;    char* auth_token;    int ncookies;    char* cookies[MAX_COOKIES];    int status;    argv0 = argv[0];    argn = 1;    verbose = 0;    timeout = 60;    referer = (char*) 0;    user_agent = "http_get";    auth_token = (char*) 0;    ncookies = 0;    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )	{	if ( strcmp( argv[argn], "-v" ) == 0 )	    verbose = 1;	else if ( strcmp( argv[argn], "-t" ) == 0 && argn + 1 < argc )	    {	    ++argn;	    timeout = atoi( argv[argn] );	    }	else if ( strcmp( argv[argn], "-r" ) == 0 && argn + 1 < argc )	    {	    ++argn;	    referer = argv[argn];	    }	else if ( strcmp( argv[argn], "-u" ) == 0 && argn + 1 < argc )	    {	    ++argn;	    user_agent = argv[argn];	    }	else if ( strcmp( argv[argn], "-a" ) == 0 && argn + 1 < argc )	    {	    ++argn;	    auth_token = argv[argn];	    }	else if ( strcmp( argv[argn], "-c" ) == 0 && argn + 1 < argc )	    {	    if ( ncookies >= MAX_COOKIES )		{		(void) fprintf( stderr, "%s: too many cookies\n", argv0 );		exit( 1 );		}	    ++argn;	    cookies[ncookies++] = argv[argn];	    }	else	    usage();	++argn;	}    if ( argn >= argc )	usage();    url = argv[argn];    ++argn;    if ( argn != argc )	usage();    (void) signal( SIGALRM, sigcatch );    status = getURL( url, referer, user_agent, auth_token, ncookies, cookies );    if ( status == 200 )	exit( 0 );    else if ( status == 0 )	exit( 1 );    else	exit( status );    }static voidusage()    {    (void) fprintf( stderr, "usage:  %s [-c cookie] [-t timeout] [-r referer] [-u user-agent] [-a username:password] [-v] url\n", argv0 );    exit( 1 );    }/* URL must be of the form http://host-name[:port]/file-name */static intgetURL( char* url, char* referer, char* user_agent, char* auth_token, int ncookies, char** cookies )    {    char* s;    int protocol;    char host[2000];    int host_len;    unsigned short port;    char* file = (char*) 0;    char* http = "http://";    int http_len = strlen( http );#ifdef USE_SSL    char* https = "https://";    int https_len = strlen( https );#endif /* USE_SSL */    int proto_len;    if ( url == (char*) 0 )        {	(void) fprintf( stderr, "%s: null URL\n", argv0 );        exit( 1 );        }    if ( strncmp( http, url, http_len ) == 0 )	{	proto_len = http_len;	protocol = PROTO_HTTP;	}#ifdef USE_SSL    else if ( strncmp( https, url, https_len ) == 0 )	{	proto_len = https_len;	protocol = PROTO_HTTPS;	}#endif /* USE_SSL */    else        {	(void) fprintf( stderr, "%s: non-http URL\n", argv0 );        exit( 1 );        }    /* Get the host name. */    for ( s = url + proto_len; *s != '\0' && *s != ':' && *s != '/'; ++s )	;    host_len = s - url;    host_len -= proto_len;    strncpy( host, url + proto_len, host_len );    host[host_len] = '\0';    /* Get port number. */    if ( *s == ':' )	{	port = (unsigned short) atoi( ++s );	while ( *s != '\0' && *s != '/' )	    ++s;	}    else#ifdef USE_SSL	if ( protocol == PROTO_HTTPS )	    port = 443;	else	    port = 80;#else	port = 80;#endif    /* Get the file name. */    if ( *s == '\0' )	file = "/";    else	file = s;    return getURLbyParts( protocol, host, port, file, referer, user_agent, auth_token, ncookies, cookies );    }static intgetURLbyParts( int protocol, char* host, unsigned short port, char* file, char* referer, char* user_agent, char* auth_token, int ncookies, char** cookies )    {    int sockfd;#ifdef USE_SSL    SSL_CTX* ssl_ctx;    SSL* ssl;#endif    char buf[20000];    int i, bytes, b, header_state, status;    (void) alarm( timeout );    sockfd = open_client_socket( host, port );#ifdef USE_SSL    if ( protocol == PROTO_HTTPS )	{	/* Make SSL connection. */	int r;	SSL_load_error_strings();	SSLeay_add_ssl_algorithms();	ssl_ctx = SSL_CTX_new( SSLv23_client_method() );	ssl = SSL_new( ssl_ctx );	SSL_set_fd( ssl, sockfd );	r = SSL_connect( ssl );	if ( r <= 0 )	    {	    (void) fprintf(		stderr, "%s: %s - SSL connection failed - %d\n",		argv0, url, r );	    ERR_print_errors_fp( stderr );	    exit( 1 );	    }	}#endif    /* Build request buffer, starting with the GET. */    (void) alarm( timeout );    bytes = snprintf( buf, sizeof(buf), "GET %s HTTP/1.0\r\n", file );    /* HTTP/1.1 host header - some servers want it even in HTTP/1.0. */    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Host: %s\r\n", host );    if ( referer != (char*) 0 )	/* Referer. */	bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Referer: %s\r\n", referer );    /* User-agent. */    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "User-Agent: %s\r\n", user_agent );    /* Fixed headers. */    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Accept: */*\r\n" );    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Accept-Encoding: gzip, compress\r\n" );    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Accept-Language: en\r\n" );    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Accept-Charset: iso-8859-1,*,utf-8\r\n" );    if ( auth_token != (char*) 0 )	{	/* Basic Auth info. */	char token_buf[1000];	token_buf[b64_encode( auth_token, strlen( auth_token ), token_buf, sizeof(token_buf) )] = '\0';	bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Authorization: Basic %s\r\n", token_buf );	}    /* Cookies. */    for ( i = 0; i < ncookies; ++i )	bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "Cookie: %s\r\n", cookies[i] );    /* Blank line. */    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "\r\n" );    /* Now actually send it. */#ifdef USE_SSL    if ( protocol == PROTO_HTTPS )	(void) SSL_write( ssl, buf, bytes );    else	(void) write( sockfd, buf, bytes );#else    (void) write( sockfd, buf, bytes );#endif    /* Get lines until a blank one. */    (void) alarm( timeout );    header_state = HDST_LINE1_PROTOCOL;    status = 0;    for (;;)	{#ifdef USE_SSL	if ( protocol == PROTO_HTTPS )	    bytes = SSL_read( ssl, buf, sizeof(buf) );	else	    bytes = read( sockfd, buf, sizeof(buf) );#else	bytes = read( sockfd, buf, sizeof(buf) );#endif	if ( bytes <= 0 )	    break;	for ( b = 0; b < bytes; ++b )	    {	    if ( verbose )		(void) write( 1, &buf[b], 1 );	    switch ( header_state )		{		case HDST_LINE1_PROTOCOL:		switch ( buf[b] )		    {		    case ' ': case '\t':		    header_state = HDST_LINE1_WHITESPACE; ; break;		    case '\n': header_state = HDST_LF ; break;		    case '\r': header_state = HDST_CR; break;		    }		break;		case HDST_LINE1_WHITESPACE:		switch ( buf[b] )		    {		    case '0': case '1': case '2': case '3': case '4':		    case '5': case '6': case '7': case '8': case '9':		    status = buf[b] - '0';		    header_state = HDST_LINE1_STATUS;		    break;		    case '\n': header_state = HDST_LF ; break;		    case '\r': header_state = HDST_CR; break;		    default: header_state = HDST_TEXT; break;		    }		break;		case HDST_LINE1_STATUS:		switch ( buf[b] )		    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -