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

📄 response.c

📁 一个很好用的解析
💻 C
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================                             response===============================================================================  This module contains callbacks from and services for a request handler.  Copyright information is at the end of the file=============================================================================*/#include <ctype.h>#include <assert.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <time.h>#include "xmlrpc_config.h"#include "mallocvar.h"#include "xmlrpc-c/string_int.h"#include "xmlrpc-c/abyss.h"#include "server.h"#include "session.h"#include "conn.h"#include "token.h"#include "date.h"#include "data.h"#include "abyss_info.h"#include "http.h"voidResponseError(TSession * const sessionP) {    const char * const reason = HTTPReasonByStatus(sessionP->status);    const char * errorDocument;    ResponseAddField(sessionP, "Content-type", "text/html");    ResponseWriteStart(sessionP);        xmlrpc_asprintf(&errorDocument,                    "<HTML><HEAD><TITLE>Error %d</TITLE></HEAD>"                    "<BODY><H1>Error %d</H1><P>%s</P>" SERVER_HTML_INFO                     "</BODY></HTML>",                    sessionP->status, sessionP->status, reason);        ConnWrite(sessionP->conn, errorDocument, strlen(errorDocument));     xmlrpc_strfree(errorDocument);}abyss_boolResponseChunked(TSession * const sessionP) {    /* This is only a hope, things will be real only after a call of       ResponseWriteStart()    */    assert(!sessionP->responseStarted);    sessionP->chunkedwrite =        (sessionP->version.major > 1) ||        (sessionP->version.major == 1 && (sessionP->version.minor >= 1));    sessionP->chunkedwritemode = TRUE;    return TRUE;}voidResponseStatus(TSession * const sessionP,               uint16_t   const code) {    sessionP->status = code;}uint16_tResponseStatusFromErrno(int const errnoArg) {    uint16_t code;    switch (errnoArg) {    case EACCES:        code=403;        break;    case ENOENT:        code=404;        break;    default:        code=500;    }    return code;}voidResponseStatusErrno(TSession * const sessionP) {    ResponseStatus(sessionP, ResponseStatusFromErrno(errno));}abyss_boolResponseAddField(TSession *   const sessionP,                 const char * const name,                 const char * const value) {    return TableAdd(&sessionP->response_headers, name, value);}static voidaddDateHeader(TSession * const sessionP) {    char dateValue[64];    abyss_bool validDate;    validDate = DateToString(&sessionP->date, dateValue);    if (sessionP->status >= 200 && validDate)        ResponseAddField(sessionP, "Date", dateValue);}voidResponseWriteStart(TSession * const sessionP) {    struct _TServer * const srvP = ConnServer(sessionP->conn)->srvP;    unsigned int i;    assert(!sessionP->responseStarted);    if (sessionP->status == 0) {        // Handler hasn't set status.  That's an error        sessionP->status = 500;    }    sessionP->responseStarted = TRUE;    {        const char * const reason = HTTPReasonByStatus(sessionP->status);        const char * line;        xmlrpc_asprintf(&line,"HTTP/1.1 %u %s\r\n", sessionP->status, reason);        ConnWrite(sessionP->conn, line, strlen(line));        xmlrpc_strfree(line);    }    if (HTTPKeepalive(sessionP)) {        const char * keepaliveValue;                ResponseAddField(sessionP, "Connection", "Keep-Alive");        xmlrpc_asprintf(&keepaliveValue, "timeout=%u, max=%u",                        srvP->keepalivetimeout, srvP->keepalivemaxconn);        ResponseAddField(sessionP, "Keep-Alive", keepaliveValue);        xmlrpc_strfree(keepaliveValue);    } else        ResponseAddField(sessionP, "Connection", "close");        if (sessionP->chunkedwrite && sessionP->chunkedwritemode)        ResponseAddField(sessionP, "Transfer-Encoding", "chunked");    addDateHeader(sessionP);    /* Generation of the server field */    if (srvP->advertise)        ResponseAddField(sessionP, "Server", SERVER_HVERSION);    /* send all the fields */    for (i = 0; i < sessionP->response_headers.size; ++i) {        TTableItem * const ti = &sessionP->response_headers.item[i];        const char * line;        xmlrpc_asprintf(&line, "%s: %s\r\n", ti->name, ti->value);        ConnWrite(sessionP->conn, line, strlen(line));        xmlrpc_strfree(line);    }    ConnWrite(sessionP->conn, "\r\n", 2);  }abyss_boolResponseWriteBody(TSession *   const sessionP,                  const char * const data,                  uint32_t     const len) {    return HTTPWriteBodyChunk(sessionP, data, len);}abyss_boolResponseWriteEnd(TSession * const sessionP) {    return HTTPWriteEndChunk(sessionP);}abyss_boolResponseContentType(TSession *   const serverP,                    const char * const type) {    return ResponseAddField(serverP, "Content-type", type);}abyss_boolResponseContentLength(TSession * const sessionP,                      uint64_t   const len) {    char contentLengthValue[32];        sprintf(contentLengthValue, "%llu", len);    return ResponseAddField(sessionP, "Content-length", contentLengthValue);}/*********************************************************************** MIMEType*********************************************************************/struct MIMEType {    TList typeList;    TList extList;    TPool pool;};static MIMEType * globalMimeTypeP = NULL;MIMEType *MIMETypeCreate(void) {     MIMEType * MIMETypeP;    MALLOCVAR(MIMETypeP);    if (MIMETypeP) {        ListInit(&MIMETypeP->typeList);        ListInit(&MIMETypeP->extList);        PoolCreate(&MIMETypeP->pool, 1024);    }    return MIMETypeP;}voidMIMETypeDestroy(MIMEType * const MIMETypeP) {    PoolFree(&MIMETypeP->pool);}voidMIMETypeInit(void) {    if (globalMimeTypeP != NULL)        abort();    globalMimeTypeP = MIMETypeCreate();}voidMIMETypeTerm(void) {    if (globalMimeTypeP == NULL)        abort();    MIMETypeDestroy(globalMimeTypeP);    globalMimeTypeP = NULL;}static voidmimeTypeAdd(MIMEType *   const MIMETypeP,            const char * const type,            const char * const ext,            abyss_bool * const successP) {        uint16_t index;    void * mimeTypesItem;    abyss_bool typeIsInList;    assert(MIMETypeP != NULL);    typeIsInList = ListFindString(&MIMETypeP->typeList, type, &index);    if (typeIsInList)        mimeTypesItem = MIMETypeP->typeList.item[index];    else        mimeTypesItem = (void*)PoolStrdup(&MIMETypeP->pool, type);    if (mimeTypesItem) {        abyss_bool extIsInList;        extIsInList = ListFindString(&MIMETypeP->extList, ext, &index);        if (extIsInList) {            MIMETypeP->typeList.item[index] = mimeTypesItem;            *successP = TRUE;        } else {            void * extItem = (void*)PoolStrdup(&MIMETypeP->pool, ext);            if (extItem) {                abyss_bool addedToMimeTypes;                addedToMimeTypes =                    ListAdd(&MIMETypeP->typeList, mimeTypesItem);                if (addedToMimeTypes) {

⌨️ 快捷键说明

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