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

📄 httpd.c

📁 ENC28J60 System HTTP
💻 C
📖 第 1 页 / 共 3 页
字号:
/*,-----------------------------------------------------------------------------------------.| net/httpd|-----------------------------------------------------------------------------------------| this file implements a very basic http server| - support for HTTP POST | - support for http basic auuth (all /adm/.. file acces must be authorized)|| KNOWN PROBLEMS:| - somehow quick&dirty implementation ! sorry for that ;)| - uses some dirty hacks (content length detection etc)| - very big routines without function calls for memory/flash/speed reasons| - not really documented :-\| - http authorization does not work if browser request is split into two packets ! (-> always not authorized)| - httpd_add_prog* only use 16bit as data offset ! -> biggest filesize in avr flash is 65k!!!|| Author   : {{removed according to contest rules}}|            -> circuitcellar.com avr design contest 2006|            -> Entry #AT2616||-----------------------------------------------------------------------------------------| License:| 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 of the License, 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., 51| Franklin St, Fifth Floor, Boston, MA 02110, USA|| http://www.gnu.de/gpl-ger.html`-----------------------------------------------------------------------------------------*/#include "httpd.h"//ACTIVATE DEBUG by editing this file:#include "debug.h"///FIXME: include the .c file here !///       without this sizeof() does not work !! -> is there another way to do this ?!#include "httpd_data.c"struct httpd_conn_struct {	unsigned char state;	unsigned char substate;	unsigned int  file_id;	unsigned long  seq_offset;	unsigned int  data_ptr;	unsigned long data_position;};struct httpd_conn_struct httpd_conn[TCP_SOCKET_COUNT];//initialise connection tablevoid httpd_init(void){	for(unsigned char c=0; c<TCP_SOCKET_COUNT; c++){		httpd_cleanup_conn(c);	}}//initialise/cleanup http connvoid httpd_cleanup_conn(unsigned char i){	if (i<TCP_SOCKET_COUNT){		httpd_conn[i].state = HTTPD_STATE_IDLE;		httpd_conn[i].data_position = 0;	}}//return: how many data bytes should be transferred ?unsigned int httpd_data_in(unsigned char *buffer, unsigned int datapos, unsigned int datalen, unsigned char socketnum, unsigned char *appstate){	unsigned int pos;	unsigned char file_name[8+6+1];	unsigned char file_ext[3+1];	unsigned char f;	unsigned int ret;	unsigned long offset;	unsigned char authorized;	pos = 0;	#if HTTPD_DEBUG2	softuart_puts_progmem("HTTP: SEQ-SEQ_OFFSET_DATA = ");	softuart_put_uint16((tcp_sockets[socketnum].seq-httpd_conn[socketnum].seq_offset)&0xFFFF);	softuart_puts_progmem("\r\n");	#endif  //initialise filename:	for (f=0; f<8+6+1; f++)		file_name[f] = 0;	for (f=0; f<3+1; f++)		file_ext[f] = 0;	switch(httpd_conn[socketnum].state){		case(HTTPD_STATE_IDLE):		//case(HTTPD_STATE_IDLE_r):		//case(HTTPD_STATE_IDLE_rn):		//case(HTTPD_STATE_IDLE_rnr):		//case(HTTPD_STATE_IDLE_rnrn):			//new request, scan for GET/POST:			if ((buffer[datapos + 0] == 'G') && 			    (buffer[datapos + 1] == 'E') && 			    (buffer[datapos + 2] == 'T')){				//get request !				pos = datapos + 3;								f = 0;				//find start of requested url				while(buffer[pos] == ' ')					pos++;				while((buffer[pos] != ' ')  && (buffer[pos] != '\r') && (buffer[pos] != '\n')  && (buffer[pos] != '?') && (pos<datapos+datalen)){					//read requested file,					//read filename:					file_name[f] = buffer[pos];					//read file extension:					/*if (!((file_ext[2] == ' ') || (file_ext[2] == '?'))){						file_ext[0] = file_ext[1];						file_ext[1] = file_ext[2];						file_ext[2] = buffer[pos];					}*/					if (buffer[pos] == '.'){						file_ext[0] = buffer[pos+1];						file_ext[1] = buffer[pos+2];						file_ext[2] = buffer[pos+3];						file_name[f] = 0;						break;					}					if (file_name[f] == '.')						file_name[f] = 0;										if (f<8+6)						f++;						//remove first /					if (file_name[0] == '/')						f=0;					pos++;				}				//if (file_name[f]=='.')				//	file_name[f] = 0;				#if HTTPD_DEBUG				softuart_puts_progmem("HTTP: GET <");								for(f=0;f<8+6 && file_name[f];f++)					softuart_putc(file_name[f]);				softuart_putc('.');				for(f=0;f<3 && file_ext[f];f++)					softuart_putc(file_ext[f]);				softuart_puts_progmem(">.\r\n");				#endif				//set file id:				if (file_name[0] == '/' || string_compare_progmem("index", file_name)){					///show index					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_INDEX;					file_ext[0] = 'h'; //->html				}else if ( string_compare_progmem("site/cam", file_name)){					///show webcam pic					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SITE_CAM;				}else if ( string_compare_progmem("site/temp", file_name)){					///show templog site					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SITE_TEMP;				}else if ( string_compare_progmem("site/io", file_name)){					///show io site					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SITE_IO;				}else if ( string_compare_progmem("site/ficon", file_name)){					///show file icon					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SITE_FILE_ICON_PIC;				}else if ( string_compare_progmem("graph_0", file_name)){					///show tempgraph (use eeprom data)					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_GRAPH0;				}else if ( string_compare_progmem("fs/ls", file_name)){					///show dataflash file list					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_FS_LS;				}else if ( string_compare_progmem("cam/pic", file_name)){					///show webcam image					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_CAM_PIC;				}else if ( string_compare_progmem("cam/busy", file_name)){					///show webcam busy image					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_CAM_BUSY;				}else if ( string_compare_progmem("site/servo", file_name)){					///show servo page					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SERVO_OK;				}else if ( string_compare_progmem_noeof("servo_", file_name)){					///show/set servo pos					//parse number & set servopos (use uint16 parser)					//if you want to show servopos without moving use servo_999.bmp for example					if (string_buffer_to_uint16(&file_name[6])<256)						servo_set_pos(string_buffer_to_uint16(&file_name[6])&0xFF);					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SERVO_POS;				}else if ( string_compare_progmem_noeof("set/", file_name)){					///show port image					if(file_name[7] == '1'){						httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SET_IO_1_PIC;						port_set_portbit(file_name[4], file_name[5], 1);					}else{						httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_SET_IO_0_PIC;						port_set_portbit(file_name[4], file_name[5], 0);					}				//deprecated				//}else if ( string_compare_progmem_noeof("fs/f", file_name)){				//	///show dataflash file with id given (fs/f1234 -> file 1234 !):				//	httpd_conn[socketnum].file_id = 0xFF + string_buffer_to_uint16(&file_name[4]);				}else if ( string_compare_progmem_noeof("fs/", file_name)){					///try to find dataflash file with the given name:					httpd_conn[socketnum].file_id = 0xFF + filesystem_search_file(&file_name[3], &file_ext[0]);					httpd_conn[socketnum].data_ptr = 0; 					if (httpd_conn[socketnum].file_id == 0xFF)						httpd_conn[socketnum].file_id = HTTPD_STATE_IDLE; ///no file found !				}else if ( string_compare_progmem("adm/up", file_name)){					///show upload form					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_UP;				}else if ( string_compare_progmem_noeof("adm/rm/", file_name)){					///try to find dataflash file with the given name:					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_REMOVED;				}else if ( string_compare_progmem("adm/mkfs", file_name)){					///format filesystem question					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_MKFS;				}else if ( string_compare_progmem("adm/mkfs2", file_name)){					///format filesystem exec!					httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_MKFS2;				}else{					///FILE not found -> 404 err					httpd_conn[socketnum].file_id = HTTPD_STATE_IDLE;				}				//initialise substate				httpd_conn[socketnum].substate = HTTPD_SUBSTATE_NONE;			}else if ((buffer[datapos + 0] == 'P') && 					(buffer[datapos + 1] == 'O') && 					(buffer[datapos + 2] == 'S') && 					(buffer[datapos + 3] == 'T')){				//QUICK HACK (TEST!)				httpd_conn[socketnum].file_id = HTTPD_STATE_FILE_POST;				string_progmem_to_buffer(PSTR("adm/"), file_name,4);				//initialise substate				httpd_conn[socketnum].substate = HTTPD_SUBSTATE_NONE;			}			//find the content length!			//use a quick & dirty method for this !!!			//-> we search for *th: <number> 			//   (instead of content-length:)			//			// we do this because to minimize the following problem:			// clen detection DOES NOT work when the header is 			// split into multiple packets & the packetborder			// is anywhere between th: <number> !! FIXME!			if (httpd_conn[socketnum].file_id == 0xFE){				pos = datapos;				//pos+4 because len("th: ") is 4 (fixme: number might be outside packetlen!)				while (pos+4<datapos+datalen){					if (string_compare_progmem_noeof("th: ", &buffer[pos])){						//next is the number ! 						//parse it !						httpd_conn[socketnum].data_position = string_buffer_to_uint32(&buffer[pos+4]);						break;					}					pos++;				}			}			///search for authorization key			authorized = 0;			if (string_compare_progmem_noeof("adm/", file_name)){				//accessing admin zone, search for auth!				#if HTTPD_DEBUG_AUTH				softuart_puts_progmem("HTTPD: auth required! [");				#endif				pos = datapos;								while(pos<datapos+datalen){					//speedup, check first letter					if (buffer[pos] == 'A'){						//if match, call whole function match						if (string_compare_progmem_noeof("Authorization: Basic ", &buffer[pos])){							//got it ! now buf[pos+21]-... has auth string!							unsigned char len;							unsigned char *pwbuff = &buffer[pos+21];							//maximum pw len 100							for(len=0; len < 100; len++){ 								//check buf < '0' is ok because of base64... \r\n & space are smaller ;)								if (pwbuff[len]<'0')									break;								#if HTTPD_DEBUG_AUTH								softuart_putc(pwbuff[len]);								#endif							}							//len--;														//base64 decode, after this the decoded string is in buffer[pos+21]...							base64_decode(&pwbuff[0], len);							#if HTTPD_DEBUG_AUTH							softuart_puts_progmem("], decoded [");							for(len=0; len < 100; len++){								if (pwbuff[len]==0)										break;								softuart_putc(pwbuff[len]);							}							softuart_puts_progmem("] auth? ");							#endif							if (string_compare_progmem(HTTPD_ADMIN_AUTH_LOGIN":"HTTPD_ADMIN_AUTH_PASS, &pwbuff[0])){								//auth passed !!								authorized = 1;							}							#if HTTPD_DEBUG_AUTH							softuart_put_uint8(authorized);							softuart_putnewline();							#endif							break;						}					}					pos++;				}				//check if there was a file remove request				if (authorized && (httpd_conn[socketnum].file_id == HTTPD_STATE_FILE_REMOVED)){					httpd_conn[socketnum].file_id = 0xFF + string_buffer_to_uint16(&file_name[7]);

⌨️ 快捷键说明

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