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

📄 http.c

📁 一个很好用的解析
💻 C
📖 第 1 页 / 共 2 页
字号:
        *httpErrorCodeP = 400;  /* Bad Request */    else {        if (fieldName[strlen(fieldName)-1] != ':')            /* Not a valid field name */            *httpErrorCodeP = 400;  /* Bad Request */        else {            fieldName[strlen(fieldName)-1] = '\0';  /* remove trailing colon */            strtolower(fieldName);                        *httpErrorCodeP = 0;  /* no error */            *fieldNameP = fieldName;        }    }}static voidprocessHeader(const char * const fieldName,              char *       const fieldValue,              TSession *   const sessionP,              uint16_t *   const httpErrorCodeP) {/*----------------------------------------------------------------------------   We may modify *fieldValue, and we put pointers to *fieldValue and   *fieldName into *sessionP.   We must fix this some day.  *sessionP should point to individual   malloc'ed strings.-----------------------------------------------------------------------------*/    *httpErrorCodeP = 0;  /* initial assumption */    if (xmlrpc_streq(fieldName, "connection")) {        if (xmlrpc_strcaseeq(fieldValue, "keep-alive"))            sessionP->request_info.keepalive = TRUE;        else            sessionP->request_info.keepalive = FALSE;    } else if (xmlrpc_streq(fieldName, "host"))        parseHostPort(fieldValue, &sessionP->request_info.host,                      &sessionP->request_info.port, httpErrorCodeP);    else if (xmlrpc_streq(fieldName, "from"))        sessionP->request_info.from = fieldValue;    else if (xmlrpc_streq(fieldName, "user-agent"))        sessionP->request_info.useragent = fieldValue;    else if (xmlrpc_streq(fieldName, "referer"))        sessionP->request_info.referer = fieldValue;    else if (xmlrpc_streq(fieldName, "range")) {        if (xmlrpc_strneq(fieldValue, "bytes=", 6)) {            abyss_bool succeeded;            succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]);            *httpErrorCodeP = succeeded ? 0 : 400;        }    } else if (xmlrpc_streq(fieldName, "cookies")) {        abyss_bool succeeded;        succeeded = ListAddFromString(&sessionP->cookies, fieldValue);        *httpErrorCodeP = succeeded ? 0 : 400;    }}abyss_boolRequestRead(TSession * const sessionP) {    uint16_t httpErrorCode;  /* zero for no error */    char * requestLine;    readRequestLine(sessionP, &requestLine, &httpErrorCode);    if (!httpErrorCode) {        TMethod httpMethod;        const char * host;        const char * path;        const char * query;        unsigned short port;        abyss_bool moreHeaders;        parseRequestLine(requestLine, &httpMethod, &sessionP->version,                         &host, &port, &path, &query,                         &moreHeaders, &httpErrorCode);        if (!httpErrorCode)            initRequestInfo(&sessionP->request_info, sessionP->version,                            strdup(requestLine),                            httpMethod, host, port, path, query);        while (moreHeaders && !httpErrorCode) {            char * p;            abyss_bool succeeded;            succeeded = ConnReadHeader(sessionP->conn, &p);            if (!succeeded)                httpErrorCode = 408;  /* Request Timeout */            else {                if (!*p)                    /* We have reached the empty line so all the request                       was read.                    */                    moreHeaders = FALSE;                else {                    char * fieldName;                    getFieldNameToken(&p, &fieldName, &httpErrorCode);                    if (!httpErrorCode) {                        char * fieldValue;                        NextToken((const char **)&p);                                                fieldValue = p;                                                TableAdd(&sessionP->request_headers,                                 fieldName, fieldValue);                                                processHeader(fieldName, fieldValue, sessionP,                                      &httpErrorCode);                    }                }            }        }    }    if (httpErrorCode)        ResponseStatus(sessionP, httpErrorCode);    else        sessionP->validRequest = true;    return !httpErrorCode;}char *RequestHeaderValue(TSession *r,char *name){    return (TableFind(&r->request_headers,name));}abyss_boolRequestValidURI(TSession * const sessionP) {    if (!sessionP->request_info.uri)        return FALSE;        if (xmlrpc_streq(sessionP->request_info.uri, "*"))        return (sessionP->request_info.method != m_options);    if (strchr(sessionP->request_info.uri, '*'))        return FALSE;    return TRUE;}abyss_boolRequestValidURIPath(TSession * const sessionP) {    uint32_t i;    const char * p;    p = sessionP->request_info.uri;    i = 0;    if (*p == '/') {        i = 1;        while (*p)            if (*(p++) == '/') {                if (*p == '/')                    break;                else if ((strncmp(p,"./",2) == 0) || (strcmp(p, ".") == 0))                    ++p;                else if ((strncmp(p, "../", 2) == 0) ||                         (strcmp(p, "..") == 0)) {                    p += 2;                    --i;                    if (i == 0)                        break;                }                /* Prevent accessing hidden files (starting with .) */                else if (*p == '.')                    return FALSE;                else                    if (*p)                        ++i;            }    }    return (*p == 0 && i > 0);}abyss_boolRequestAuth(TSession *r,char *credential,char *user,char *pass) {    char *p,*x;    char z[80],t[80];    p=RequestHeaderValue(r,"authorization");    if (p) {        NextToken((const char **)&p);        x=GetToken(&p);        if (x) {            if (strcasecmp(x,"basic")==0) {                NextToken((const char **)&p);                sprintf(z,"%s:%s",user,pass);                Base64Encode(z,t);                if (strcmp(p,t)==0) {                    r->request_info.user=strdup(user);                    return TRUE;                };            };        }    };    sprintf(z,"Basic realm=\"%s\"",credential);    ResponseAddField(r,"WWW-Authenticate",z);    ResponseStatus(r,401);    return FALSE;}/*********************************************************************** Range*********************************************************************/abyss_bool RangeDecode(char *str,uint64_t filesize,uint64_t *start,uint64_t *end){    char *ss;    *start=0;    *end=filesize-1;    if (*str=='-')    {        *start=filesize-strtol(str+1,&ss,10);        return ((ss!=str) && (!*ss));    };    *start=strtol(str,&ss,10);    if ((ss==str) || (*ss!='-'))        return FALSE;    str=ss+1;    if (!*str)        return TRUE;    *end=strtol(str,&ss,10);    if ((ss==str) || (*ss) || (*end<*start))        return FALSE;    return TRUE;}/*********************************************************************** HTTP*********************************************************************/const char *HTTPReasonByStatus(uint16_t const code) {    struct _HTTPReasons {        uint16_t status;        const char * reason;    };    static struct _HTTPReasons const reasons[] =  {        { 100,"Continue" },         { 101,"Switching Protocols" },         { 200,"OK" },         { 201,"Created" },         { 202,"Accepted" },         { 203,"Non-Authoritative Information" },         { 204,"No Content" },         { 205,"Reset Content" },         { 206,"Partial Content" },         { 300,"Multiple Choices" },         { 301,"Moved Permanently" },         { 302,"Moved Temporarily" },         { 303,"See Other" },         { 304,"Not Modified" },         { 305,"Use Proxy" },         { 400,"Bad Request" },         { 401,"Unauthorized" },         { 402,"Payment Required" },         { 403,"Forbidden" },         { 404,"Not Found" },         { 405,"Method Not Allowed" },         { 406,"Not Acceptable" },         { 407,"Proxy Authentication Required" },         { 408,"Request Timeout" },         { 409,"Conflict" },         { 410,"Gone" },         { 411,"Length Required" },         { 412,"Precondition Failed" },         { 413,"Request Entity Too Large" },         { 414,"Request-URI Too Long" },         { 415,"Unsupported Media Type" },         { 500,"Internal Server Error" },         { 501,"Not Implemented" },         { 502,"Bad Gateway" },         { 503,"Service Unavailable" },         { 504,"Gateway Timeout" },         { 505,"HTTP Version Not Supported" },        { 000, NULL }    };    const struct _HTTPReasons * reasonP;    reasonP = &reasons[0];    while (reasonP->status <= code)        if (reasonP->status == code)            return reasonP->reason;        else            ++reasonP;    return "No Reason";}int32_tHTTPRead(TSession *   const s ATTR_UNUSED,         const char * const buffer ATTR_UNUSED,         uint32_t     const len ATTR_UNUSED) {    return 0;}abyss_boolHTTPWriteBodyChunk(TSession *   const sessionP,                   const char * const buffer,                   uint32_t     const len) {    abyss_bool succeeded;    if (sessionP->chunkedwrite && sessionP->chunkedwritemode) {        char chunkHeader[16];        sprintf(chunkHeader, "%x\r\n", len);        succeeded =            ConnWrite(sessionP->conn, chunkHeader, strlen(chunkHeader));        if (succeeded) {            succeeded = ConnWrite(sessionP->conn, buffer, len);            if (succeeded)                succeeded = ConnWrite(sessionP->conn, "\r\n", 2);        }    } else        succeeded = ConnWrite(sessionP->conn, buffer, len);    return succeeded;}abyss_boolHTTPWriteEndChunk(TSession * const sessionP) {    abyss_bool retval;    if (sessionP->chunkedwritemode && sessionP->chunkedwrite) {        /* May be one day trailer dumping will be added */        sessionP->chunkedwritemode = FALSE;        retval = ConnWrite(sessionP->conn, "0\r\n\r\n", 5);    } else        retval = TRUE;    return retval;}abyss_boolHTTPKeepalive(TSession * const sessionP) {/*----------------------------------------------------------------------------   Return value: the connection should be kept alive after the session   *sessionP is over.-----------------------------------------------------------------------------*/    return (sessionP->request_info.keepalive &&            !sessionP->serverDeniesKeepalive &&            sessionP->status < 400);}/********************************************************************************** http.c**** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.** All rights reserved.**** Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions** are met:** 1. Redistributions of source code must retain the above copyright**    notice, this list of conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright**    notice, this list of conditions and the following disclaimer in the**    documentation and/or other materials provided with the distribution.** 3. The name of the author may not be used to endorse or promote products**    derived from this software without specific prior written permission.** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF** SUCH DAMAGE.********************************************************************************/

⌨️ 快捷键说明

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