OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [khttpd/] [rfc.c] - Rev 1765

Compare with Previous | Blame | View Log

/*
 
kHTTPd -- the next generation
 
RFC related functions (headers and stuff)
 
*/
 
/****************************************************************
 *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 ****************************************************************/
 
 
#include <linux/kernel.h>
 
#include <linux/ctype.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/net.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/unistd.h>
#include <linux/file.h>
#include <linux/smp_lock.h>
 
#include <net/ip.h>
#include <net/sock.h>
 
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
 
 
#include "prototypes.h"
#include "structure.h"
#include "sysctl.h"
 
 
#define KHTTPD_NUMMIMETYPES 	40
 
static atomic_t	MimeCount;
 
struct MimeType
{
	__u32 	identifier;
	char	type[64-sizeof(__u32)-sizeof(__kernel_size_t)];  
	__kernel_size_t	len;
};
 
static struct MimeType	MimeTypes[KHTTPD_NUMMIMETYPES];
 
 
void AddMimeType(const char *Ident,const char *Type)
{	
	__u32	*I;
 
	EnterFunction("AddMimeType");
 
	if (strlen(Ident)!=4) 
   	{	
   		(void)printk(KERN_ERR "httpd: Only 4-byte mime-identifiers are accepted\n");
   		return;
   	}
 
	if (strlen(Type)>(64-sizeof(__u32)-sizeof(__kernel_size_t) ) )  
   	{	
   		(void)printk(KERN_ERR "httpd: Mime-string too long.\n");
   		return;
   	}
 
   	I=(__u32*)Ident;
 
   	/* FIXME: Need to lock-down all access to the mime-structure here */
   	/*        For now, just don't add mime-types after initialisation */
 
 
   	MimeTypes[atomic_read(&MimeCount)].identifier=*I;
   	strncpy(MimeTypes[atomic_read(&MimeCount)].type,Type,(64-sizeof(__u32)-sizeof(__kernel_size_t)));
   	MimeTypes[atomic_read(&MimeCount)].len = strlen(Type);
 
   	atomic_inc(&MimeCount);
   	LeaveFunction("AddMimeType");
}
 
 
char *ResolveMimeType(const char *File,__kernel_size_t *Len)
/*
 
	The returned string is for READ ONLY, ownership of the memory is NOT
	transferred.
 
*/
{	
	__u32	*I;
	int pos,lc,filelen;
 
	EnterFunction("ResolveMimeType");
 
	*Len = 0;
 
	if (File==NULL)
		return NULL;
 
	filelen = (int)strlen(File);
 
	if (filelen<4) 
   	{	
   		return NULL;
   	}
 
   	/* The Merced-people are NOT going to like this! So this has to be fixed
   	   in a later stage. */
 
	pos = filelen-4;
   	I=(__u32*)(File+pos);
 
   	lc=0;
 
   	while (lc<atomic_read(&MimeCount))
 	{
   		if (MimeTypes[lc].identifier == *I)
   		{
   			*Len = MimeTypes[lc].len;
   			LeaveFunction("ResolveMimeType - success");
   	  		return MimeTypes[lc].type;
   	  	}
   	  	lc++;
   	} 	
 
	if (sysctl_khttpd_sloppymime)
	{
		*Len = MimeTypes[0].len;  
		LeaveFunction("ResolveMimeType - unknown");
	   	return MimeTypes[0].type;
	}
	else
	{
		LeaveFunction("ResolveMimeType - failure");
	   	return NULL;
	}
}
 
 
static char HeaderPart1[] = "HTTP/1.0 200 OK\r\nServer: kHTTPd/0.1.6\r\nDate: ";
#ifdef BENCHMARK
static char HeaderPart1b[] ="HTTP/1.0 200 OK";
#endif
static char HeaderPart3[] = "\r\nContent-type: ";
static char HeaderPart5[] = "\r\nLast-modified: ";
static char HeaderPart7[] = "\r\nContent-length: ";
static char HeaderPart9[] = "\r\n\r\n";
 
