Project

General

Profile

mod_ssi_recursion-1.4.15.patch

rerursive SSI for 1.4.15 -- dustin - Anonymous, 2007-05-11 19:21

View differences:

src/mod_ssi.c Fri May 11 10:03:02 2007 -0700 → src/mod_ssi.c Fri May 11 12:09:49 2007 -0700
36 36
#include <sys/filio.h>
37 37
#endif
38 38

  
39
#define DEFAULT_MAX_SSI_RECURSION 25
40

  
39 41
/* init the plugin data */
40 42
INIT_FUNC(mod_ssi_init) {
41 43
	plugin_data *p;
......
94 96
#endif
95 97

  
96 98
	config_values_t cv[] = {
97
		{ "ssi.extension",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
98
		{ NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
99
		{ "ssi.extension",				NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },		 /* 0 */
100
		{ "ssi.max_recursion",			NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },		 /* 1 */
101
		{ NULL,							NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
99 102
	};
100 103

  
101 104
	if (!p) return HANDLER_ERROR;
......
107 110

  
108 111
		s = calloc(1, sizeof(plugin_config));
109 112
		s->ssi_extension  = array_init();
113
		s->ssi_max_recursion  = DEFAULT_MAX_SSI_RECURSION;
110 114

  
111 115
		cv[0].destination = s->ssi_extension;
116
		cv[1].destination = &(s->ssi_max_recursion);
112 117

  
113 118
		p->config_storage[i] = s;
114 119

  
......
150 155

  
151 156
/**
152 157
 *
153
 *  the next two functions are take from fcgi.c
158
 *	the next two functions are take from fcgi.c
154 159
 *
155 160
 */
156 161

  
......
214 219
	ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION);
215 220
	ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"),
216 221
#ifdef HAVE_IPV6
217
		     inet_ntop(srv_sock->addr.plain.sa_family,
218
			       srv_sock->addr.plain.sa_family == AF_INET6 ?
219
			       (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
220
			       (const void *) &(srv_sock->addr.ipv4.sin_addr),
221
			       b2, sizeof(b2)-1)
222
			 inet_ntop(srv_sock->addr.plain.sa_family,
223
				   srv_sock->addr.plain.sa_family == AF_INET6 ?
224
				   (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
225
				   (const void *) &(srv_sock->addr.ipv4.sin_addr),
226
				   b2, sizeof(b2)-1)
222 227
#else
223
		     inet_ntoa(srv_sock->addr.ipv4.sin_addr)
224
#endif
225
		     );
228
			 inet_ntoa(srv_sock->addr.ipv4.sin_addr)
229
#endif
230
			 );
226 231
	ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1");
227 232

  
228 233
	ltostr(buf,
229 234
#ifdef HAVE_IPV6
230
	       ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
235
		   ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
231 236
#else
232
	       ntohs(srv_sock->addr.ipv4.sin_port)
233
#endif
234
	       );
237
		   ntohs(srv_sock->addr.ipv4.sin_port)
238
#endif
239
		   );
235 240

  
236 241
	ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf);
237 242

  
238 243
	ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"),
239
		    inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
244
			inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
240 245

  
241 246
	if (con->authed_user->used) {
242 247
		ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"),
243
			     con->authed_user->ptr);
248
				 con->authed_user->ptr);
244 249
	}
245 250

  
246 251
	if (con->request.content_length > 0) {
......
286 291
	return 0;
287 292
}
288 293

  
294
URIHANDLER_FUNC(mod_ssi_physical_path);
295

  
289 296
static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
290
			    const char **l, size_t n) {
297
				const char **l, size_t n) {
291 298
	size_t i, ssicmd = 0;
292 299
	char buf[255];
293 300
	buffer *b = NULL;
......
298 305
				SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF,
299 306
				SSI_ELSE, SSI_ENDIF, SSI_EXEC } type;
