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

📄 http.c

📁 微型浏览器
💻 C
字号:
/******************************************************************************* * * http.c * * Provides the means for communicating with remote servers via http * * Version info etc. *  * Cheetah Web Browser * Copyright (C) 2001 Garett Spencley  *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  * *******************************************************************************/#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <stdlib.h>#include <netdb.h>#include <netinet/in.h>#include <unistd.h>#include "http.h"#include "error.h"#include "cheetah.h"#include "debug.h"int sock_fd;int sock_fd_open;int connected;char *hostname;int http_errno;int http_connection_open(void){	return connected;}/* * http_connect() - establishes a remote http connection to  * host. Returns 0 on success. Returns -1 on failure and * http_errno is set appropriately */int http_connect(char *host, unsigned short port, GuiMessage *msg){	struct hostent *hp;	struct sockaddr_in sin;	/* Bail out if we're already connected */	if(connected) 		return HTTP_ALREADY_CONNECTED;		/* Set the hostname */	hostname = strdup(host);	if(!hostname) {		http_errno = HTTP_NOMEM;		return -1;	}	snprintf(msg->text, 255, "Looking up host %s...", hostname);	msg->text[255] = 0;	msg->seq++;	/* Resolve the host */	hp = gethostbyname(hostname);	if(!hp)		hp = gethostbyaddr(hostname, strlen(hostname), AF_INET);	if(!hp) {		http_errno = HTTP_RESOLV;		return -1;	}	sin.sin_family = hp->h_addrtype;	memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);	sin.sin_port = htons(port);	memset(sin.sin_zero, 0, sizeof(sin.sin_zero));	strcpy(msg->text, "Connecting...");	msg->seq++;	if((sock_fd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {		http_errno = HTTP_CONNECT;		return -1;	}	if(connect(sock_fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {    	close(sock_fd);		http_errno = HTTP_CONNECT;		return -1;	}	sock_fd_open = 1;	connected    = 1;	snprintf(msg->text, 255, "Connected to %s", hostname);	msg->text[255] = 0;	msg->seq++;	return 0;}/* * http_close() - closes a http connection */int http_close(){	if(!connected)		return 0;	connected = 0;		free(hostname);	if(sock_fd_open) {		close(sock_fd);		sock_fd_open = 0;	}	return 0;}/* * http_nget() - retrive only size bytes from file storing the * result in buffer */int http_nget(char *buffer, FILE *file, size_t size, GuiMessage *msg){	int counter;	int c;	if(!buffer || !file) {		fprintf(stderr, "http_nget: Received NULL arguments.\n");		return -1;	}	/* char by char instead of fgets() for status	 * reporting .... */	counter = 0;	debug_print("Transfering %d bytes", size);	while(counter != size) {		c = fgetc(file);		if(c == EOF)			break;		buffer[counter++] = c;		if (((counter % 512) == 0) && (size > 0)) {			snprintf(msg->text, 255, "Received %d of %d bytes (%d%%)", counter, size,				((counter * 100) / size));			msg->text[255] = 0;			msg->seq++;		}	}//	buffer[counter] = 0;	/*if (counter == size) {		strcpy(msg->text, "Done.");		msg->seq++;	}*/		return 0;}/*  * get_all() - Retrieve the entire contents of file and * return it in a dynamically allocated buffer */char *get_all(FILE *file, int *bytes, GuiMessage *msg){	char *result;	int c, counter;	int bufsize;	bufsize = 2048;	result = (char *)malloc(sizeof(char) * bufsize);	if(!result)		return NULL;	counter = 0;	while((c = fgetc(file)) != EOF) {				if(counter >= bufsize) {			bufsize += 256;			result = (char *)realloc(result, sizeof(char) * bufsize);			if(!result) 				return NULL;		}		result[counter++] = c;		if ( (counter % 512) == 0 ) {			snprintf(msg->text, 255, "Received %d bytes", counter);			msg->text[255] = 0;			msg->seq++;		}	}//	result[counter] = 0;/*	strcpy(msg->text, "Done.");	msg->seq++; */	*bytes = counter;	return result;}void http_file_free(HttpFile *file){	g_return_if_fail(file != NULL && file->data != NULL && 					file->content_type != NULL);		free(file->data);	free(file->content_type);	free(file);}/* * http_get() - retrieves remote document from server * storing it in a buffer_t. You must call http_connect() * before using this function */HttpFile *http_get(char *path, GuiMessage *msg){	FILE *sock;	char buf[255];	char content_type[256];	int size;	HttpFile *result;	/* Check for open connection */	if(!connected) {		http_errno = HTTP_ALREADY_CONNECTED;		return NULL;	}		if(!sock_fd_open) {		http_errno = HTTP_NOT_CONNECTED;		return NULL;	}	/* Re-open the socket as a FILE stream */	sock = fdopen(sock_fd, "r+");	if(!sock) {		close(sock_fd);		http_errno = HTTP_FILE_DESC;		return NULL;	}	sock_fd_open = 0;	/* Send GET command */	strcpy(msg->text,"Politely asking for document");	msg->seq++;	fprintf(sock, "GET %s HTTP/1.0\n", path);	fprintf(sock, "User-Agent: Cheetah %s\n", CHEETAH_VERSION);	fprintf(sock, "Connection: close\n");	fprintf(sock, "Host: %s\n\n", hostname);	fflush(sock);	/* Allocate the file structure */	result = (HttpFile *)malloc(sizeof(HttpFile));	if(!result) {		http_errno = HTTP_NOMEM;		return NULL;	}	/* Retrieve relevant headers. */	size = 0;	while((fgets(buf, 255, sock))) {		if(*buf == '\r' && buf[1] == '\n')			break;		sscanf(buf, "Content-Length: %d", &size);		sscanf(buf, "Content-Type: %s", content_type);	}	if(strlen(content_type)) {		result->content_type = strdup(content_type);		if(!result->content_type) {			http_errno = HTTP_NOMEM;			free(result);			return NULL;		}	} else 		result->content_type = strdup("");	if(size < 0) {		fclose(sock);		free(result);		http_errno = HTTP_CONTENT_LENGTH;		return NULL;	}	/* Create the buffer and fill it */	if(size == 0) {		result->data = get_all(sock, &(result->bytes), msg);		if(!result->data) {			fclose(sock);			free(result);			http_errno = HTTP_NOMEM;			return NULL;		}	} else {		result->data = (char *)malloc(sizeof(char) * size);		if(!result->data) {			fclose(sock);			free(result);			http_errno = HTTP_NOMEM;			return NULL;		}				if(http_nget(result->data, sock, size, msg) < 0) 			free(result);		result->bytes = size;	}		fclose(sock);	return result;}/* * http_perror() - prints msg followed by a ':' followed by the * error associated with http_errno (prints it to 'error()' function) */void http_perror(char *msg,char *dest){	char string[512];	int max_len;	snprintf(string, 511, "%s: ", msg);	string[511] = 0;	max_len = 512 - strlen(msg);	switch(http_errno)	{	case HTTP_ERROR_UNKOWN:		strncat(string, "Unkown error.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_ALREADY_CONNECTED:		strncat(string, "Attempted to connect to remote host"						"while already connected.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_RESOLV:		strncat(string, "Unable to resolve hostname.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_CONNECT:		strncat(string, "Unable to connect to remote host.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_NOMEM:		strncat(string, "Out of memory.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_CONTENT_LENGTH:		strncat(string, "Document contained an illegal Content-Length.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_NOT_CONNECTED:		strncat(string, "Attempted to retrieve remote document while not"						"connected to remote server.", max_len-1);		string[max_len-1] = 0;		break;	case HTTP_FILE_DESC:		strncat(string, "Problem with socket file descriptor.", max_len-1);		string[max_len-1] = 0;		break;	default:		strncat(string, "Unkown error.", max_len-1);		string[max_len-1] = 0;		break;	}	if (dest==NULL)		error(string);	else		strncpy(dest,string,255);}

⌨️ 快捷键说明

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