浏览器在发送Get请求时,会把请求字符串进行转义操作(英文术语为: escape); 比如,我们在地址栏输入(注意最后”it’s me”中的空格):
浏览器会把它转义为:
在上一篇最后给出的例子中,如果在文本框内输入
你会发现,浏览器最终发送的请求为
通过CGIC,我们可以把这些被转义后的字符还原为我们本来的输入,这个过程就叫“反转义” (Unescape)。
不过这个过程有点像hack他的代码。
整个过程分三个步骤:
1)打开cgic.c,找到这一行语句:
注意,我们要找的只是这个函数声明,不是函数定义;
2)在这个函数声明语句的上方,你会看到一个结构体定义:
- typedef enum {
- cgiUnescapeSuccess,
- cgiUnescapeMemory
- } cgiUnescapeResultType;
把这几行语句复制到cgic.h文件中,并在这里把它注释掉;
同时还要删除在第一步中找到的函数声明语句中的“static”关键字。
3)我们现在就可以使用反转义函数cgiUnescapeChars了:
在你自己的代码(按照惯例,还是test.c)中,加入以下声明语句即可
接下来我们给出一段完整的test.c代码
- #include <stdio.h>
- #include "cgic.h"
- #include <string.h>
- #include <stdlib.h>
- extern char *cgiQueryString;
- extern cgiUnescapeResultType cgiUnescapeChars(char **sp, char *cp, int len);
- int cgiMain() {
- char * buffer;
- cgiHeaderContentType("text/html");
- fprintf(cgiOut, "<HTML><HEAD>\n");
- fprintf(cgiOut, "<TITLE>My CGI</TITLE></HEAD>\n");
- fprintf(cgiOut, "<BODY>");
- cgiUnescapeChars(&buffer, cgiQueryString, strlen(cgiQueryString));
- fprintf(cgiOut, "<H1>%s</H1>",buffer);
- fprintf(cgiOut, "</BODY>\n");
- fprintf(cgiOut, "</HTML>\n");
- free(buffer);
- return 0;
- }
值得注意的是,buffer的存储空间是cgiUnescapeChars帮你分配的,但最后要由你自己来释放(free),这一点千万不可忘记。
下面你可以结合上一篇给出的测试用html代码试试该cgi程序的运行结果,也可以直接在浏览器地址栏输入一些带有特殊符号的字符串。
最后讲一下为什么不得不用这种hacker的方式来完成该任务,而CGIC不显式提供?
CGIC的出发点是,我们平时只需要解析请求中的键 值对,比如:”?q=nice&client=IE”,当我们在服务端查询“q”的值时,我们就能得到“nice”。CGIC有一族函数帮助我们 完成这个任务,比如cgiFormString(以后会讲到)。在解析这种请求格式的时候,如果我们提供的参数值含有被转义的字符,那么CGIC就会在内 部调用cgiUnescapeChars完成反转义。
但是,有时候我们会发送非常复杂的Get请求字符串,但并不是“键-值”对的格式。这就需要直接使用cgiUnescapeChars进行反转义了。
例如:假设我们有个服务端cgi程序chat.cgi,这是个网络聊天机器人(也许你可以开发自己的Web版MSN机器人、QQ机器人)。如果我们发送如下请求:
那么chat.cgi就会把“this is a cgi user”当做你对它说的话,经过处理,它会回复一段语句。为了方便,我们并没有写成“键-值”对的形式。这个时候被我们hack的cgiUnescapeChars就能派上用场了。