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

📄 httpd.c

📁 web服务器单片机开发
💻 C
字号:
#include  "uip.h"
#include  "httpd.h"
#include  "fsdata.h"
#include  "symtab.h"
#include  "funcsys.h"
#include  <string.h>

#define HTTP_NOGET        0
#define HTTP_FILE         1
#define HTTP_FUNC		  2

struct httpd_state *hs;
pFS pfs;					//指向文件结构的指针
pFUNC pfunc;				//指向函数结构的指针
#define ISO_G        0x47
#define ISO_E        0x45
#define ISO_T        0x54
#define ISO_slash    0x2f    
#define ISO_c        0x63
#define ISO_g        0x67
#define ISO_i        0x69
#define ISO_space    0x20
#define ISO_nl       0x0a
#define ISO_cr       0x0d
#define ISO_a        0x61
#define ISO_t        0x74
#define ISO_hash     0x23

/*static void aborted(void);			
static void timedout(void);
static void closed(void);*/
static void connected(void);							//private function's declarations
static void acked(void);
static void newdata(void);
static void senddata(void);

void httpd_init(void){
  fs_init();											//文件初始化
  func_init();											//函数初始化
  /* Listen to port 80. */
  uip_listen(HTONS(80));
}

void httpd_appcall(void) {
	hs = (struct httpd_state *)(uip_conn->appstate);
	
	if(uip_connected()) {
		connected();
		return;
	}
	if(uip_newdata()){
		newdata();
	}
	if(uip_acked()) {
		acked();
	}
	if(uip_rexmit() ||uip_newdata()) {
		if(hs->state == HTTP_FILE)//只有在HTTP_FILE状态下,才调用senddata()函数。
			senddata();
	}
}

/*static void aborted(void) {}
static void timedout(void) {}
static void closed(void) {}		暂时不处理这几个函数*/

static void newdata(void){
	int i;
	if(uip_appdata[0] != ISO_G ||
		uip_appdata[1] != ISO_E ||
		uip_appdata[2] != ISO_T ||
		uip_appdata[3] != ISO_space) {
		uip_abort();		
	}
	for(i=4;i<80;i++){					//得到请求字符串
		if(uip_appdata[i]==' '){		//This should be ' ' (GET请求之后紧跟着一个空格)
			uip_appdata[i]=0;
			break;
		}
	}
	if(strstr((char*)&uip_appdata[4],"cgi")){					//获取函数名,处理CGI函数的情况
		for(i=5;i<80;i++){
			if(uip_appdata[i]=='.'){
				uip_appdata[i]=0;
				break;
			}
		}
		pfunc=(pFUNC)Lookup((char*)&uip_appdata[5]);			//查表,注意取地址
		if(pfunc!=NULL){
			char* s;
			s = strstr((char*)&uip_appdata[17],"password=");
			s += 9;
			for(i=0; s[i]!='&';++i)
				pw[i] = s[i];
			pw[i] = 0;
			hs->datalen = 0;									//记住在HTTP_FUNC状态下,设置要发送的数据长度为0
			hs->state = HTTP_FUNC;
			//strcpy(pw,"123233");
			(pfunc->funcname)();
		}
		else{
			pfs = (pFS)Lookup("notfind");
			hs->state = HTTP_FILE;	
		}
	}
	else{														//处理文件的情况
		if((uip_appdata[4]=='/') && (uip_appdata[5]=='\0'))		//这里应该是0,因为在for循环中已经把请求字符串中的' '变成了'\0'
			pfs=(pFS)Lookup("index");
		else{
			char* s;                                                                                                                                                                                    
			s = strtok((char*)&uip_appdata[5],".");				//注意不要漏掉&
			pfs=(pFS)Lookup(s);
		}
		if(pfs == NULL)						//注意这里应该是pfs,而不是pfs->data
			pfs = (pFS)Lookup("notfind");	//如果没有找到请求的文件,打开NotFind文件。
		hs->state = HTTP_FILE;				//切换到HTTP_FILE状态
		hs->dataptr = pfs->data;
		hs->datalen = pfs->len;
	}	
}
		
		
static void connected(void) {	
	hs->state = HTTP_NOGET;					//切换到HTTP_NOGET状态,并将要发送的文件长度设置为0
	hs->datalen = 0;	
}

static void acked(void){
	hs->datalen -= uip_conn->len;
	hs->dataptr += uip_conn->len;
	if(hs->datalen == 0 && hs->state == HTTP_FILE){
		uip_close();
	}
	if(hs->state == HTTP_FUNC)				//假设动态网页的内容在一帧数据中就可以发送完毕,在小型应用中这是可行的。
		uip_close();
}
	
static void senddata(void) {	
	if(hs->datalen > 0)
		uip_send(hs->dataptr, hs->datalen);
}

⌨️ 快捷键说明

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