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

📄 mod_isapi.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
            apr_thread_mutex_unlock(loaded.lock);            return rv;        }        if ((*isa)->last_load_rv == APR_SUCCESS) {            apr_thread_mutex_unlock(loaded.lock);            if ((rv = apr_thread_rwlock_rdlock(gainlock))                    != APR_SUCCESS) {                return rv;            }            rv = (*isa)->last_load_rv;            apr_thread_rwlock_unlock(gainlock);            return rv;        }        if (apr_time_now() > (*isa)->last_load_time + ISAPI_RETRY) {            /* Remember last_load_time before releasing the global             * hash lock to avoid colliding with another thread             * that hit this exception at the same time as our             * retry attempt, since we unlock the global mutex             * before attempting a write lock for this module.             */            apr_time_t check_time = (*isa)->last_load_time;            apr_thread_mutex_unlock(loaded.lock);            if ((rv = apr_thread_rwlock_wrlock(gainlock))                    != APR_SUCCESS) {                return rv;            }            /* If last_load_time is unchanged, we still own this             * retry, otherwise presume another thread provided             * our retry (for good or ill).  Relock the global             * hash for updating last_load_ vars, so their update             * is always atomic to the global lock.             */            if (check_time == (*isa)->last_load_time) {                rv = isapi_load(loaded.pool, s, *isa);                apr_thread_mutex_lock(loaded.lock);                (*isa)->last_load_rv = rv;                (*isa)->last_load_time = apr_time_now();                apr_thread_mutex_unlock(loaded.lock);            }            else {                rv = (*isa)->last_load_rv;            }            apr_thread_rwlock_unlock(gainlock);            return rv;        }        /* We haven't hit timeup on retry, let's grab the last_rv         * within the hash mutex before unlocking.         */        rv = (*isa)->last_load_rv;        apr_thread_mutex_unlock(loaded.lock);        return rv;    }    /* If the module was not found, it's time to create a hash key entry     * before releasing the hash lock to avoid multiple threads from     * loading the same module.     */    key = apr_pstrdup(loaded.pool, fpath);    *isa = apr_pcalloc(loaded.pool, sizeof(isapi_loaded));    (*isa)->filename = key;    if (r) {        /* A mutex that exists only long enough to attempt to         * load this isapi dll, the release this module to all         * other takers that came along during the one-time         * load process.  Short lifetime for this lock would         * be great, however, using r->pool is nasty if those         * blocked on the lock haven't all unlocked before we         * attempt to destroy.  A nastier race condition than         * I want to deal with at this moment...         */        apr_thread_rwlock_create(&(*isa)->in_progress, loaded.pool);        apr_thread_rwlock_wrlock((*isa)->in_progress);    }    apr_hash_set(loaded.hash, key, APR_HASH_KEY_STRING, *isa);    /* Now attempt to load the isapi on our own time,     * allow other isapi processing to resume.     */    apr_thread_mutex_unlock(loaded.lock);    rv = isapi_load(loaded.pool, s, *isa);    (*isa)->last_load_time = apr_time_now();    (*isa)->last_load_rv = rv;    if (r && (rv == APR_SUCCESS)) {        /* Let others who are blocked on this particular         * module resume their requests, for better or worse.         */        apr_thread_rwlock_t *unlock = (*isa)->in_progress;        (*isa)->in_progress = NULL;        apr_thread_rwlock_unlock(unlock);    }    else if (!r && (rv != APR_SUCCESS)) {        /* We must leave a rwlock around for requests to retry         * loading this dll after timeup... since we were in         * the setup code we had avoided creating this lock.         */        apr_thread_rwlock_create(&(*isa)->in_progress, loaded.pool);    }    return (*isa)->last_load_rv;}/********************************************************** * *  ISAPI Module request callbacks section * **********************************************************//* Our "Connection ID" structure */struct isapi_cid {    EXTENSION_CONTROL_BLOCK *ecb;    isapi_dir_conf           dconf;    isapi_loaded            *isa;    request_rec             *r;    int                      headers_set;    int                      response_sent;    PFN_HSE_IO_COMPLETION    completion;    void                    *completion_arg;    apr_thread_mutex_t      *completed;};int APR_THREAD_FUNC GetServerVariable (isapi_cid    *cid,                                       char         *variable_name,                                       void         *buf_ptr,                                       apr_uint32_t *buf_size){    request_rec *r = cid->r;    const char *result;    char *buf_data = (char*)buf_ptr;    apr_uint32_t len;    if (!strcmp(variable_name, "ALL_HTTP"))    {        /* crlf delimited, colon split, comma separated and         * null terminated list of HTTP_ vars         */        const apr_array_header_t *arr = apr_table_elts(r->subprocess_env);        const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts;        int i;        for (len = 0, i = 0; i < arr->nelts; i++) {            if (!strncmp(elts[i].key, "HTTP_", 5)) {                len += strlen(elts[i].key) + strlen(elts[i].val) + 3;            }        }        if (*buf_size < len + 1) {            *buf_size = len + 1;            apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER));            return 0;        }        for (i = 0; i < arr->nelts; i++) {            if (!strncmp(elts[i].key, "HTTP_", 5)) {                strcpy(buf_data, elts[i].key);                buf_data += strlen(elts[i].key);                *(buf_data++) = ':';                strcpy(buf_data, elts[i].val);                buf_data += strlen(elts[i].val);                *(buf_data++) = '\r';                *(buf_data++) = '\n';            }        }        *(buf_data++) = '\0';        *buf_size = len + 1;        return 1;    }    if (!strcmp(variable_name, "ALL_RAW"))    {        /* crlf delimited, colon split, comma separated and         * null terminated list of the raw request header         */        const apr_array_header_t *arr = apr_table_elts(r->headers_in);        const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts;        int i;        for (len = 0, i = 0; i < arr->nelts; i++) {            len += strlen(elts[i].key) + strlen(elts[i].val) + 4;        }        if (*buf_size < len + 1) {            *buf_size = len + 1;            apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER));            return 0;        }        for (i = 0; i < arr->nelts; i++) {            strcpy(buf_data, elts[i].key);            buf_data += strlen(elts[i].key);            *(buf_data++) = ':';            *(buf_data++) = ' ';            strcpy(buf_data, elts[i].val);            buf_data += strlen(elts[i].val);            *(buf_data++) = '\r';            *(buf_data++) = '\n';        }        *(buf_data++) = '\0';        *buf_size = len + 1;        return 1;    }    /* Not a special case */    result = apr_table_get(r->subprocess_env, variable_name);    if (result) {        len = strlen(result);        if (*buf_size < len + 1) {            *buf_size = len + 1;            apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER));            return 0;        }        strcpy(buf_data, result);        *buf_size = len + 1;        return 1;    }    /* Not Found */    apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_INDEX));    return 0;}int APR_THREAD_FUNC ReadClient(isapi_cid    *cid,                               void         *buf_data,                               apr_uint32_t *buf_size){    request_rec *r = cid->r;    apr_uint32_t read = 0;    int res;    if (r->remaining < *buf_size) {        *buf_size = (apr_size_t)r->remaining;    }    while (read < *buf_size &&           ((res = ap_get_client_block(r, (char*)buf_data + read,                                       *buf_size - read)) > 0)) {        read += res;    }    *buf_size = read;    if (res < 0) {        apr_set_os_error(APR_FROM_OS_ERROR(ERROR_READ_FAULT));    }    return (res >= 0);}/* Common code invoked for both HSE_REQ_SEND_RESPONSE_HEADER and * the newer HSE_REQ_SEND_RESPONSE_HEADER_EX ServerSupportFunction(s) * as well as other functions that write responses and presume that * the support functions above are optional. * * Other callers trying to split headers and body bytes should pass * head/headlen alone (leaving stat/statlen NULL/0), so that they * get a proper count of bytes consumed.  The argument passed to stat * isn't counted as the head bytes are. */static apr_ssize_t send_response_header(isapi_cid *cid,                                        const char *stat,                                        const char *head,                                        apr_size_t statlen,                                        apr_size_t headlen){    int head_present = 1;    int termarg;    int res;    int old_status;    const char *termch;    apr_size_t ate = 0;    if (!head || headlen == 0 || !*head) {        head = stat;        stat = NULL;        headlen = statlen;        statlen = 0;        head_present = 0; /* Don't eat the header */    }    if (!stat || statlen == 0 || !*stat) {        if (head && headlen && *head && ((stat = memchr(head, '\r', headlen))                                      || (stat = memchr(head, '\n', headlen))                                      || (stat = memchr(head, '\0', headlen))                                      || (stat = head + headlen))) {            statlen = stat - head;            if (memchr(head, ':', statlen)) {                stat = "Status: 200 OK";                statlen = strlen(stat);            }            else {                const char *flip = head;                head = stat;                stat = flip;                headlen -= statlen;                ate += statlen;                if (*head == '\r' && headlen)                    ++head, --headlen, ++ate;                if (*head == '\n' && headlen)                    ++head, --headlen, ++ate;            }        }    }    if (stat && (statlen > 0) && *stat) {        char *newstat;        if (!apr_isdigit(*stat)) {            const char *stattok = stat;            int toklen = statlen;            while (toklen && *stattok && !apr_isspace(*stattok)) {                ++stattok; --toklen;            }            while (toklen && apr_isspace(*stattok)) {                ++stattok; --toklen;            }            /* Now decide if we follow the xxx message             * or the http/x.x xxx message format             */            if (toklen && apr_isdigit(*stattok)) {                statlen = toklen;                stat = stattok;            }        }        newstat = apr_palloc(cid->r->pool, statlen + 9);        strcpy(newstat, "Status: ");        apr_cpystrn(newstat + 8, stat, statlen + 1);        stat = newstat;        statlen += 8;    }    if (!head || headlen == 0 || !*head) {        head = "\r\n";        headlen = 2;    }    else    {        if (head[headlen - 1] && head[headlen]) {            /* Whoops... not NULL terminated */            head = apr_pstrndup(cid->r->pool, head, headlen);        }    }

⌨️ 快捷键说明

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