📄 core.c
字号:
conf = (core_server_config *)apr_pcalloc(a, sizeof(core_server_config));#ifdef GPROF conf->gprof_dir = NULL;#endif conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME; conf->ap_document_root = is_virtual ? NULL : DOCUMENT_LOCATION; conf->sec_dir = apr_array_make(a, 40, sizeof(ap_conf_vector_t *)); conf->sec_url = apr_array_make(a, 40, sizeof(ap_conf_vector_t *)); /* recursion stopper */ conf->redirect_limit = 0; /* 0 == unset */ conf->subreq_limit = 0; return (void *)conf;}static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv){ core_server_config *base = (core_server_config *)basev; core_server_config *virt = (core_server_config *)virtv; core_server_config *conf; conf = (core_server_config *)apr_palloc(p, sizeof(core_server_config)); memcpy(conf, virt, sizeof(core_server_config)); if (!conf->access_name) { conf->access_name = base->access_name; } if (!conf->ap_document_root) { conf->ap_document_root = base->ap_document_root; } conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir); conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url); conf->redirect_limit = virt->redirect_limit ? virt->redirect_limit : base->redirect_limit; conf->subreq_limit = virt->subreq_limit ? virt->subreq_limit : base->subreq_limit; return conf;}/* Add per-directory configuration entry (for <directory> section); * these are part of the core server config. */AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config){ core_server_config *sconf = ap_get_module_config(s->module_config, &core_module); void **new_space = (void **)apr_array_push(sconf->sec_dir); *new_space = dir_config;}AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config){ core_server_config *sconf = ap_get_module_config(s->module_config, &core_module); void **new_space = (void **)apr_array_push(sconf->sec_url); *new_space = url_config;}AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config){ void **new_space = (void **)apr_array_push(conf->sec_file); *new_space = url_config;}/* We need to do a stable sort, qsort isn't stable. So to make it stable * we'll be maintaining the original index into the list, and using it * as the minor key during sorting. The major key is the number of * components (where the root component is zero). */struct reorder_sort_rec { ap_conf_vector_t *elt; int orig_index;};static int reorder_sorter(const void *va, const void *vb){ const struct reorder_sort_rec *a = va; const struct reorder_sort_rec *b = vb; core_dir_config *core_a; core_dir_config *core_b; core_a = ap_get_module_config(a->elt, &core_module); core_b = ap_get_module_config(b->elt, &core_module); /* a regex always sorts after a non-regex */ if (!core_a->r && core_b->r) { return -1; } else if (core_a->r && !core_b->r) { return 1; } /* we always sort next by the number of components */ if (core_a->d_components < core_b->d_components) { return -1; } else if (core_a->d_components > core_b->d_components) { return 1; } /* They have the same number of components, we now have to compare * the minor key to maintain the original order (from the config.) */ return a->orig_index - b->orig_index;}void ap_core_reorder_directories(apr_pool_t *p, server_rec *s){ core_server_config *sconf; apr_array_header_t *sec_dir; struct reorder_sort_rec *sortbin; int nelts; ap_conf_vector_t **elts; int i; apr_pool_t *tmp; sconf = ap_get_module_config(s->module_config, &core_module); sec_dir = sconf->sec_dir; nelts = sec_dir->nelts; elts = (ap_conf_vector_t **)sec_dir->elts; if (!nelts) { /* simple case of already being sorted... */ /* We're not checking this condition to be fast... we're checking * it to avoid trying to palloc zero bytes, which can trigger some * memory debuggers to barf */ return; } /* we have to allocate tmp space to do a stable sort */ apr_pool_create(&tmp, p); sortbin = apr_palloc(tmp, sec_dir->nelts * sizeof(*sortbin)); for (i = 0; i < nelts; ++i) { sortbin[i].orig_index = i; sortbin[i].elt = elts[i]; } qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter); /* and now copy back to the original array */ for (i = 0; i < nelts; ++i) { elts[i] = sortbin[i].elt; } apr_pool_destroy(tmp);}/***************************************************************** * * There are some elements of the core config structures in which * other modules have a legitimate interest (this is ugly, but necessary * to preserve NCSA back-compatibility). So, we have a bunch of accessors * here... */AP_DECLARE(int) ap_allow_options(request_rec *r){ core_dir_config *conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->opts;}AP_DECLARE(int) ap_allow_overrides(request_rec *r){ core_dir_config *conf; conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->override;}AP_DECLARE(const char *) ap_auth_type(request_rec *r){ core_dir_config *conf; conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->ap_auth_type;}AP_DECLARE(const char *) ap_auth_name(request_rec *r){ core_dir_config *conf; conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->ap_auth_name;}AP_DECLARE(const char *) ap_default_type(request_rec *r){ core_dir_config *conf; conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->ap_default_type ? conf->ap_default_type : DEFAULT_CONTENT_TYPE;}AP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */{ core_server_config *conf; conf = (core_server_config *)ap_get_module_config(r->server->module_config, &core_module); return conf->ap_document_root;}AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r){ core_dir_config *conf; conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->ap_requires;}AP_DECLARE(int) ap_satisfies(request_rec *r){ core_dir_config *conf; conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); return conf->satisfy[r->method_number];}/* Should probably just get rid of this... the only code that cares is * part of the core anyway (and in fact, it isn't publicised to other * modules). */char *ap_response_code_string(request_rec *r, int error_index){ core_dir_config *dirconf; core_request_config *reqconf; /* check for string registered via ap_custom_response() first */ reqconf = (core_request_config *)ap_get_module_config(r->request_config, &core_module); if (reqconf->response_code_strings != NULL && reqconf->response_code_strings[error_index] != NULL) { return reqconf->response_code_strings[error_index]; } /* check for string specified via ErrorDocument */ dirconf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); if (dirconf->response_code_strings == NULL) { return NULL; } if (dirconf->response_code_strings[error_index] == &errordocument_default) { return NULL; } return dirconf->response_code_strings[error_index];}/* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */static APR_INLINE void do_double_reverse (conn_rec *conn){ apr_sockaddr_t *sa; apr_status_t rv; if (conn->double_reverse) { /* already done */ return; } if (conn->remote_host == NULL || conn->remote_host[0] == '\0') { /* single reverse failed, so don't bother */ conn->double_reverse = -1; return; } rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool); if (rv == APR_SUCCESS) { while (sa) { if (apr_sockaddr_equal(sa, conn->remote_addr)) { conn->double_reverse = 1; return; } sa = sa->next; } } conn->double_reverse = -1;}AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip){ int hostname_lookups; if (str_is_ip) { /* if caller wants to know */ *str_is_ip = 0; } /* If we haven't checked the host name, and we want to */ if (dir_config) { hostname_lookups = ((core_dir_config *)ap_get_module_config(dir_config, &core_module)) ->hostname_lookups; if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) { hostname_lookups = HOSTNAME_LOOKUP_OFF; } } else { /* the default */ hostname_lookups = HOSTNAME_LOOKUP_OFF; } if (type != REMOTE_NOLOOKUP && conn->remote_host == NULL && (type == REMOTE_DOUBLE_REV || hostname_lookups != HOSTNAME_LOOKUP_OFF)) { if (apr_getnameinfo(&conn->remote_host, conn->remote_addr, 0) == APR_SUCCESS) { ap_str_tolower(conn->remote_host); if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) { do_double_reverse(conn); if (conn->double_reverse != 1) { conn->remote_host = NULL; } } } /* if failed, set it to the NULL string to indicate error */ if (conn->remote_host == NULL) { conn->remote_host = ""; } } if (type == REMOTE_DOUBLE_REV) { do_double_reverse(conn); if (conn->double_reverse == -1) { return NULL; } } /* * Return the desired information; either the remote DNS name, if found, * or either NULL (if the hostname was requested) or the IP address * (if any identifier was requested). */ if (conn->remote_host != NULL && conn->remote_host[0] != '\0') { return conn->remote_host; } else { if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) { return NULL; } else { if (str_is_ip) { /* if caller wants to know */ *str_is_ip = 1; } return conn->remote_ip; } }}AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r){ core_dir_config *dir_conf; if (r->connection->remote_logname != NULL) { return r->connection->remote_logname; } /* If we haven't checked the identity, and we want to */ dir_conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); if (dir_conf->do_rfc1413 & 1) { return ap_rfc1413(r->connection, r->server); } else { return NULL; }}/* There are two options regarding what the "name" of a server is. The * "canonical" name as defined by ServerName and Port, or the "client's * name" as supplied by a possible Host: header or full URI. We never * trust the port passed in the client's headers, we always use the * port of the actual socket. * * The DNS option to UseCanonicalName causes this routine to do a * reverse lookup on the local IP address of the connection and use * that for the ServerName. This makes its value more reliable while * at the same time allowing Demon's magic virtual hosting to work. * The assumption is that DNS lookups are sufficiently quick... * -- fanf 1998-10-03 */AP_DECLARE(const char *) ap_get_server_name(request_rec *r){ conn_rec *conn = r->connection; core_dir_config *d; d = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) { return r->hostname ? r->hostname : r->server->server_hostname; } if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) { if (conn->local_host == NULL) { if (apr_getnameinfo(&conn->local_host, conn->local_addr, 0) != APR_SUCCESS) conn->local_host = apr_pstrdup(conn->pool, r->server->server_hostname); else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -