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

📄 httpd_main.c

📁 网页的客户端开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * $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 + -