当前版本在访问目录时,如果目录中包含index.html文件,那么会将该文件的内容作为结果返回。如果index.html文件不存在,则会返回403状态码。之前的版本只有访问网站根目录时,才会尝试访问index.html...

项目下载地址:

    zenglServer源代码的相关地址:https://github.com/zenglong/zenglServer  当前版本对应的tag标签为:v0.13.0

zenglServer v0.13.0:

    当前版本在访问目录时,如果目录中包含index.html文件,那么会将该文件的内容作为结果返回。如果index.html文件不存在,则会返回403状态码。之前的版本只有访问网站根目录时,才会尝试访问index.html,当前版本则在访问网站根目录和任意子目录时,都会尝试访问index.html文件。这个改动所涉及的C代码主要位于main.c文件里:

static int routine_process_client_socket(CLIENT_SOCKET_LIST * socket_list, int lst_idx)
{
	.........................................................
	// status_code存储响应状态码,默认为200
	int status_code = 200;
	ZL_EXP_BOOL is_custom_status_code = ZL_EXP_FALSE; // 是否是自定义的请求头
	int content_length = 0;
	struct stat filestatus;
	// 下面会根据webroot根目录,和url_path来构建full_path完整路径
	int full_length = main_full_path_append(full_path, 0, FULL_PATH_SIZE, webroot);
	int root_length = full_length;
	full_length += main_full_path_append(full_path, full_length, FULL_PATH_SIZE, url_path);
	full_path[full_length] = '\0';
	stat(full_path, &filestatus);
	// 如果是访问目录,则将该目录中的index.html文件里的内容,作为结果反馈给客户端
	if(S_ISDIR(filestatus.st_mode)) {
		if(full_path[full_length - 1] == '/')
			full_length += main_full_path_append(full_path, full_length, FULL_PATH_SIZE, "index.html");
		else
			full_length += main_full_path_append(full_path, full_length, FULL_PATH_SIZE, "/index.html");
		full_path[full_length] = '\0';
		write_to_server_log_pipe(WRITE_TO_PIPE, "full_path: %s\n", full_path);
		// 以只读方式打开文件
		doc_fd = open(full_path, O_RDONLY);
		if(doc_fd > 0) {
			stat(full_path, &filestatus);
		}
	}
	else {
		write_to_server_log_pipe(WRITE_TO_PIPE, "full_path: %s\n", full_path);
		// 如果要访问的文件是以.zl结尾的,就将该文件当做zengl脚本来进行编译执行
		if(full_length > 3 && S_ISREG(filestatus.st_mode) && (strncmp(full_path + (full_length - 3), ".zl", 3) == 0)) {
			........................................................
		}
		....................................................
	}
	.........................................................
}


    为了测试,在my_webroot目录的v0_13_0子目录中增加了一个index.html文件,通过客户端访问v0_13_0目录,默认会将index.html文件的内容返回,测试结果如下:



图1:访问目录,默认会访问index.html

    此外,当前版本在解析mustache模板文件时,如果模板路径以斜杠开头,则模板路径会相对于网站根目录。之前的版本,模板路径只能相对于当前主执行脚本所在的目录,当前版本通过斜杠开头的模板路径就可以通过同一个模板路径来定位到同一个模板文件,而不用关心主执行脚本所在的目录。相关的C代码位于module_builtin.c文件里:

/**
 * 根据filename构建完整的模板路径,如果filename是以斜杠开头,就表示相对于webroot网站根目录的路径,否则就是相对于当前主执行脚本的路径
 */
static void builtin_template_get_fullpath(char * full_path, char * filename, MAIN_DATA * my_data)
{
	if(filename[0] == '/') {
		char * webroot = main_get_webroot();
		int append_length = 0;
		append_length += main_full_path_append(full_path, append_length, FULL_PATH_SIZE, webroot);
		append_length += main_full_path_append(full_path, append_length, FULL_PATH_SIZE, filename);
		full_path[append_length] = '\0';
	}
	else
		builtin_make_fullpath(full_path, filename, my_data);
}

...........................................................