#ifdef BENCHMARK
/* In BENCHMARK-mode, just send the bare essentials */
void SendHTTPHeader(struct http_request *Request)
{
	struct msghdr	msg;
	mm_segment_t	oldfs;
	struct iovec	iov[9];
	int 		len,len2;
 
 
	EnterFunction("SendHTTPHeader");
 
	msg.msg_name     = 0;
	msg.msg_namelen  = 0;
	msg.msg_iov	 = &iov[0];
	msg.msg_iovlen   = 6;
	msg.msg_control  = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags    = 0;  /* Synchronous for now */
 
	iov[0].iov_base = HeaderPart1b;
	iov[0].iov_len  = 15;
	iov[1].iov_base = HeaderPart3;
	iov[1].iov_len  = 16;
	iov[2].iov_base = Request->MimeType;
	iov[2].iov_len  = Request->MimeLength;
 
	iov[3].iov_base = HeaderPart7;
	iov[3].iov_len  = 18;
 
 
	sprintf(Request->LengthS,"%i",Request->FileLength);
	iov[4].iov_base = Request->LengthS;
	iov[4].iov_len  = strlen(Request->LengthS);
	iov[5].iov_base = HeaderPart9;
	iov[5].iov_len  = 4;
 
	len2=15+16+18+iov[2].iov_len+iov[4].iov_len+4;
 
 
	len = 0;
 
 
	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock_sendmsg(Request->sock,&msg,len2);
	set_fs(oldfs);
 
 
	return;	
}
#else
void SendHTTPHeader(struct http_request *Request)
{
	struct msghdr	msg;
	mm_segment_t	oldfs;
	struct iovec	iov[9];
	int 		len,len2;
	__kernel_size_t	slen;
 
	EnterFunction("SendHTTPHeader");
 
	msg.msg_name     = 0;
	msg.msg_namelen  = 0;
	msg.msg_iov	 = &(iov[0]);
	msg.msg_iovlen   = 9;
	msg.msg_control  = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags    = 0;  /* Synchronous for now */
 
	iov[0].iov_base = HeaderPart1;
	iov[0].iov_len  = 45;
	iov[1].iov_base = CurrentTime;
	iov[1].iov_len  = 29;
	iov[2].iov_base = HeaderPart3;
	iov[2].iov_len  = 16;
 
	iov[3].iov_base = Request->MimeType;
	iov[3].iov_len  = Request->MimeLength;
 
	iov[4].iov_base = HeaderPart5;
	iov[4].iov_len  = 17;
	iov[5].iov_base = &(Request->TimeS[0]);
	iov[5].iov_len  = 29;
	iov[6].iov_base = HeaderPart7;
	iov[6].iov_len  = 18;
	iov[7].iov_base = &(Request->LengthS[0]);
	slen = strlen(Request->LengthS); 
	iov[7].iov_len  = slen;
	iov[8].iov_base = HeaderPart9;
	iov[8].iov_len  = 4;
 
	len2=45+2*29+16+17+18+slen+4+iov[3].iov_len;
 
	len = 0;
 
	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock_sendmsg(Request->sock,&msg,len2);
	set_fs(oldfs);
	LeaveFunction("SendHTTPHeader");
 
 
	return;	
}
#endif
 
 
 
/* 
 
Parse a HTTP-header. Be careful for buffer-overflows here, this is the most important
place for this, since the remote-user controls the data.
 
*/
void ParseHeader(char *Buffer,const int length, struct http_request *Head)
{
	char *Endval,*EOL,*tmp;
 
	EnterFunction("ParseHeader");
	Endval = Buffer + length;
 
	/* We want to parse only the first header if multiple headers are present */
	tmp = strstr(Buffer,"\r\n\r\n"); 
	if (tmp!=NULL)
	    Endval = tmp;
 
 
	while (Buffer<Endval)
	{
		if (isspace(Buffer[0]))
		{
			Buffer++;
			continue;
		}
 
 
		EOL=strchr(Buffer,'\n');
 
		if (EOL==NULL) EOL=Endval;
 
		if (EOL-Buffer<4) 
		{
			Buffer++;
			continue;
		}
 
		if (strncmp("GET ",Buffer,4)==0)
		{
			int PrefixLen;
			Buffer+=4;
 
			tmp=strchr(Buffer,' ');
			if (tmp==0) 
			{
				tmp=EOL-1;
				Head->HTTPVER = 9;
			} else
				Head->HTTPVER = 10;
 
			if (tmp>Endval) continue;
 
			strncpy(Head->FileName,sysctl_khttpd_docroot,sizeof(Head->FileName));
			PrefixLen = strlen(sysctl_khttpd_docroot);
			Head->FileNameLength = min_t(unsigned int, 255, tmp - Buffer + PrefixLen);		
 
			strncat(Head->FileName,Buffer,min_t(unsigned int, 255 - PrefixLen, tmp - Buffer));
 
			Buffer=EOL+1;	
#ifdef BENCHMARK
			break;
#endif						
			continue;
		}
#ifndef BENCHMARK		
		if (strncmp("If-Modified-Since: ",Buffer,19)==0)
		{
			Buffer+=19;
 
			strncpy(Head->IMS,Buffer,min_t(unsigned int, 127,EOL-Buffer-1));
 
			Buffer=EOL+1;	
			continue;
		}
 
		if (strncmp("User-Agent: ",Buffer,12)==0)
		{
			Buffer+=12;
 
			strncpy(Head->Agent,Buffer,min_t(unsigned int, 127,EOL-Buffer-1));
 
			Buffer=EOL+1;	
			continue;
		}
 
 
		if (strncmp("Host: ",Buffer,6)==0)
		{
			Buffer+=6;
 
			strncpy(Head->Host,Buffer,min_t(unsigned int, 127,EOL-Buffer-1));
 
			Buffer=EOL+1;	
			continue;
		}
#endif		
		Buffer = EOL+1;  /* Skip line */
	}
	LeaveFunction("ParseHeader");
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.