现在的位置: 首页 > 综合 > 正文

web服务器对url中的相对路径的处理(”./”, “//”,”../”)

2013年02月01日 ⁄ 综合 ⁄ 共 2079字 ⁄ 字号 评论关闭

    本次为了方便展示和调试,并没有将代买写入到真实的运行环境,而是单独写了一个test程序,

使用的思路主要是回溯。首先记录本次的开始位置,

情况一:如果本次得到内容时“./”,回溯到本次开始匹配的位置即可。

情况二:如果本次得到的内容是"/",回溯到本次开始匹配的位置即可。

情况三: 如果本次的到的内容时“../",首先回溯到本次开始匹配的位置,并且删除上一级目录

其他情况: 直接写入本次匹配的值。开始下一次匹配。

一下为程序代码,本code只经过本人的简单测试,可能会存在漏洞。希望大家在查看的同时,写出更好的代码。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>


/*对url中的相对路径的符合进行处理。
 * 从url中移除 "/../", "//", "/./" 。
 *
 * /reage/..             真实路径为  /
 * /reage/../reage1      真实路径为  /reage1
 * /reage/./reage1       真实路径为  /reage/reage1
 * /reage//reage1        真实路径为  /reage/reage
 *
 *
*/

int buffer_path_simplify(char *dest, const char *src)
{
	int count;
	char c;
	/*
		start保存结果路径的开始位置。
		slash本次配皮的开始位置,
		walk正在匹配的字符
		out将要写入的结果的位置
	*/
	char *start, *slash, *walk, *out;
	
	char pre; //当前匹配的前一个字符

	if (src == NULL ||  dest == NULL)
		return -1;


	walk  = src;
	start = dest;
	out   = dest;
	slash = dest;



	while (*walk == ' ') {
		walk++;
	}

	pre = *(walk++);
	c    = *(walk++);
	if (pre != '/') {
		*(out++) = '/';
	}
	*(out++) = pre;

	if (pre == '\0') {
		*out = 0;
		return 0;
	}

	while (1) {
		// '/'表示本次匹配的结束,'\0'表示整个过程的结束
		if (c == '/' || c == '\0') {
			//计算本次共匹配到的字符 即使'/'与'/'的距离
			count = out - slash;
			//说明本次匹配为../需要删除前面的目录
			if (count == 3 && pre == '.') {
					
				//首先回到本次匹配的开始,即使../的一个点的位置,
				out = slash;
				//回溯到前面的一个目录,只要前面不是根目录
				if (out > start) {
					out--;
					while (out > start && *out != '/') {
						out--;
					}
				}

				if (c == '\0')
					out++;
			} else if (count == 1 || pre == '.') {
				//本次匹配为“./”只要删除掉就可。即使回到本次开始匹配的位置
				out = slash;
				if (c == '\0')
					out++;
			}

			slash = out;
		}

		if (c == '\0')
			break;
		//先将内容写入,本保存上一个的内容
		pre = c;
		c    = *walk;
		*out = pre;

		out++;
		walk++;
	}

	*out = '\0';

	return 0;
}


int main(){
	char dest[1024];
	char path[1024] = "../reage/../reage//aa.c";
	
	buffer_path_simplify(dest, path);
	printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
	
	
	strcpy(path, "/../reage/../../../././reage//aa.c");	
	buffer_path_simplify(dest, path);
	printf("URL=\"%s\" == path=\"%s\"\n", path, dest);

	strcpy(path, "/reage/../");	
	buffer_path_simplify(dest, path);
	printf("URL=\"%s\" == path=\"%s\"\n", path, dest);

	strcpy(path, "/reage/../reage1");	
	buffer_path_simplify(dest, path);
	printf("URL=\"%s\" == path=\"%s\"\n", path, dest);

	strcpy(path, "/reage/./");	
	buffer_path_simplify(dest, path);
	printf("URL=\"%s\" == path=\"%s\"\n", path, dest);

	strcpy(path, "/reage//reage");	
	buffer_path_simplify(dest, path);
	printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
}	

blog:http://blog.csdn.net/rentiansheng/article/details/8922368

抱歉!评论已关闭.