/**
 * 解析partial模板语法时,会调用的回调函数
 * 例如:
 * {{> header.tpl}}
 * 在渲染时,就会调用下面这个回调函数,将header.tpl子模板的内容读取并解析出来
 */
static int builtin_crustache__partial(ZL_EXP_VOID * VM_ARG, crustache_template **partial, char * partial_name, size_t name_size)
{
	char full_path[FULL_PATH_SIZE];
	if(name_size == 0)
		return -1;
	char tmp = partial_name[name_size];
	char * api_name = "bltMustacheFileRender";
	int file_size;
	partial_name[name_size] = '\0';
	MAIN_DATA * my_data = zenglApi_GetExtraData(VM_ARG, "my_data");
	builtin_template_get_fullpath(full_path, partial_name, my_data);
	partial_name[name_size] = tmp;
	char * file_contents = builtin_get_file_content(VM_ARG, full_path, api_name, &file_size);
	(*partial) = builtin_crustache_new_template(VM_ARG, file_contents, api_name, file_size, full_path);
	zenglApi_FreeMem(VM_ARG, file_contents);
	return 0;
}

...........................................................

/**
 * bltMustacheFileRender模块函数,渲染mustache模板
 * filename参数表示模板文件名(可以是相对于当前执行脚本的相对路径),可选的array参数表示需要在模板中渲染的数据(一个哈希数组)
 * .........................................................
 */
ZL_EXP_VOID module_builtin_mustache_file_render(ZL_EXP_VOID * VM_ARG,ZL_EXP_INT argcount)
{
	ZENGL_EXPORT_MOD_FUN_ARG arg = {ZL_EXP_FAT_NONE,{0}};
	if(argcount < 1)
		zenglApi_Exit(VM_ARG,"usage: bltMustacheFileRender(filename[, array])");
	zenglApi_GetFunArg(VM_ARG,1,&arg); //得到第一个参数
	if(arg.type != ZL_EXP_FAT_STR)
		zenglApi_Exit(VM_ARG,"first argument filename of bltMustacheFileRender must be string");
	char * filename = arg.val.str;
	char full_path[FULL_PATH_SIZE];
	MAIN_DATA * my_data = zenglApi_GetExtraData(VM_ARG, "my_data");
	builtin_template_get_fullpath(full_path, filename, my_data);
	int file_size;
	char * api_name = "bltMustacheFileRender";
	char * file_contents = builtin_get_file_content(VM_ARG, full_path, api_name, &file_size);
	crustache_template *template = builtin_crustache_new_template(VM_ARG, file_contents, api_name, file_size, full_path);
	.........................................................
}


    从代码中可以看到,在使用bltMustacheFileRender模块函数渲染模板时,以及使用partial模板语法解析子模板时,都可以使用斜杠开头的相对于网站根目录的路径来定位模板文件。在my_webroot目录的v0_13_0子目录中增加了test.zl测试脚本,用于测试斜杠开头的模板路径,test.zl的脚本代码如下:

use builtin;

print bltMustacheFileRender("header.tpl");
print bltMustacheFileRender("/v0_13_0/footer.tpl");


    header.tpl和footer.tpl都是v0_13_0目录中的模板文件。该脚本的执行结果如下:



图2:test.zl测试脚本

    以上就是当前版本相关的内容。OK,就到这里,休息,休息一下 o(∩_∩)o~~

结束语:

    知道自己做的是对的事,就要坚持下去,不计较得失,写自己认为值得写的故事。

——  《导火新闻线》
 
上下篇

下一篇: zenglServer v0.14.0 正则表达式模块

上一篇: zenglServer v0.12.0 图形验证码, 新增模块函数

相关文章

zenglServer v0.12.0 图形验证码, 新增模块函数

zenglServer v0.6.0 session会话

zenglServer v0.4.0 daemon守护进程, epoll事件驱动

zenglServer v0.10.0 使用zengl脚本的编译缓存,跳过编译过程

zenglServer v0.7.0-v0.7.1 mustache模板解析

zenglServer v0.10.1 添加bltInt,bltFloat,bltHtmlEscape模块函数,使用v1.8.1版本的zengl语言库