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

📄 http_protocol.c

📁 apache服务器源代码(版本号:2.2.2)
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* If a valid If-Modified-Since request-header field was given     * AND it is a GET or HEAD request     * AND the requested resource has not been modified since the time     * specified in this field, then the server MUST     *    respond with a status of 304 (Not Modified).     * A date later than the server's current request time is invalid.     */    if (r->method_number == M_GET        && (not_modified || !if_nonematch)        && (if_modified_since =              apr_table_get(r->headers_in,                            "If-Modified-Since")) != NULL) {        apr_time_t ims_time;        apr_int64_t ims, reqtime;        ims_time = apr_date_parse_http(if_modified_since);        ims = apr_time_sec(ims_time);        reqtime = apr_time_sec(r->request_time);        not_modified = ims >= mtime && ims <= reqtime;    }    if (not_modified) {        return HTTP_NOT_MODIFIED;    }    return OK;}/** * Singleton registry of additional methods. This maps new method names * such as "MYGET" to methnums, which are int offsets into bitmasks. * * This follows the same technique as standard M_GET, M_POST, etc. These * are dynamically assigned when modules are loaded and <Limit GET MYGET> * directives are processed. */static apr_hash_t *methods_registry = NULL;static int cur_method_number = METHOD_NUMBER_FIRST;/* internal function to register one method/number pair */static void register_one_method(apr_pool_t *p, const char *methname,                                int methnum){    int *pnum = apr_palloc(p, sizeof(*pnum));    *pnum = methnum;    apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, pnum);}/* This internal function is used to clear the method registry * and reset the cur_method_number counter. */static apr_status_t ap_method_registry_destroy(void *notused){    methods_registry = NULL;    cur_method_number = METHOD_NUMBER_FIRST;    return APR_SUCCESS;}AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p){    methods_registry = apr_hash_make(p);    apr_pool_cleanup_register(p, NULL,                              ap_method_registry_destroy,                              apr_pool_cleanup_null);    /* put all the standard methods into the registry hash to ease the       mapping operations between name and number */    register_one_method(p, "GET", M_GET);    register_one_method(p, "PUT", M_PUT);    register_one_method(p, "POST", M_POST);    register_one_method(p, "DELETE", M_DELETE);    register_one_method(p, "CONNECT", M_CONNECT);    register_one_method(p, "OPTIONS", M_OPTIONS);    register_one_method(p, "TRACE", M_TRACE);    register_one_method(p, "PATCH", M_PATCH);    register_one_method(p, "PROPFIND", M_PROPFIND);    register_one_method(p, "PROPPATCH", M_PROPPATCH);    register_one_method(p, "MKCOL", M_MKCOL);    register_one_method(p, "COPY", M_COPY);    register_one_method(p, "MOVE", M_MOVE);    register_one_method(p, "LOCK", M_LOCK);    register_one_method(p, "UNLOCK", M_UNLOCK);    register_one_method(p, "VERSION-CONTROL", M_VERSION_CONTROL);    register_one_method(p, "CHECKOUT", M_CHECKOUT);    register_one_method(p, "UNCHECKOUT", M_UNCHECKOUT);    register_one_method(p, "CHECKIN", M_CHECKIN);    register_one_method(p, "UPDATE", M_UPDATE);    register_one_method(p, "LABEL", M_LABEL);    register_one_method(p, "REPORT", M_REPORT);    register_one_method(p, "MKWORKSPACE", M_MKWORKSPACE);    register_one_method(p, "MKACTIVITY", M_MKACTIVITY);    register_one_method(p, "BASELINE-CONTROL", M_BASELINE_CONTROL);    register_one_method(p, "MERGE", M_MERGE);}AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname){    int *methnum;    if (methods_registry == NULL) {        ap_method_registry_init(p);    }    if (methname == NULL) {        return M_INVALID;    }    /* Check if the method was previously registered.  If it was     * return the associated method number.     */    methnum = (int *)apr_hash_get(methods_registry, methname,                                  APR_HASH_KEY_STRING);    if (methnum != NULL)        return *methnum;    if (cur_method_number > METHOD_NUMBER_LAST) {        /* The method registry  has run out of dynamically         * assignable method numbers. Log this and return M_INVALID.         */        ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p,                      "Maximum new request methods %d reached while "                      "registering method %s.",                      METHOD_NUMBER_LAST, methname);        return M_INVALID;    }    register_one_method(p, methname, cur_method_number);    return cur_method_number++;}#define UNKNOWN_METHOD (-1)static int lookup_builtin_method(const char *method, apr_size_t len){    /* Note: the following code was generated by the "shilka" tool from       the "cocom" parsing/compilation toolkit. It is an optimized lookup       based on analysis of the input keywords. Postprocessing was done       on the shilka output, but the basic structure and analysis is       from there. Should new HTTP methods be added, then manual insertion       into this code is fine, or simply re-running the shilka tool on       the appropriate input. */    /* Note: it is also quite reasonable to just use our method_registry,       but I'm assuming (probably incorrectly) we want more speed here       (based on the optimizations the previous code was doing). */    switch (len)    {    case 3:        switch (method[0])        {        case 'P':            return (method[1] == 'U'                    && method[2] == 'T'                    ? M_PUT : UNKNOWN_METHOD);        case 'G':            return (method[1] == 'E'                    && method[2] == 'T'                    ? M_GET : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 4:        switch (method[0])        {        case 'H':            return (method[1] == 'E'                    && method[2] == 'A'                    && method[3] == 'D'                    ? M_GET : UNKNOWN_METHOD);        case 'P':            return (method[1] == 'O'                    && method[2] == 'S'                    && method[3] == 'T'                    ? M_POST : UNKNOWN_METHOD);        case 'M':            return (method[1] == 'O'                    && method[2] == 'V'                    && method[3] == 'E'                    ? M_MOVE : UNKNOWN_METHOD);        case 'L':            return (method[1] == 'O'                    && method[2] == 'C'                    && method[3] == 'K'                    ? M_LOCK : UNKNOWN_METHOD);        case 'C':            return (method[1] == 'O'                    && method[2] == 'P'                    && method[3] == 'Y'                    ? M_COPY : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 5:        switch (method[2])        {        case 'T':            return (memcmp(method, "PATCH", 5) == 0                    ? M_PATCH : UNKNOWN_METHOD);        case 'R':            return (memcmp(method, "MERGE", 5) == 0                    ? M_MERGE : UNKNOWN_METHOD);        case 'C':            return (memcmp(method, "MKCOL", 5) == 0                    ? M_MKCOL : UNKNOWN_METHOD);        case 'B':            return (memcmp(method, "LABEL", 5) == 0                    ? M_LABEL : UNKNOWN_METHOD);        case 'A':            return (memcmp(method, "TRACE", 5) == 0                    ? M_TRACE : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 6:        switch (method[0])        {        case 'U':            switch (method[5])            {            case 'K':                return (memcmp(method, "UNLOCK", 6) == 0                        ? M_UNLOCK : UNKNOWN_METHOD);            case 'E':                return (memcmp(method, "UPDATE", 6) == 0                        ? M_UPDATE : UNKNOWN_METHOD);            default:                return UNKNOWN_METHOD;            }        case 'R':            return (memcmp(method, "REPORT", 6) == 0                    ? M_REPORT : UNKNOWN_METHOD);        case 'D':            return (memcmp(method, "DELETE", 6) == 0                    ? M_DELETE : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 7:        switch (method[1])        {        case 'P':            return (memcmp(method, "OPTIONS", 7) == 0                    ? M_OPTIONS : UNKNOWN_METHOD);        case 'O':            return (memcmp(method, "CONNECT", 7) == 0                    ? M_CONNECT : UNKNOWN_METHOD);        case 'H':            return (memcmp(method, "CHECKIN", 7) == 0                    ? M_CHECKIN : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 8:        switch (method[0])        {        case 'P':            return (memcmp(method, "PROPFIND", 8) == 0                    ? M_PROPFIND : UNKNOWN_METHOD);        case 'C':            return (memcmp(method, "CHECKOUT", 8) == 0                    ? M_CHECKOUT : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 9:        return (memcmp(method, "PROPPATCH", 9) == 0                ? M_PROPPATCH : UNKNOWN_METHOD);    case 10:        switch (method[0])        {        case 'U':            return (memcmp(method, "UNCHECKOUT", 10) == 0                    ? M_UNCHECKOUT : UNKNOWN_METHOD);        case 'M':            return (memcmp(method, "MKACTIVITY", 10) == 0                    ? M_MKACTIVITY : UNKNOWN_METHOD);        default:            return UNKNOWN_METHOD;        }    case 11:        return (memcmp(method, "MKWORKSPACE", 11) == 0                ? M_MKWORKSPACE : UNKNOWN_METHOD);    case 15:        return (memcmp(method, "VERSION-CONTROL", 15) == 0                ? M_VERSION_CONTROL : UNKNOWN_METHOD);    case 16:        return (memcmp(method, "BASELINE-CONTROL", 16) == 0                ? M_BASELINE_CONTROL : UNKNOWN_METHOD);    default:        return UNKNOWN_METHOD;    }    /* NOTREACHED */}/* Get the method number associated with the given string, assumed to * contain an HTTP method.  Returns M_INVALID if not recognized. * * This is the first step toward placing method names in a configurable * list.  Hopefully it (and other routines) can eventually be moved to * something like a mod_http_methods.c, complete with config stuff. */AP_DECLARE(int) ap_method_number_of(const char *method){    int len = strlen(method);    int which = lookup_builtin_method(method, len);    if (which != UNKNOWN_METHOD)        return which;    /* check if the method has been dynamically registered */    if (methods_registry != NULL) {        int *methnum = apr_hash_get(methods_registry, method, len);        if (methnum != NULL) {            return *methnum;        }    }    return M_INVALID;}/* * Turn a known method number into a name. */AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum){    apr_hash_index_t *hi = apr_hash_first(p, methods_registry);    /* scan through the hash table, looking for a value that matches       the provided method number. */    for (; hi; hi = apr_hash_next(hi)) {        const void *key;        void *val;        apr_hash_this(hi, &key, NULL, &val);        if (*(int *)val == methnum)

⌨️ 快捷键说明

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