300 307
	} ssicmds[] = {
301
		{ "echo",     SSI_ECHO },
308
		{ "echo",	  SSI_ECHO },
302 309
		{ "include",  SSI_INCLUDE },
303 310
		{ "flastmod", SSI_FLASTMOD },
304
		{ "fsize",    SSI_FSIZE },
311
		{ "fsize",	  SSI_FSIZE },
305 312
		{ "config",   SSI_CONFIG },
306 313
		{ "printenv", SSI_PRINTENV },
307
		{ "set",      SSI_SET },
308
		{ "if",       SSI_IF },
309
		{ "elif",     SSI_ELIF },
310
		{ "endif",    SSI_ENDIF },
311
		{ "else",     SSI_ELSE },
312
		{ "exec",     SSI_EXEC },
314
		{ "set",	  SSI_SET },
315
		{ "if",		  SSI_IF },
316
		{ "elif",	  SSI_ELIF },
317
		{ "endif",	  SSI_ENDIF },
318
		{ "else",	  SSI_ELSE },
319
		{ "exec",	  SSI_EXEC },
313 320

  
314 321
		{ NULL, SSI_UNSET }
315 322
	};
......
333 340
			enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI,
334 341
					SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type;
335 342
		} echovars[] = {
336
			{ "DATE_GMT",      SSI_ECHO_DATE_GMT },
343
			{ "DATE_GMT",	   SSI_ECHO_DATE_GMT },
337 344
			{ "DATE_LOCAL",    SSI_ECHO_DATE_LOCAL },
338 345
			{ "DOCUMENT_NAME", SSI_ECHO_DOCUMENT_NAME },
339 346
			{ "DOCUMENT_URI",  SSI_ECHO_DOCUMENT_URI },
340 347
			{ "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED },
341
			{ "USER_NAME",     SSI_ECHO_USER_NAME },
348
			{ "USER_NAME",	   SSI_ECHO_USER_NAME },
342 349

  
343 350
			{ NULL, SSI_ECHO_UNSET }
344 351
		};
......
347 354
			const char *var;
348 355
			enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type;
349 356
		} encvars[] = {
350
			{ "url",          SSI_ENC_URL },
351
			{ "none",         SSI_ENC_NONE },
352
			{ "entity",       SSI_ENC_ENTITY },
357
			{ "url",		  SSI_ENC_URL },
358
			{ "none",		  SSI_ENC_NONE },
359
			{ "entity",		  SSI_ENC_ENTITY },
353 360

  
354 361
			{ NULL, SSI_ENC_UNSET }
355 362
		};
......
546 553
		}
547 554

  
548 555
		if (0 == stat(p->stat_fn->ptr, &st)) {
556
			buffer *tmp = NULL;
549 557
			time_t t = st.st_mtime;
550 558

  
551 559
			switch (ssicmd) {
......
574 582
				}
575 583
				break;
576 584
			case SSI_INCLUDE:
577
				chunkqueue_append_file(con->write_queue, p->stat_fn, 0, st.st_size);
585
				/* do recursive SSI expansion */
586

  
587
				/* prevents infinite loop */
588
				if (buffer_is_equal(con->physical.path, p->stat_fn)) {
589
					buffer_copy_string(srv->tmp_buf, "<!-- your include directives create an infinite loop; aborting -->");
590
					chunkqueue_append_buffer(con->write_queue, srv->tmp_buf);
591
					break;
592
				}
593

  
594
				/* only allow predefined recursion depth */
595
				if (con->loops_per_request > p->conf.ssi_max_recursion) {
596
					buffer_copy_string(srv->tmp_buf, "<!-- your include directives recurse deeper than pre-defined max_recursion; aborting -->");
597
					chunkqueue_append_buffer(con->write_queue, srv->tmp_buf);
598
					break;
599
				}
600

  
601
				tmp = buffer_init();
602
				/* save path of current document */
603
				buffer_copy_string_buffer(tmp, con->physical.path);
604
				/* next sub-document to parse */
605
				buffer_copy_string_buffer(con->physical.path, p->stat_fn);
606
				if (mod_ssi_physical_path(srv,con,p) != HANDLER_FINISHED) {
607
					/* the document was not processed, so write it as is */
608
					chunkqueue_append_file(con->write_queue, con->physical.path, 0, st.st_size);
609
				}
610
				/* restore saved path */
611
				buffer_copy_string_buffer(con->physical.path, tmp);
612
				buffer_free(tmp);
578 613
				break;
579 614
			}
