This is an automated email from the ASF dual-hosted git repository. mxmanghi pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git
The following commit(s) were added to refs/heads/master by this push: new bf0bb2a environment variables internals revision, add new tests to control their resolution and handling bf0bb2a is described below commit bf0bb2a066195be28b9ba2eeb02e3d9e9c495c74 Author: Massimo Manghi <massimo.man...@gmail.com> AuthorDate: Thu Oct 21 12:58:39 2021 +0200 environment variables internals revision, add new tests to control their resolution and handling --- ChangeLog | 25 ++- doc/xml/commands.xml | 2 +- src/mod_rivet_ng/TclWebapache.c | 357 ++++++++++++++++++++++++----------- src/mod_rivet_ng/rivetCore.c | 8 +- src/mod_rivet_ng/rivet_types.h | 2 +- tests/apachetest/template.conf.1.tcl | 2 +- tests/env.rvt | 22 ++- tests/env.test | 45 ++++- tests/env_methods.tcl | 15 ++ tests/rivet.test | 19 +- 10 files changed, 357 insertions(+), 140 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3934540..bf536f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,19 +1,26 @@ +2021-10-20 Massimo Manghi <mxman...@apache.org> + * src/mod_rivet_ng/Tclwebapache.c: new environment variable handling. + Command ::rivet::env doesn't necessarily trigger the whole enviroment load + into request_rec, it tries to resolve a variable incrementally. Need + to recommend the usage of ::rivet::env instead of ::rivet::load_env + * tests/env.rvt: adding new tests to environment variable resolution + 2021-09-06 Massimo Manghi <mxman...@apache.org> - * rivet/packages/session/session-create-*.sql: making cache fields larger + * rivet/packages/session/session-create-*.sql: making cache fields larger 2021-07-30 Massimo Manghi <mxman...@apache.org> - * src/mod_rivet_ng/TclWebapache.c: integrating the current scant Tcl error info - returned by the various ::rivet::upload subcommands - * rivet/packages/dio/: Removing references to subversion's tags + * src/mod_rivet_ng/TclWebapache.c: integrating the current scant Tcl error info + returned by the various ::rivet::upload subcommands + * rivet/packages/dio/: Removing references to subversion's tags 2021-04-13 Massimo Manghi <mxman...@apache.org> - * src/mod_rivet_ng/rivetInspect.c: add server current loglevel. Removed - unneeded ref count management in the server array construction + * src/mod_rivet_ng/rivetInspect.c: add server current loglevel. Removed + unneeded ref count management in the server array construction 2021-03-07 Massimo Manghi <mxman...@apache.org> - * VERSION: bumped version as 3.2.1 - * src/mod_rivet_ng/mod_rivet.c: more linear determination of the bridge name - * rivet/packages/formbroker.tcl: introduced key maxlength + * VERSION: bumped version as 3.2.1 + * src/mod_rivet_ng/mod_rivet.c: more linear determination of the bridge name + * rivet/packages/formbroker.tcl: introduced key maxlength 2020-11-19 Massimo Manghi <mxman...@apache.org> * rivet/packages/dio/dio.tcl,dio_Mysql.tcl: adding support for diff --git a/doc/xml/commands.xml b/doc/xml/commands.xml index 38ee5ab..8e1c3e0 100644 --- a/doc/xml/commands.xml +++ b/doc/xml/commands.xml @@ -539,7 +539,7 @@ for any special (with respect to SGML, and hence HTML) characters from the specified string, and returns the result. For example, the right angle bracket is escaped to the corrected - ampersand gt symbol. + ampersand gt symbol. </para> </refsect1> </refentry> diff --git a/src/mod_rivet_ng/TclWebapache.c b/src/mod_rivet_ng/TclWebapache.c index 3f79c33..d4ae276 100644 --- a/src/mod_rivet_ng/TclWebapache.c +++ b/src/mod_rivet_ng/TclWebapache.c @@ -41,15 +41,29 @@ extern module rivet_module; extern mod_rivet_globals* module_globals; -#define TCLWEBPOOL req->req->pool -#define BUFSZ 4096 +/* It's kind of an overkill, but we define macros for handling the + * flags that control and reduce the overhead when loading the + * environment variables */ + +#define ENV_COMMON_VARS_M 1 +#define ENV_CGI_VARS_M 2 +#define ENV_VARS_M 4 +#define ENV_VARS_RESET(env) env = 0; +#define ENV_COMMON_VARS(env) env |= ENV_COMMON_VARS_M; +#define ENV_CGI_VARS(env) env |= ENV_CGI_VARS_M; +#define ENV_VARS(env) env |= ENV_VARS_M; + +#define ENV_IS_LOADED(env) (env == (ENV_COMMON_VARS_M | ENV_CGI_VARS_M | ENV_VARS_M)) +#define ENV_COMMON_VARS_LOADED(env) (env & ENV_COMMON_VARS_M) != 0 +#define ENV_CGI_VARS_LOADED(env) (env & ENV_CGI_VARS_M) != 0 +#define ENV_VARS_LOADED(env) (env & ENV_VARS_M) != 0 /* This is used below to determine what part of the parmsarray to parse. */ -#define PARMSARRAY_COORDINATES i = 0; j = parmsarray->nelts; \ -if (source == VAR_SRC_QUERYSTRING) { j = req->apachereq->nargs; } \ -else if (source == VAR_SRC_POST) { i = req->apachereq->nargs; } +#define PARMSARRAY_COORDINATES(i,j,parray,nargs) i = 0; j = parray->nelts; \ +if (source == VAR_SRC_QUERYSTRING) { j = nargs; } \ +else if (source == VAR_SRC_POST) { i = nargs; } /* * -- TclWeb_NewRequestObject @@ -67,13 +81,12 @@ TclWeb_NewRequestObject (apr_pool_t *p) req->apachereq = ApacheRequest_new(p); req->headers_printed = 0; req->headers_set = 0; - req->environment_set = 0; + ENV_VARS_RESET(req->environment_set) req->charset = NULL; /* we will test against NULL to check if a charset * * was specified in the conf */ return req; } - /* * -- TclWeb_InitRequest * @@ -101,7 +114,7 @@ TclWeb_InitRequest(rivet_thread_private* private, Tcl_Interp *interp) req->apachereq = ApacheRequest_init(req->apachereq,r); req->headers_printed = 0; req->headers_set = 0; - req->environment_set = 0; + ENV_VARS_RESET(req->environment_set) req->charset = NULL; /* @@ -156,8 +169,6 @@ TclWeb_SetHeaderType(char *header, TclWebRequest *req) if (req->headers_set) return TCL_ERROR; -// req->req->content_type = (char *) apr_pstrdup(req->req->pool, header); - ap_set_content_type(req->req,apr_pstrdup(req->req->pool, header)); req->headers_set = 1; return TCL_OK; @@ -187,7 +198,6 @@ TclWeb_PrintHeaders(TclWebRequest *req) */ TclWeb_SendHeaders(req); - /* ap_send_http_header(req->req); */ req->headers_printed = 1; return TCL_OK; @@ -207,7 +217,7 @@ TclWeb_PrintError(CONST84 char *errstr, int htmlflag, TclWebRequest *req) { if (htmlflag != 1) { - ap_rputs(ap_escape_html(TCLWEBPOOL, errstr), req->req); + ap_rputs(ap_escape_html(req->req->pool,errstr),req->req); } else { ap_rputs(errstr, req->req); } @@ -270,65 +280,66 @@ INLINE int TclWeb_MakeURL(Tcl_Obj *result, char *filename, TclWebRequest *req) { Tcl_SetStringObj(result, - ap_construct_url(TCLWEBPOOL,filename,req->req),-1); + ap_construct_url(req->req->pool,filename,req->req),-1); return TCL_OK; } int TclWeb_GetVar(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) { - int i, j; - apr_array_header_t *parmsarray = (apr_array_header_t *) - apr_table_elts(req->apachereq->parms); - apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; + int i,j; + apr_array_header_t *parmsarray = (apr_array_header_t *)apr_table_elts(req->apachereq->parms); + apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; int flag = 0; - PARMSARRAY_COORDINATES; + PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) /* This isn't real efficient - move to hash table later on... */ while (i < j) { char *parmkey = TclWeb_StringToUtf(parms[i].key, req); - if (!strncmp(varname, parmkey, + if (!strncmp(varname,parmkey, strlen(varname) < strlen(parmkey) ? strlen(parmkey) : strlen(varname))) { + /* The following makes sure that we get one string, with no sub lists. */ + if (flag == 0) { + flag = 1; - Tcl_SetStringObj(result, - TclWeb_StringToUtf(parms[i].val, req), -1); + Tcl_SetStringObj (result,TclWeb_StringToUtf(parms[i].val,req),-1); + } else { + Tcl_Obj *tmpobj; Tcl_Obj *tmpobjv[2]; tmpobjv[0] = result; - tmpobjv[1] = TclWeb_StringToUtfToObj(parms[i].val, req); - tmpobj = Tcl_ConcatObj(2, tmpobjv); - Tcl_SetStringObj(result, Tcl_GetString(tmpobj), -1); + tmpobjv[1] = TclWeb_StringToUtfToObj (parms[i].val,req); + tmpobj = Tcl_ConcatObj (2,tmpobjv); + Tcl_SetStringObj (result,Tcl_GetString(tmpobj),-1); + } + } i++; } - if (result->length == 0) - { - return TCL_ERROR; - } + if (result->length == 0) { return TCL_ERROR; } return TCL_OK; } int -TclWeb_GetVarAsList(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) -{ +TclWeb_GetVarAsList(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) { int i, j; apr_array_header_t *parmsarray = (apr_array_header_t *) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; - PARMSARRAY_COORDINATES; + PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) /* This isn't real efficient - move to hash table later on. */ while (i < j) @@ -359,20 +370,20 @@ TclWeb_GetAllVars(Tcl_Obj *result, int source, TclWebRequest *req) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; - PARMSARRAY_COORDINATES; + PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) while (i < j) { - Tcl_ListObjAppendElement(req->interp, result, - TclWeb_StringToUtfToObj(parms[i].key, req)); - Tcl_ListObjAppendElement(req->interp, result, - TclWeb_StringToUtfToObj(parms[i].val, req)); - i++; + Tcl_ListObjAppendElement(req->interp,result, + TclWeb_StringToUtfToObj(parms[i].key,req)); + Tcl_ListObjAppendElement(req->interp,result, + TclWeb_StringToUtfToObj(parms[i].val,req)); + i++; } if (result == NULL) { - return TCL_ERROR; + return TCL_ERROR; } return TCL_OK; } @@ -385,18 +396,18 @@ TclWeb_GetVarNames(Tcl_Obj *result, int source, TclWebRequest *req) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; - PARMSARRAY_COORDINATES; + PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) while (i < j) { - Tcl_ListObjAppendElement(req->interp, result, - TclWeb_StringToUtfToObj(parms[i].key, req)); - i++; + Tcl_ListObjAppendElement(req->interp, result, + TclWeb_StringToUtfToObj(parms[i].key, req)); + i++; } if (result == NULL) { - return TCL_ERROR; + return TCL_ERROR; } return TCL_OK; @@ -410,7 +421,7 @@ TclWeb_VarExists(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; - PARMSARRAY_COORDINATES; + PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) /* This isn't real efficient - move to hash table later on. */ while (i < j) @@ -445,79 +456,181 @@ TclWeb_VarNumber(Tcl_Obj *result, int source, TclWebRequest *req) return TCL_OK; } +/* These 2 array must be aligned and a one-to-one correspondence preserved + * The enum include_vars_idx must be terminated by 'inval_env_var' + */ + +static const char* include_env_vars[] = +{ + "DATE_LOCAL","DATE_GMT","LAST_MODIFIED","DOCUMENT_URI","DOCUMENT_PATH_INFO","DOCUMENT_NAME", + "QUERY_STRING_UNESCAPED","USER_NAME","RIVET_CACHE_FREE","RIVET_CACHE_SIZE", + NULL +}; +enum include_vars_idx { + date_local=0,date_gmt,last_modified,document_uri,document_path_info,document_name, + query_string_unescaped,user_name,rivet_cache_free,rivet_cache_size, + invalid_env_var +}; + +static char* +TclWeb_SelectEnvIncludeVar (rivet_thread_private* private,int idx) +{ + switch (idx) + { + case date_local: + { + apr_pool_t* pool = private->req->req->pool; + apr_time_t date = private->req->req->request_time; + + return ap_ht_time(pool,date,DEFAULT_TIME_FORMAT,0); + } + case date_gmt: + { + apr_pool_t* pool = private->req->req->pool; + apr_time_t date = private->req->req->request_time; + + return ap_ht_time(pool,date,DEFAULT_TIME_FORMAT,1); + } + case last_modified: + { + apr_pool_t* pool = private->req->req->pool; + + return ap_ht_time(pool,private->req->req->finfo.mtime,DEFAULT_TIME_FORMAT,1); + } + case document_uri: + { + return private->req->req->uri; + } + case document_path_info: + { + return private->req->req->path_info; + } + case document_name: + { + char *t; + + if ((t = strrchr(private->req->req->filename,'/'))) { + return ++t; + } else { + return private->req->req->uri; + } + } + case query_string_unescaped: + { + if (private->req->req->args) { + apr_pool_t* pool = private->req->req->pool; + char *arg_copy = (char*) apr_pstrdup(pool,private->req->req->args); + + ap_unescape_url(arg_copy); + return ap_escape_shell_cmd(pool,arg_copy); + } else { + return NULL; + } + + } + case user_name: + { +#ifndef WIN32 + struct passwd *pw = (struct passwd *) getpwuid(private->req->req->finfo.user); + if (pw) { + //apr_table_set( table, "USER_NAME", + // apr_pstrdup( pool, pw->pw_name ) ); + return pw->pw_name; + } else { + apr_pool_t* pool = private->req->req->pool; + return (char*) apr_psprintf(pool,"user#%lu",(unsigned long)private->req->req->finfo.user); + } +#else + return NULL; +#endif + } + case rivet_cache_free: + { + apr_pool_t* pool = private->req->req->pool; + return (char*) apr_psprintf (pool, "%d",(RIVET_PEEK_INTERP(private,private->running_conf))->cache_free); + } + case rivet_cache_size: + { + apr_pool_t* pool = private->req->req->pool; + return (char*) apr_psprintf (pool, "%d",(RIVET_PEEK_INTERP(private,private->running_conf))->cache_size); + } + } + return NULL; +} + /* - * Load the Apache environment and CGI variables into the request. If we - * have already done so, we don't need to do it again. + * -- TclWeb_InitEnvVars + * + * Load the CGI and environment variables into the request_rec environment structure + * Variables belong to 3 cathegories + * + * + common variables (ap_add_common_vars) + * + CGI variables (ad_cgi_vars) + * + a miscellaneous set of variables + * listed in the array include_env_vars + * + * Each cathegory is controlled by flags in order to reduce the overhead of getting them + * into request_rec in case previous call to ::rivet::env could have already forced them + * into request_rec */ + static void TclWeb_InitEnvVars (rivet_thread_private* private) { - //rivet_server_conf *rsc; - char *timefmt = DEFAULT_TIME_FORMAT; - char *t; - apr_time_t date; -#ifndef WIN32 - struct passwd *pw; -#endif /* ndef WIN32 */ - TclWebRequest *req; - apr_table_t *table; + TclWebRequest *req = private->req; + apr_table_t *table; + int idx; - req = private->req; - table = req->req->subprocess_env; - date = req->req->request_time; - - if( req->environment_set ) return; + if (ENV_IS_LOADED(req->environment_set)) return; - //rsc = RIVET_SERVER_CONF( req->req->server->module_config ); + table = req->req->subprocess_env; /* Retrieve cgi variables. */ - ap_add_cgi_vars( req->req ); - ap_add_common_vars( req->req ); - - /* These were the "include vars" */ - - apr_table_set( table, "DATE_LOCAL", - ap_ht_time( TCLWEBPOOL, date, timefmt, 0 ) ); - apr_table_set( table, "DATE_GMT", - ap_ht_time( TCLWEBPOOL, date, timefmt, 1 ) ); - apr_table_set( table, "LAST_MODIFIED", - ap_ht_time( TCLWEBPOOL, req->req->finfo.mtime, timefmt, 1 ) ); - apr_table_set( table, "DOCUMENT_URI", req->req->uri ); - apr_table_set( table, "DOCUMENT_PATH_INFO", req->req->path_info ); - - if ((t = strrchr(req->req->filename, '/'))) { - apr_table_set( table, "DOCUMENT_NAME", ++t ); - } else { - apr_table_set( table, "DOCUMENT_NAME", req->req->uri ); + if (!ENV_CGI_VARS_LOADED(req->environment_set)) + { + ap_add_cgi_vars(req->req); + ENV_CGI_VARS(req->environment_set); } - - if( req->req->args ) { - char *arg_copy = (char*) apr_pstrdup(TCLWEBPOOL, req->req->args); - ap_unescape_url(arg_copy); - apr_table_set( table, "QUERY_STRING_UNESCAPED", - ap_escape_shell_cmd( TCLWEBPOOL, arg_copy ) ); + if (!ENV_COMMON_VARS_LOADED(req->environment_set)) + { + ap_add_common_vars(req->req); + ENV_COMMON_VARS(req->environment_set) } -#ifndef WIN32 - pw = (struct passwd *) getpwuid(req->req->finfo.user); - if( pw ) { - //apr_table_set( table, "USER_NAME", - // apr_pstrdup( TCLWEBPOOL, pw->pw_name ) ); - } else { - apr_table_set( table, "USER_NAME", - (char*) apr_psprintf( TCLWEBPOOL, "user#%lu", - (unsigned long)req->req->finfo.user ) ); + /* Loading into 'table' the include vars */ + + /* actually this is not necessary. ENV_VARS is modified only here therefore + * if it's set this function has been called already + * and it should have returned at the beginning of the execution. I keep + * it for clarity and uniformity with the CGI variables and in case + * the incremental environment control is extended + */ + + if (!ENV_VARS_LOADED(req->environment_set)) + { + for (idx = 0;idx < invalid_env_var;idx++) + { + apr_table_set(table,include_env_vars[idx],TclWeb_SelectEnvIncludeVar(private,idx)); + } + ENV_VARS(req->environment_set) } -#endif - /* Here we create some variables with Rivet internal information. */ +} - apr_table_set (table, "RIVET_CACHE_FREE", - (char*) apr_psprintf (TCLWEBPOOL, "%d",(RIVET_PEEK_INTERP(private,private->running_conf))->cache_free)); - apr_table_set (table, "RIVET_CACHE_SIZE", - (char*) apr_psprintf (TCLWEBPOOL, "%d",(RIVET_PEEK_INTERP(private,private->running_conf))->cache_size)); +static char* +TclWeb_GetEnvIncludeVar (rivet_thread_private* private,char* key) +{ + int idx; - req->environment_set = 1; + for (idx = 0;idx < invalid_env_var; idx++) + { + const char* include_var_p = include_env_vars[idx]; + if (strncmp(key,include_var_p,strlen(key) < strlen(include_var_p) ? strlen(key) : strlen(include_var_p)) == 0) + { + return TclWeb_SelectEnvIncludeVar(private,idx); + } + } + return NULL; } int @@ -610,21 +723,21 @@ TclWeb_GetHeaderVars(Tcl_Obj *headersvar,rivet_thread_private* private) INLINE int TclWeb_Base64Encode(char *out, char *in, TclWebRequest *req) { - out = ap_pbase64encode(TCLWEBPOOL, in); + out = ap_pbase64encode(req->req->pool, in); return TCL_OK; } INLINE int TclWeb_Base64Decode(char *out, char *in, TclWebRequest *req) { - out = ap_pbase64decode(TCLWEBPOOL, in); + out = ap_pbase64decode(req->req->pool, in); return TCL_OK; } INLINE int TclWeb_EscapeShellCommand(char *out, char *in, TclWebRequest *req) { - out = ap_escape_shell_cmd(TCLWEBPOOL, in); + out = ap_escape_shell_cmd(req->req->pool, in); return TCL_OK; } @@ -639,7 +752,7 @@ char *TclWeb_StringToUtf(char *in, TclWebRequest *req) Tcl_DString dstr; Tcl_DStringInit(&dstr); Tcl_ExternalToUtfDString(NULL, in, (signed)strlen(in), &dstr); - tmp = (char*) apr_pstrdup(TCLWEBPOOL, Tcl_DStringValue(&dstr)); + tmp = (char*) apr_pstrdup(req->req->pool, Tcl_DStringValue(&dstr)); Tcl_DStringFree(&dstr); return tmp; } @@ -678,7 +791,7 @@ int TclWeb_UploadChannel(char *varname, TclWebRequest *req) } Tcl_RegisterChannel(req->interp,chan); - result = Tcl_NewObj(); + result = Tcl_NewObj(); Tcl_SetStringObj(result, Tcl_GetChannelName(chan), -1); Tcl_SetObjResult(req->interp, result); @@ -829,23 +942,37 @@ char * TclWeb_GetEnvVar(rivet_thread_private* private,char *key) { char *val; - TclWebRequest *req; - - req = private->req; - TclWeb_InitEnvVars(private); + TclWebRequest *req = private->req; /* Check to see if it's a header variable first. */ - val = (char *)apr_table_get( req->req->headers_in, key ); + val = (char *)apr_table_get (req->req->headers_in,key); + if (val) { return val; } + + /* We incrementally prepare subprocess_env */ + /* CGI common vars first */ - if( !val ) { - val = (char *)apr_table_get( req->req->subprocess_env, key ); + if (!ENV_COMMON_VARS_LOADED(req->environment_set)) + { + ap_add_common_vars(req->req); + ENV_COMMON_VARS(req->environment_set) } + val = (char *)apr_table_get(req->req->subprocess_env,key); + if (val) { return val; } - return val; + /* CGI HTTP 1.1 vars */ + + if (!ENV_CGI_VARS_LOADED(req->environment_set)) + { + ap_add_cgi_vars(req->req); + ENV_CGI_VARS(req->environment_set) + } + val = (char *)apr_table_get(req->req->subprocess_env,key); + if (val) { return val; } + return TclWeb_GetEnvIncludeVar(private,key); } char * -TclWeb_GetVirtualFile( TclWebRequest *req, char *virtualname ) +TclWeb_GetVirtualFile(TclWebRequest *req, char *virtualname) { request_rec *apreq; char *filename = NULL; diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c index c7d4e21..1554bb2 100644 --- a/src/mod_rivet_ng/rivetCore.c +++ b/src/mod_rivet_ng/rivetCore.c @@ -669,9 +669,9 @@ TCL_CMD_HEADER ( Rivet_Var ) "|number|all)"); return TCL_ERROR; } - cmd = Tcl_GetString(objv[0]); + cmd = Tcl_GetString(objv[0]); command = Tcl_GetString(objv[1]); - result = Tcl_NewObj(); + result = Tcl_NewObj(); /* determine if var_qs, var_post or var was called */ @@ -1414,9 +1414,9 @@ TCL_CMD_HEADER( Rivet_EnvCmd ) return TCL_ERROR; } - key = Tcl_GetStringFromObj( objv[1], NULL ); + key = Tcl_GetStringFromObj (objv[1],NULL); - val = TclWeb_GetEnvVar( private, key ); + val = TclWeb_GetEnvVar (private,key); Tcl_SetObjResult(interp, Tcl_NewStringObj( val, -1 ) ); return TCL_OK; diff --git a/src/mod_rivet_ng/rivet_types.h b/src/mod_rivet_ng/rivet_types.h index 6d24ff4..d3f30ca 100644 --- a/src/mod_rivet_ng/rivet_types.h +++ b/src/mod_rivet_ng/rivet_types.h @@ -87,7 +87,7 @@ typedef struct TclWebRequest { int headers_printed; /* has the header been printed yet? */ int headers_set; /* has the header been set yet? */ int content_sent; - int environment_set; /* have we setup the environment variables? */ + unsigned int environment_set; /* have we setup the environment variables? */ char* charset; } TclWebRequest; diff --git a/tests/apachetest/template.conf.1.tcl b/tests/apachetest/template.conf.1.tcl index 5b96c92..b63cacc 100644 --- a/tests/apachetest/template.conf.1.tcl +++ b/tests/apachetest/template.conf.1.tcl @@ -1,4 +1,4 @@ -# \$Id\$ + # Minimal config file for testing # Parsed by makeconf.tcl diff --git a/tests/env.rvt b/tests/env.rvt index d039ce0..fe45389 100644 --- a/tests/env.rvt +++ b/tests/env.rvt @@ -1,7 +1,25 @@ <? -::rivet::load_env +if {[::rivet::var_qs exists protocol]} { -puts "env(DOCUMENT_NAME) = $env(DOCUMENT_NAME)\n" + puts [::rivet::env SERVER_PROTOCOL] +} else { + + set load_env_f [::rivet::var get load_env 0] + + if {[string is true $load_env_f]} { + + # test env-1.1 + + ::rivet::load_env + puts "env(DOCUMENT_NAME) = $env(DOCUMENT_NAME)\n" + } else { + + # test env-1.2 + + set doc_name [::rivet::env DOCUMENT_NAME] + puts "env(DOCUMENT_NAME) = $doc_name\n" + } +} ?> diff --git a/tests/env.test b/tests/env.test index 05de770..155836c 100644 --- a/tests/env.test +++ b/tests/env.test @@ -1,9 +1,44 @@ -# $Id$ +# +# testing how the environment variables resolution +# is handled by mod_rivet +# -set testfilename1 env.rvt +set rvttestfilename env.rvt ::tcltest::test env-1.1 {Environment variable} { - set page [ ::http::geturl "${urlbase}$testfilename1" ] - regexp -line "^env\\(DOCUMENT_NAME\\) = $testfilename1\$" [ ::http::data $page ] match + set page [ ::http::geturl "${urlbase}$rvttestfilename?load_env=true" ] + regexp -line "^env\\(DOCUMENT_NAME\\) = $rvttestfilename\$" [::http::data $page] match set match -} "env(DOCUMENT_NAME) = $testfilename1" +} "env(DOCUMENT_NAME) = $rvttestfilename" + +::tcltest::test env-1.2 {Environment variable} { + set page [ ::http::geturl "${urlbase}$rvttestfilename?load_env=false" ] + regexp -line "^env\\(DOCUMENT_NAME\\) = $rvttestfilename\$" [::http::data $page] match + set match +} "env(DOCUMENT_NAME) = $rvttestfilename" + +::tcltest::test env-1.2.1 {CGI Environment variable double translation} { + set page1 [ ::http::geturl "${urlbase}$rvttestfilename?protocol=1"] + set match1 [string trim [::http::data $page1]] + set page2 [ ::http::geturl "${urlbase}$rvttestfilename?protocol=1"] + set match2 [string trim [::http::data $page2]] + #puts "proto: $match1 $match2" + expr [string match $match1 $match2] +} "1" + +set envmethod env_methods.tcl +set env_vars [list "DATE_LOCAL" "DATE_GMT" "LAST_MODIFIED" "DOCUMENT_URI" "DOCUMENT_PATH_INFO" "DOCUMENT_NAME" \ + "QUERY_STRING_UNESCAPED" "RIVET_CACHE_FREE" "RIVET_CACHE_SIZE" "HTTP_ACCEPT" "HTTP_HOST" \ + "QUERY_STRING" "SCRIPT_FILENAME" "SERVER_NAME" "SERVER_PORT" "SERVER_PROTOCOL"] + +puts "comparing ::rivet::env and ::rivet::load_env for variable resolution" +foreach v $env_vars { + puts -nonewline "$v " + ::tcltest::test env-1.3 {Environment variable methods} { + set page [::http::geturl "${urlbase}$envmethod?envvar=$v"] + ::http::data $page + } "$v: OK" +} +puts "" + + diff --git a/tests/env_methods.tcl b/tests/env_methods.tcl new file mode 100644 index 0000000..e52b003 --- /dev/null +++ b/tests/env_methods.tcl @@ -0,0 +1,15 @@ + + set envvar [::rivet::var_qs get envvar] + set v1 [::rivet::env $envvar] + + ::rivet::load_env loadenv + set v2 $loadenv($envvar) + set comp [string match $v1 $v2] + if {$comp} { + set msg OK + } else { + set msg "env: $v1, load_env: $v2" + } + + puts -nonewline "$envvar: $msg" + diff --git a/tests/rivet.test b/tests/rivet.test index fade49a..6ed3950 100755 --- a/tests/rivet.test +++ b/tests/rivet.test @@ -2,6 +2,23 @@ # the next line restarts using tclsh \ exec tclsh "$0" "$@" +# 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. + # Rivet test suite, by David N. Welton <dav...@apache.org> # See README file for more information. @@ -27,8 +44,6 @@ set testgroup1 1 set testgroup2 1 set testgroup3 1 -#lappend TestList failtest.test - # Run all tests against one server process. if { $testgroup1 } { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@tcl.apache.org For additional commands, e-mail: commits-h...@tcl.apache.org