📄 httpd_main.c
字号:
/*
* $Id: httpd_main.c,v 1.0 2003/02/21 00:11:04 csm Exp $
* $Copyright: (c) 2002, 2003 Broadcom Corp.
* All Rights Reserved.$
*/
/***********************************************************************
* iMpacct Technology Corporation. Copyright 2001 - 2100. *
* ALL RIGHTS RESERVED *
*----------------------------------------------------------------------*
* Project : RoboSwitch
* Creator : Gary Chen / iMpacct 04/08/2002
* File : httpd_main.c
* Description: Handle HTTP protocol
*
* History:
*
************************************************************************/
#include <sys/sys_config.h>
#include <parm/parm_config.h>
#include <http/http_cfg.h>
#include <http/http_lib.h>
#include <network.h>
static void httpd_connection_task(void);
static void httpd_protocol_task(cyg_handle_t);
static void httpd_service(int conn_fd, HTTPD_CONN_T* hc);
static void httpd_init_conn_table(HTTPD_CONN_T* hc);
static void httpd_free_conn_table(HTTPD_CONN_T* hc);
void httpd_realloc_str(char** strP, int* maxsizeP, int size);
static void httpd_handle_read (HTTPD_CONN_T* hc);
static void httpd_handle_send(HTTPD_CONN_T* hc);
static cyg_handle_t http_mbox_handle;
static cyg_mbox http_mbox_queue;
static http_dbg_cnt=0;
UI32_T httpd_malloc_cnt=0, httpd_free_cnt=0;
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_start
*-----------------------------------------------------------------------
* DESCRIPTION: To initialize the HTTP process
* INPUT : None
* OUTPUT : None
*----------------------------------------------------------------------*/
void httpd_start()
{
ULONG HttpdConnect_tid, HttpdProtocol_tid;
http_init_cfg();
cyg_mbox_create(&http_mbox_handle,&http_mbox_queue);
// start httd_connect_task
sys_create_task("HttpdConnect",httpd_connection_task,(cyg_addrword_t)0,
20, 2048, &HttpdConnect_tid);
// start httd_connect_task
sys_create_task("HttpdProtocol",httpd_protocol_task,(cyg_addrword_t)http_mbox_handle,
19, 2048*10, &HttpdProtocol_tid);
sys_start_task(HttpdConnect_tid);
sys_start_task(HttpdProtocol_tid);
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_connection_task
*-----------------------------------------------------------------------
* DESCRIPTION: Create a httpd connection and wait client's request
* INPUT : None
* OUTPUT : None
*----------------------------------------------------------------------*/
void httpd_connection_task(void)
{
UI32_T port;
UI16_T sport;
int s, newsockfd, one=1, num, addr_len;
struct sockaddr_in server_addr,client_addr;
fd_set in_fds;
http_get_port(&port);
sport=port; // type conversion
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
dprintf("<httpd_connect_task>Failed to create a socket!\n");
return;
}
/* Allow reuse of local addresses. */
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char*) &one, sizeof(one)) < 0)
{
dprintf("<httpd_connect_task>Failed to setsockopt(..SO_REUSEADDR..)!\n");
close(s);
return;
}
memset((char *) &server_addr,0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_len = sizeof(server_addr);
server_addr.sin_port = htons(sport);
if (bind(s, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 ||
listen(s, SOMAXCONN) < 0)
{
dprintf("<httpd_connect_task>Failed to bind a socket!\n");
close(s);
return;
}
FD_ZERO(&in_fds);
FD_SET(s, &in_fds);
while (1)
{
num = select(s+1, &in_fds, (fd_set *)NULL, (fd_set *)NULL, 0);
if (num>0)
{
addr_len = sizeof(struct sockaddr_in);
newsockfd = accept(s, (struct sockaddr *)&client_addr, &addr_len);
if (newsockfd == -1)
continue; // Try again
else
{
// For Linux, fork a process to handle new connect
// for Embedded system, notify http protocol task to handle
// this connection
HTTP_MSG_T *msg;
if ((msg=(HTTP_MSG_T *)httpd_malloc(sizeof(HTTP_MSG_T)))==(HTTP_MSG_T *)0)
{
dprintf("<httpd_connect_task>Failed to allocate memory!\n");
close(newsockfd);
continue;
}
msg->size=sizeof(HTTP_MSG_T);
msg->cmd=HTTP_PKT_CMD;
msg->sock=s;
msg->conn_fd=newsockfd;
if (cyg_mbox_put(http_mbox_handle,msg)==0)
{
dprintf("<httpd_connect_task>Failed to put a message to mbox!\n");
httpd_free(msg);
close(newsockfd);
continue;
}
// OK to notify http protocol task
}
} else {
dprintf("<httpd_connect_task>Failed to select()!\n");
continue; // Try again
}
}
// TBD
// if port is changed, delete old socket and jump to start of this routine
// to re-create a new socket connection
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_protocol_task
*-----------------------------------------------------------------------
* DESCRIPTION: httpd protocol task is used to handle http packet
* INPUT : None
* OUTPUT : None
*----------------------------------------------------------------------*/
void httpd_protocol_task(cyg_handle_t mbox_handle)
{
HTTP_MSG_T *msg;
while (1)
{
msg=(HTTP_MSG_T *)cyg_mbox_get(mbox_handle);
if (!msg || msg->size!=sizeof(HTTP_MSG_T) || msg->cmd!=HTTP_PKT_CMD)
{
dprintf("<httpd_protocol_task>Failed to get a mbox message!\n");
}
else
{
HTTPD_CONN_T *hc;
// test
http_dbg_cnt++;
if (hc=(HTTPD_CONN_T *)httpd_malloc(sizeof(HTTPD_CONN_T)))
httpd_service(msg->conn_fd, hc);
if (hc) httpd_free(hc);
close(msg->conn_fd);
}
if (msg) httpd_free(msg);
}
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_service
*-----------------------------------------------------------------------
* DESCRIPTION: httpd service
* INPUT : int conn_fd
* HTTPD_CONN_T *hc
* OUTPUT : None
*----------------------------------------------------------------------*/
static void httpd_service(int conn_fd, HTTPD_CONN_T* hc)
{
struct sockaddr_in client;
int len;
WebLib_EncodeUsernamePassword ();
memset(hc, 0, sizeof(HTTPD_CONN_T));
httpd_init_conn_table(hc);
hc->conn_fd=conn_fd;
len = sizeof(struct sockaddr_in);
getpeername(conn_fd, (struct sockaddr *)&client, &len);
hc->client_addr=client.sin_addr;
hc->client_addr.s_addr=ntohl(hc->client_addr.s_addr);
httpd_handle_read(hc);
httpd_handle_send(hc);
httpd_free_conn_table(hc);
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_init_conn_table
*-----------------------------------------------------------------------
* DESCRIPTION: Initialize connection table
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : None
*----------------------------------------------------------------------*/
static void httpd_init_conn_table(HTTPD_CONN_T* hc)
{
// struct sockaddr_in sin;
// int sz;
if (! hc->initialized)
{
hc->maxdecodedurl =
hc->maxorigfilename = hc->maxexpnfilename = hc->maxencodings =
hc->maxpathinfo = hc->maxquery = hc->maxaccept =
hc->maxaccepte = hc->maxreqhost = hc->maxremoteuser =
hc->maxresponse = 0;
httpd_realloc_str(&hc->decodedurl, &hc->maxdecodedurl, 1);
httpd_realloc_str(&hc->origfilename, &hc->maxorigfilename, 1);
httpd_realloc_str(&hc->expnfilename, &hc->maxexpnfilename, 0);
httpd_realloc_str(&hc->encodings, &hc->maxencodings, 0);
httpd_realloc_str(&hc->pathinfo, &hc->maxpathinfo, 0);
httpd_realloc_str(&hc->query, &hc->maxquery, 0);
httpd_realloc_str(&hc->accept, &hc->maxaccept, 0);
httpd_realloc_str(&hc->accepte, &hc->maxaccepte, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -