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

📄 mod_usertrack.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* User Tracking Module (Was mod_cookies.c) * * *** IMPORTANT NOTE: This module is not designed to generate  * *** cryptographically secure cookies.  This means you should not  * *** use cookies generated by this module for authentication purposes * * This Apache module is designed to track users paths through a site. * It uses the client-side state ("Cookie") protocol developed by Netscape. * It is known to work on most browsers. * * Each time a page is requested we look to see if the browser is sending * us a Cookie: header that we previously generated. * * If we don't find one then the user hasn't been to this site since * starting their browser or their browser doesn't support cookies.  So * we generate a unique Cookie for the transaction and send it back to * the browser (via a "Set-Cookie" header) * Future requests from the same browser should keep the same Cookie line. * * By matching up all the requests with the same cookie you can * work out exactly what path a user took through your site.  To log * the cookie use the " %{Cookie}n " directive in a custom access log; * * Example 1 : If you currently use the standard Log file format (CLF) * and use the command "TransferLog somefilename", add the line *       LogFormat "%h %l %u %t \"%r\" %s %b %{Cookie}n" * to your config file. * * Example 2 : If you used to use the old "CookieLog" directive, you * can emulate it by adding the following command to your config file *       CustomLog filename "%{Cookie}n \"%r\" %t" * * Mark Cox, mjc@apache.org, 6 July 95 * * This file replaces mod_cookies.c */#include "httpd.h"#include "http_config.h"#include "http_core.h"#if !defined(WIN32) && !defined(MPE) && !defined(TPF41)#include <sys/time.h>#endifmodule MODULE_VAR_EXPORT usertrack_module;typedef struct {    int always;    time_t expires;} cookie_log_state;typedef enum {    CT_UNSET,    CT_NETSCAPE,    CT_COOKIE,    CT_COOKIE2} cookie_type_e;typedef enum {    CF_NORMAL,    CF_COMPACT} cookie_format_e;typedef struct {    int enabled;    cookie_type_e style;    cookie_format_e format;    char *cookie_name;    char *cookie_domain;    char *prefix_string;    char *regexp_string;  /* used to compile regexp; save for debugging */    regex_t *regexp;  /* used to find usertrack cookie in cookie header */} cookie_dir_rec;/* Define this to allow post-2000 cookies. Cookies use two-digit dates, * so it might be dicey. (Netscape does it correctly, but others may not) */#define MILLENIAL_COOKIES/* Default name of the cookie */#define COOKIE_NAME "Apache"/* Make cookie id: Try to make something unique based on  * pid, time, and hostid, plus the user-configurable prefix. * */static char * make_cookie_id(char * buffer, int bufsize, request_rec *r,                             cookie_format_e cformat){#if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES)    clock_t mpe_times;    struct tms mpe_tms;#elif !defined(WIN32)    struct timeval tv;#ifdef NETWARE    time_t tz = 0;#else    struct timezone tz = {0, 0};#endif /* defined(NETWARE) */#endif    cookie_dir_rec *dcfg;    long reqtime = (long) r->request_time;    long clocktime;    unsigned long ipaddr = ntohl(r->connection->remote_addr.sin_addr.s_addr);    const char *rname = ap_get_remote_host(r->connection, r->per_dir_config,					   REMOTE_NAME);    dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module);#if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES)/* We lack gettimeofday(), so we must use time() to obtain the epoch   seconds, and then times() to obtain CPU clock ticks (milliseconds).   Combine this together to obtain a hopefully unique cookie ID. */    mpe_times = times(&mpe_tms);    clocktime = (long) mpe_tms.tms_utime;    #elif defined(NETWARE)    clocktime = (long) clock();#elif defined(WIN32)    /*     * We lack gettimeofday() and we lack times(). So we'll use     * GetTickCount(), which returns milliseconds since Windows     * was started. It should be relatively unique.     */    clocktime = (long) GetTickCount();#else    gettimeofday(&tv, &tz);    reqtime = (long) tv.tv_sec;    if (cformat == CF_COMPACT)	clocktime = (long) (tv.tv_usec % 65535);    else	clocktime = (long) (tv.tv_usec / 1000);#endif    if (cformat == CF_COMPACT)	ap_snprintf(buffer, bufsize, "%s%lx%x%lx%lx", 		    dcfg->prefix_string, ipaddr, (int) getpid(),                    reqtime, clocktime);    else	ap_snprintf(buffer, bufsize, "%s%s.%d%ld%ld", 		    dcfg->prefix_string, rname, (int) getpid(),                    reqtime, clocktime);    return buffer;}static void make_cookie(request_rec *r){    cookie_log_state *cls = ap_get_module_config(r->server->module_config,						 &usertrack_module);    /* 1024 == hardcoded constant */    char cookiebuf[1024];    char *new_cookie;    cookie_dir_rec *dcfg;    dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module);    make_cookie_id(cookiebuf, sizeof(cookiebuf), r, dcfg->format);    if (cls->expires) {        struct tm *tms;        time_t when;        when = cls->expires;        if ((dcfg->style == CT_UNSET) || (dcfg->style == CT_NETSCAPE)) {            when += r->request_time;#ifndef MILLENIAL_COOKIES        /*         * Only two-digit date string, so we can't trust "00" or more.         * Therefore, we knock it all back to just before midnight on         * 1/1/2000 (which is 946684799)         */        if (when > 946684799)            when = 946684799;#endif        }        tms = gmtime(&when);        /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */        new_cookie = ap_psprintf(r->pool, "%s=%s; path=/",                                 dcfg->cookie_name, cookiebuf);        if ((dcfg->style == CT_UNSET) || (dcfg->style == CT_NETSCAPE)) {            new_cookie = ap_psprintf(r->pool, "%s; "                                     "expires=%s, %.2d-%s-%.2d "                                     "%.2d:%.2d:%.2d GMT",                                     new_cookie,                                     ap_day_snames[tms->tm_wday],                                     tms->tm_mday,                                     ap_month_snames[tms->tm_mon],                                     tms->tm_year % 100,                                     tms->tm_hour, tms->tm_min, tms->tm_sec);        }        else {            new_cookie = ap_psprintf(r->pool, "%s; max-age=%d",                                     new_cookie, (int) when);        }    }    else {	new_cookie = ap_psprintf(r->pool, "%s=%s; path=/",				 dcfg->cookie_name, cookiebuf);    }    if (dcfg->cookie_domain != NULL) {        new_cookie = ap_psprintf(r->pool, "%s; domain=%s",                                 new_cookie, dcfg->cookie_domain);    }    if (dcfg->style == CT_COOKIE2) {        new_cookie = ap_pstrcat(r->pool, new_cookie, "; version=1", NULL);    }    ap_table_addn(r->headers_out,                  (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"),                  new_cookie);    ap_table_setn(r->notes, "cookie", ap_pstrdup(r->pool, cookiebuf));   /* log first time */    return;}/* * dcfg->regexp is "^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)", * which has three subexpressions, $0..$2 */#define NUM_SUBS 3static void set_and_comp_regexp(cookie_dir_rec *dcfg,                                 pool *p,                                const char *cookie_name) {    int danger_chars = 0;    const char *sp = cookie_name;    /*     * The goal is to end up with this regexp,      * ^cookie_name=([^;]+)|;[\t]+cookie_name=([^;]+)      * with cookie_name obviously substituted either     * with the real cookie name set by the user in httpd.conf,     * or with the default COOKIE_NAME.     */    /* Anyway, we need to escape the cookie_name before pasting it     * into the regex     */    while (*sp) {        if (!ap_isalnum(*sp)) {            ++danger_chars;        }        ++sp;    }    if (danger_chars) {        char *cp;        cp = ap_palloc(p, sp - cookie_name + danger_chars + 1); /* 1 == \0 */        sp = cookie_name;        cookie_name = cp;        while (*sp) {            if (!ap_isalnum(*sp)) {                *cp++ = '\\';            }            *cp++ = *sp++;        }        *cp = '\0';    }    dcfg->regexp_string = ap_pstrcat(p, "^", cookie_name,                                     "=([^;]+)|;[ \t]+", cookie_name,                                     "=([^;]+)", NULL);    dcfg->regexp = ap_pregcomp(p, dcfg->regexp_string, REG_EXTENDED);    ap_assert(dcfg->regexp != NULL);

⌨️ 快捷键说明

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