head     1.1;
branch   1.1.1;
access   ;
symbols  init:1.1.1.1 vendor:1.1.1;
locks    ; strict;
comment  @# @;


1.1
date     2006.01.16.11.22.34;  author sctp;  state Exp;
branches 1.1.1.1;
next     ;

1.1.1.1
date     2006.01.16.11.22.34;  author sctp;  state Exp;
branches ;
next     ;


desc
@@



1.1
log
@Initial revision
@
text
@//---------------------------------------------------------------------------
//	HTTP Server over SCTP / HTTP 1.0
//
//	Version		: 0.2
//	Writer		: Kwon bo-kun
//	Date		: 2005/12/11
//	Description	: TCP HTTP1.0 
//	Last Update	: 2006/01/11
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
//	Server 
//
//		http10_server [-pvdb]
//			-p <bind Ʈȣ>
//			-v 			; verbose
//			-d <wwwroot丮>	;  ϵ ġ 
//			-b <۽ ũ>
//
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
//  
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>  // sockaddr_in 
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/stat.h> // stat Լ ü


//#if defined(__FreeBSD__)
//#ifdef _SUNOS
//#ifdef _BSD_SOURCE


//---------------------------------------------------------------------------
//  
//---------------------------------------------------------------------------
#define MAX_LISTENQ		32
#define HTTP_VERSION	"1.0"
#define HTTP_VER		"HTTP/1.0"


//---------------------------------------------------------------------------
//  
//---------------------------------------------------------------------------
int o_verbose = 0;
int o_port = 80;
int o_bufsize = 1024;
char o_wwwroot[256] = "./";


//---------------------------------------------------------------------------
//  Լ 
//---------------------------------------------------------------------------
int		isGetMethod(char *uri);
int		isFileExist(char *filepath);
int		isForbidden(char *filepath);
int		isEmpty(char *filepath);
int		GetFilename(char *uri, char *filepath);
int		ParseRequest(char *buf, char *method, char *uri, char *httpver);
void	ProcessRequest(int sockfd);
void	SendError( int sock, int errorno );
void 	SendOK( int sock );


//---------------------------------------------------------------------------
// α׷ 
//---------------------------------------------------------------------------
int main(int argc, char **argv)
{

	// Program Option
	int opt;
	char o_tmp[10];

	int serv_sock;
	int clnt_sock;
	int sock_reuse = 1;

	struct sockaddr_in serv_addr;
	struct sockaddr_in clnt_addr;

	socklen_t nClntAddrSize;

	while ( (opt = getopt(argc, argv, "vp:d:b:")) != -1) {
		switch (opt)
		{
			case 'v':
				o_verbose = 1;
				break;

			case 'p':
				snprintf(o_tmp, sizeof(o_tmp), "%s", optarg);
				o_port = atoi(o_tmp);
				break;

			case 'd':
				snprintf(o_wwwroot, sizeof(o_wwwroot), "%s", optarg);
				break;

			case 'b':
				snprintf(o_tmp, sizeof(o_tmp), "%s", optarg);
				o_bufsize = atoi(o_tmp);
				break;
		}
	}

	if (o_verbose) {
		printf("HTTP 1.0 over TCP [Server]\n");
		printf("Server Port : [%d]\n", o_port);
	}

	// ϻ
	serv_sock = Socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

	// Ʈ    ɼǺ
	Setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_reuse, sizeof(int));

	// ϱü ʱȭ
	bzero( &serv_addr, sizeof(serv_addr) );
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
	serv_addr.sin_port = htons( o_port );

	//  ε
	Bind( serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

	// 
	Listen( serv_sock, MAX_LISTENQ );

	while ( 1 )
	{
		nClntAddrSize = sizeof( clnt_addr );
		clnt_sock = accept( serv_sock, (struct sockaddr*)&clnt_addr, &nClntAddrSize );
	
		//  
		if (o_verbose) {
			printf("Ŭ̾Ʈ \n");
			fflush(stdout);
		}
		
		// ڽ϶ Ʈ ó
	//if (fork() == 0)
			ProcessRequest( clnt_sock );
	//	else
			//close(clnt_sock);
	}

	return 0;
}


//---------------------------------------------------------------------------
// function : void SendError( int sock, int errorno )
// retvalue : Ŭ̾Ʈ ޽ ش.
//---------------------------------------------------------------------------
void SendError( int sock, int errorno )
{
	char errmsg[100];

	switch( errorno )
	{
		case 204:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 204 Content\r\n");
			break;

		case 400:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 400 Bad Request\r\n");
			break;

		case 404:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 404 Not Found\r\n");
			break;
		
		case 403:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 403 Forbidden\r\n");
			break;

		case 405:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 405 Method Not Found\r\n");
			break;

		case 408:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 408 Request Timeout\r\n");
			break;
		
		case 501:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 501 Not implemented\r\n");
			break;

		default:
			snprintf(errmsg, sizeof(errmsg), HTTP_VER " 505 HTTP Version not supported\r\n");
	}

	send(sock, errmsg, strlen(errmsg), 0);
}

