前面的就不说了。就说写cache部分遇到的问题。
思路就是把从服务器端获得的状态码是202的响应报文缓存下来,当客户端再次申请相同的url时,加一行问问服务器有没有modified过,如果没有直接把缓存的文件发给客户端。
到这里,思路是很清晰的,可是在实现上有一个坑。
参考了以下前辈们写的代码
以下是代理服务器获得服务器发来的报文时,直接写入到文件中
FILE *out;
out = fopen(filename, "w");
fwrite(buffer, sizeof(char), strlen(buffer), out);
//buffer就是从服务器那里获得的状态码200的报文
fclose(out);
printf("\n=====================================\n\n");
printf("\n网页已经被缓存\n");
这里是代理服务器从文件中读取出来缓存的文件,如果服务器发来304的状态码(没有modified过),那么直接把这个缓存内容发给客户端就行了
FILE *in = NULL;
if ((in = fopen(filename, "r")) != NULL) {
fread(buffer, sizeof(char), MAXSIZE, in);
fclose(in);
}
乍一看这个代码很好啊,没有问题。其实当你真正跑起来的时候会发现,如果没有modified过,你用上面的代码从文件中读进来之前缓存好的内容,发给客户端,浏览器上什么都显示不出来。换句话说上面的代码其实并没有真正把服务器要发给客户的报文缓存下来。
这个问题是这样,在报文中其实夹杂了一些\0的字符。如果你直接用上面的代码写入到文件,那么根据c语言的机制,他只把\0之前的内容写入文件,认为字符串到了\0就结束了(其实后面还有呢)
上图是我跟踪的一个报文信息,你会发现他在第535到第540行都是\0,但是541行之后还是有报文信息的。如果你直接把这个报文用上面的代码写入文件,那么实质上他只能写道第534行,后面都丢了,之后再读出来发给客户浏览器自然就出错了。
解决方案:首先你要对于报文的字符串从最后一个位置往前扫描,扫描到第一个不是\0的位置i,这才是字符串的真正结尾。
然后用fputc()函数一个字符一个字符的写入,这个函数是可以把\0写进文件去的。然后就没有问题啦~