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

📄 httpd.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ================================================================= * *      httpd.c * *      A simple embedded HTTP server * * =================================================================  * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating * System. * Copyright (C) 2002 Nick Garnett. * Copyright (C) 2003 Andrew Lunn. *  * eCos 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 or (at your option) * any later version. *  * eCos 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 eCos; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *  * As a special exception, if other files instantiate templates or * use macros or inline functions from this file, or you compile this * file and link it with other works to produce a work based on this * file, this file does not by itself cause the resulting work to be * covered by the GNU General Public License. However the source code * for this file must still be made available in accordance with * section (3) of the GNU General Public License. *  * This exception does not invalidate any other reasons why a work * based on this file might be covered by the GNU General Public * License. * * ------------------------------------------- * ####ECOSGPLCOPYRIGHTEND#### * ================================================================= * #####DESCRIPTIONBEGIN#### *  *  Author(s):    nickg@calivar.com *  Contributors: nickg@calivar.com, Andrew.lunn@ascom.ch *  Date:         2002-10-14 *  Purpose:       *  Description:   *                * ####DESCRIPTIONEND#### *  * ================================================================= */#include <pkgconf/system.h>#include <pkgconf/isoinfra.h>#include <pkgconf/httpd.h>#include <cyg/infra/cyg_trac.h>        /* tracing macros */#include <cyg/infra/cyg_ass.h>         /* assertion macros */#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <network.h>#include <arpa/inet.h>#include <cyg/httpd/httpd.h>/* ================================================================= */#if 0#define HTTPD_DIAG diag_printf#else#define HTTPD_DIAG(...)#endif/* ================================================================= *//* Server socket address and file descriptor. */static struct sockaddr_in server_address;static int server_socket = -1;#ifdef CYGPKG_NET_INET6static int server_socket6 = -1;static struct sockaddr_in6 server_address6;#endif/* ================================================================= *//* Thread stacks, etc. */static cyg_uint8 httpd_stacks[CYGNUM_HTTPD_THREAD_COUNT]                             [CYGNUM_HAL_STACK_SIZE_MINIMUM+                              CYGNUM_HTTPD_SERVER_BUFFER_SIZE+                              CYGNUM_HTTPD_THREAD_STACK_SIZE];static cyg_handle_t httpd_thread[CYGNUM_HTTPD_THREAD_COUNT];static cyg_thread httpd_thread_object[CYGNUM_HTTPD_THREAD_COUNT];/* ================================================================= *//* Filename lookup table */CYG_HAL_TABLE_BEGIN( cyg_httpd_table, httpd_table );CYG_HAL_TABLE_END( cyg_httpd_table_end, httpd_table );__externC cyg_httpd_table_entry cyg_httpd_table[];__externC cyg_httpd_table_entry cyg_httpd_table_end[];/* ================================================================= *//* Page not found message */static char cyg_httpd_not_found[] ="<head><title>Page Not found</title></head>\n""<body><h2>The requested URL was not found on this server.</h2></body>\n";/* ================================================================= *//* Simple pattern matcher for filenames * * This performs a simple pattern match between the given name and the * pattern. At present the only matching supported is either exact, or * if the pattern ends in * then that matches all remaining * characters. At some point we might want to implement a more * complete regular expression parser here. */static cyg_bool match( char *name, char *pattern ){    while( *name != 0 && *pattern != 0 && *name == *pattern )        name++, pattern++;    if( *name == 0 && *pattern == 0 )        return true;    if( *pattern == '*' )        return true;    return false;}/* ================================================================= *//* Main processing function                                          *//*                                                                   *//* Reads the HTTP header, look it up in the table and calls the      *//* handler.                                                          */static void cyg_httpd_process( int client_socket, struct sockaddr *client_address ){    int calen = sizeof(*client_address);    int nlc = 0;    char request[CYGNUM_HTTPD_SERVER_BUFFER_SIZE];    FILE *client;    cyg_httpd_table_entry *entry = cyg_httpd_table;    char *filename;    char *formdata = NULL;    char *p;    cyg_bool success = false;    char name[64];    char port[10];    getnameinfo(client_address, calen, name, sizeof(name),                 port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV);    HTTPD_DIAG("Connection from %s[%s]\n",name,port);      /* Convert the file descriptor to a C library FILE object so     * we can use fprintf() and friends on it.     */    client = fdopen( client_socket, "r+");      /* We are really only interested in the first line.     */    fgets( request, sizeof(request), client );      HTTPD_DIAG("Request >%s<\n", request );      /* Absorb the rest of the header. We nibble it away a     * character at a time like this to avoid having to define     * another buffer to read lines into. If we ever need to take     * more interest in the header fields, we will need to be a     * lot more sophisticated than this.     */    do{        int c = getc( client );        HTTPD_DIAG("%c",c);        if( c == '\n' )            nlc++;        else if( c != '\r' )            nlc = 0;    } while(nlc < 2);      /* Extract the filename and any form data being returned.     * We know that the "GET " request takes 4 bytes.     * TODO: handle POST type requests as well as GET's.     */      filename = p = request+4;      /* Now scan the filename until we hit a space or a '?'. If we     * end on a '?' then the rest is a form request. Put NULs at     * the end of each string.     */    while( *p != ' ' && *p != '?' )        p++;    if( *p == '?' )        formdata = p+1;    *p = 0;      if( formdata != NULL )    {        while( *p != ' ' )            p++;        *p = 0;    }      HTTPD_DIAG("Request filename >%s< formdata >%s<\n",filename,formdata?formdata:"-NULL-");      HTTPD_DIAG("table: %08x...%08x\n",cyg_httpd_table, cyg_httpd_table_end);      /* Now scan the table for a matching entry. If we find one     * call the handler routine. If that returns true then we     * terminate the scan, otherwise we keep looking.     */    while( entry != cyg_httpd_table_end )    {        HTTPD_DIAG("try %08x: %s\n", entry, entry->pattern);              if( match( filename, entry->pattern ) )        {            HTTPD_DIAG("calling %08x: %s\n", entry, entry->pattern);            if( (success = entry->handler( client, filename, formdata, entry->arg )) )                break;        }              entry++;    }      /* If we failed to find a match in the table, send a "not     * found" response.     * TODO: add an optional fallback to go look for files in     * some filesystem, somewhere.     */    if( !success )    {        HTTPD_DIAG("Not found %s\n",filename);        cyg_httpd_send_html( client, NULL, NULL, cyg_httpd_not_found );    }    fclose(client);}/* ================================================================= *//* Main HTTP server * * This just loops, collects client connections, and calls the main * process function on the connects*/static void cyg_httpd_server( cyg_addrword_t arg ){    do    {        int client_socket;        struct sockaddr client_address;        int calen = sizeof(client_address);        fd_set readfds;        int n;        /* Wait for a connection.         */        FD_ZERO(&readfds);        FD_SET(server_socket, &readfds);#ifdef CYGPKG_NET_INET6        FD_SET(server_socket6, &readfds);        n = (server_socket > server_socket6 ? server_socket : server_socket6) + 1;#else        n = server_socket + 1;#endif        select(n,&readfds,NULL,NULL,NULL);

⌨️ 快捷键说明

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