void SendOK( int sock )
{
	char *okmsg = "HTTP/1.0 200 OK\r\n" \
				  "DATE: %s\r\n" \
				  "\r\n";
	char buf[100];

	//snprintf(buf, sizeof(buf), okmsg, time());
	send(sock, okmsg, sizeof(okmsg), 0);
}


// ̸ Ⱑ ϸ -1
// ϸ 0
int GetFilename(char *uri, char *filepath) 
{
	int slen;
	char *p;

	p = uri;

	// http:// Ѵٸ
	if ( ! strncasecmp("http://", uri, 7) )
	{
		p = strchr(&uri[7], '/');
		printf("I'm in strncasecm  p\n" );

		if (!p) 
			return -1;
	}

	slen = strlen(o_wwwroot);
	strcpy(filepath, o_wwwroot);
	filepath[slen] = '\0';

	if ( filepath[slen - 1] != '/' && slen > 1) {
		filepath[slen] = '/';
		filepath[slen+1] = '\0';
	}

	strcat(filepath, p);
	return 0;
}


int ParseRequest(char *buf, char *method, char *uri, char *httpver)
{
	char *request;
	char *tokens[5];
	char *last;
	char *p;
	int i;
	int ret = 0;

	request = strdup(buf);
	for (i=0, (p = strtok_r(request, " \r\n", &last)); p && i < 3; 
		(p = strtok_r(NULL, " \r\n", &last)), i++) {
		tokens[i] = p;
	}

	if (i == 3) {
		strcpy(method, tokens[0]);
		strcpy(uri, tokens[1]);
		strcpy(httpver, tokens[2]);
		ret = 0;
	}

	free(request);

	return ret;
}

int isGetMethod(char *uri)
{
	if ( ! strncasecmp(uri, "GET", 3) ) {
		return 1;
	}

	return 0;
}

int isFileExist(char *filepath)
{
	if (access(filepath, R_OK) < 0) {
		return 0;
	}
	
	return 1;
}

int isForbidden(char *filepath)
{
	if (access(filepath, R_OK) < 0) {
		return 0;
	}

	return 1;
}

int isEmpty(char *filepath)
{
	struct stat st;

	if (stat(filepath, &st) < 0) {
		return -1;
	}

	return (st.st_size) ? 1 : 0;
}



//---------------------------------------------------------------------------
// function : void*	ThreadRoutine( void* data )
// retvalue : Ŭ̾Ʈ ó   ƾ
//---------------------------------------------------------------------------
void ProcessRequest( int sock )
{
	int nBufSize;
	int fd;
	int nRecvSize = 0;
	int nReadSize = 0;
	char headbuf[100];
	char buf[1024];
	char szFileName[256];
	char method[10], uri[256], httpver[10];
	
	memset(buf, 0, sizeof(buf));
	nRecvSize = recv( sock, buf, sizeof(buf), 0 );

	if (o_verbose) {
		printf("[read %d]--------------------------\n%s\n", nRecvSize, buf);
	}

	if ( ParseRequest(buf, method, uri, httpver) < 0) {
		SendError( sock, 400 );
		exit(1);
	}
	
	if ( ! isGetMethod(method) ) {
		SendError( sock, 505 );
		exit(1);
	}

	if ( GetFilename(uri, szFileName) < 0) {
		SendError( sock, 400 );
		exit(1);
	}

	printf("Filename is :%s\n", szFileName);

	if ( ! isFileExist(szFileName) ) {
		SendError( sock, 404 );
		exit(1);
	}

	if ( ! isForbidden(szFileName) ) {
		SendError( sock, 403 );
		exit(1);

	}

	if ( ! isEmpty(szFileName) ) {
		SendError( sock, 204 );
		exit(1);
	}


	// Ͽ
	fd = open( szFileName, O_RDONLY );
	if( fd )
	{
		//     ߶ 
		while ( (nReadSize = read( fd, buf, o_bufsize )) )
		{
			send( sock, buf, nReadSize, 0);
		}
	}

	close( sock );
	close( fd );

	if (o_verbose)
		printf("Ŭ̾Ʈ \n");

	exit(0);
}


@


1.1.1.1
log
@sctp test cvs
@
text
@@