580 615
		} else {
......
795 830
		}
796 831

  
797 832
		if ((!p->if_is_false) &&
798
		    ((p->if_is_false_level == 0) ||
799
		     (p->if_level < p->if_is_false_level))) {
833
			((p->if_is_false_level == 0) ||
834
			 (p->if_level < p->if_is_false_level))) {
800 835
			switch (ssi_eval_expr(srv, con, p, expr)) {
801 836
			case -1:
802 837
			case 0:
......
818 853

  
819 854
		if (p->if_is_false) {
820 855
			if ((p->if_level == p->if_is_false_level) &&
821
			    (p->if_is_false_endif == 0)) {
856
				(p->if_is_false_endif == 0)) {
822 857
				p->if_is_false = 0;
823 858
			}
824 859
		} else {
......
852 887

  
853 888
		if (p->if_level == p->if_is_false_level) {
854 889
			if ((p->if_is_false) &&
855
			    (p->if_is_false_endif == 0)) {
890
				(p->if_is_false_endif == 0)) {
856 891
				switch (ssi_eval_expr(srv, con, p, expr)) {
857 892
				case -1:
858 893
				case 0:
......
896 931

  
897 932
static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) {
898 933
	stream s;
899
#ifdef  HAVE_PCRE_H
934
#ifdef	HAVE_PCRE_H
900 935
	int i, n;
901 936

  
902 937
#define N 10
......
922 957
	/**
923 958
	 * <!--#element attribute=value attribute=value ... -->
924 959
	 *
925
	 * config       DONE
926
	 *   errmsg     -- missing
927
	 *   sizefmt    DONE
928
	 *   timefmt    DONE
929
	 * echo         DONE
930
	 *   var        DONE
931
	 *   encoding   -- missing
932
	 * exec         DONE
933
	 *   cgi        -- never
934
	 *   cmd        DONE
935
	 * fsize        DONE
936
	 *   file       DONE
937
	 *   virtual    DONE
938
	 * flastmod     DONE
939
	 *   file       DONE
940
	 *   virtual    DONE
941
	 * include      DONE
942
	 *   file       DONE
943
	 *   virtual    DONE
944
	 * printenv     DONE
945
	 * set          DONE
946
	 *   var        DONE
947
	 *   value      DONE
960
	 * config		DONE
961
	 *	 errmsg		-- missing
962
	 *	 sizefmt	DONE
963
	 *	 timefmt	DONE
964
	 * echo			DONE
965
	 *	 var		DONE
966
	 *	 encoding	-- missing
967
	 * exec			DONE
968
	 *	 cgi		-- never
969
	 *	 cmd		DONE
970
	 * fsize		DONE
971
	 *	 file		DONE
972
	 *	 virtual	DONE
973
	 * flastmod		DONE
974
	 *	 file		DONE
975
	 *	 virtual	DONE
976
	 * include		DONE
977
	 *	 file		DONE
978
	 *	 virtual	DONE
979
	 * printenv		DONE
980
	 * set			DONE
981
	 *	 var		DONE
982
	 *	 value		DONE
948 983
	 *
949
	 * if           DONE
950
	 * elif         DONE
951
	 * else         DONE
952
	 * endif        DONE
984
	 * if			DONE
985
	 * elif			DONE
986
	 * else			DONE
987
	 * endif		DONE
953 988
	 *
954 989
	 *
955 990
	 * expressions
956
	 * AND, OR      DONE
957
	 * comp         DONE
958
	 * ${...}       -- missing
959
	 * $...         DONE
960
	 * '...'        DONE
961
	 * ( ... )      DONE
991
	 * AND, OR		DONE
992
	 * comp			DONE
993
	 * ${...}		-- missing
994
	 * $...			DONE
995
	 * '...'		DONE
996
	 * ( ... )		DONE
962 997
	 *
963 998
	 *
964 999
	 *
965 1000
	 * ** all DONE **
966 1001
	 * DATE_GMT
967
	 *   The current date in Greenwich Mean Time.
1002
	 *	 The current date in Greenwich Mean Time.
968 1003
	 * DATE_LOCAL
969
	 *   The current date in the local time zone.
1004
	 *	 The current date in the local time zone.
970 1005
	 * DOCUMENT_NAME
971
	 *   The filename (excluding directories) of the document requested by the user.
1006
	 *	 The filename (excluding directories) of the document requested by the user.
972 1007
	 * DOCUMENT_URI
973
	 *   The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
1008
	 *	 The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
974 1009
	 * LAST_MODIFIED
975
	 *   The last modification date of the document requested by the user.
1010
	 *	 The last modification date of the document requested by the user.
976 1011
	 * USER_NAME
977
	 *   Contains the owner of the file which included it.
1012
	 *	 Contains the owner of the file which included it.
978 1013
	 *
979 1014
	 */
980 1015
#ifdef HAVE_PCRE_H
......
1023 1058
	plugin_config *s = p->config_storage[0];
1024 1059

  
1025 1060
	PATCH(ssi_extension);
1061
	PATCH(ssi_max_recursion);
1026 1062

  
1027 1063
	/* skip the first, the global context */
1028 1064
	for (i = 1; i < srv->config_context->used; i++) {
......
1039 1075
			if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
1040 1076
				PATCH(ssi_extension);
1041 1077
			}
1078
			if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.max_recursion"))) {
1079
				PATCH(ssi_max_recursion);
1080
			}
1042 1081
		}
1043 1082
	}
1044 1083

  
......
1052 1091

  
1053 1092
	if (con->physical.path->used == 0) return HANDLER_GO_ON;
1054 1093

  
1094
	con->loops_per_request++;
1095

  
1055 1096
	mod_ssi_patch_connection(srv, con, p);
1056 1097

  
1057 1098
	for (k = 0; k < p->conf.ssi_extension->used; k++) {
......
1078 1119
/* this function is called at dlopen() time and inits the callbacks */
1079 1120

  
1080 1121
int mod_ssi_plugin_init(plugin *p) {
1081
	p->version     = LIGHTTPD_VERSION_ID;
1082
	p->name        = buffer_init_string("ssi");
1083

  
1084
	p->init        = mod_ssi_init;
1122
	p->version	   = LIGHTTPD_VERSION_ID;
1123
	p->name		   = buffer_init_string("ssi");
1124

  
1125
	p->init		   = mod_ssi_init;
1085 1126
	p->handle_subrequest_start = mod_ssi_physical_path;
1086 1127
	p->set_defaults  = mod_ssi_set_defaults;
1087
	p->cleanup     = mod_ssi_free;
1088

  
1089
	p->data        = NULL;
1128
	p->cleanup	   = mod_ssi_free;
1129

  
1130
	p->data		   = NULL;
1090 1131

  
1091 1132
	return 0;
1092 1133
}
src/mod_ssi.h Fri May 11 10:03:02 2007 -0700 → src/mod_ssi.h Fri May 11 12:09:49 2007 -0700
15 15

  
16 16
typedef struct {
17 17
	array *ssi_extension;
18
	unsigned short ssi_max_recursion;
18 19
} plugin_config;
19 20

  
20 21
typedef struct {