📄 httpd.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 + -