java代理服务器smart cache源码阅读小结

原创文章,转载请注明出处:http://passerbyy.iteye.com/blog/1307446   作者:passer_by

最近看了看java开发的代理服务器smart cache的源码,作者还是面向过程的思想设计的代码,整个看下来花了不少力气,现在做个小结,也算没有白看。

一、smart cache简介
它是一款java编写的代理服务器,支持http 0.9 1.0 1.1,https协议。并且支持设置url的黑名单,还可以对请求或者响应的大小进行限制,对GET请求进行了缓存,还有其他的一些功能。具体可以参看:http://proxies.xhaus.com/java/smart_cache.html

代码可以在http://scache.sourceforge.net/下载。

二. 只对get请求做了缓存,对put、connect(https)、trace等请求没有做。
这其中最主要的原因是put请求保存参数的复杂性,后续读取缓存较为麻烦;而connect请求最主要的问题如果解析加密结果给新的客户端,这个地方我也一直不知道该怎么弄;其他请求没有深究原因。

三. 超复杂的配置。
光配置文件就有n多个,我太惊讶怎么代理还有那么多地方可以配置呢?这对我阅读代码也增加一点困难。配置文件的读取是在scache启动的时候。

四. 代码结构:

首先:socket监听,server = new ServerSocket(port, listenbacklog, adr); clientSocket = server.accept();

如果有请求进来,新建httpreq线程处理用户请求:
1. 用户请求处理。 先读取第一行:判断请求协议,类型,请求地址,协议版本;读取请求头,这里还是做了挺多处理,特别是对keep-alive、expire做了一些处理。最后得到的一个request对象。
2. 根据不同的请求类型(GET、POST、CONNECT...)选择不同的处理方式 :具体见manager.process_request(request);

(1)post请求 :继续把请求的参数传给服务器,然后读取响应结果返还给客户端。这里需要主要注意响应头中transfer-encoding为chunked的数据处理和非chunked的数据处理方式不一样,GET请求中也是这样。具体参看:request.direct_request(boolean)方法;

(2)connect请求 :起两个线程,一个线程从客户端不断传参数给服务器,另一个线程从服务器端读取参数给客户端,直到有一方没有数据为止。具体参看:request.handle_connect(boolean)方法。

(3)GET请求 :看是否存在缓存文件,是否需要更新缓存文件,是否直接读取缓存文件。具体见cacheobject.make_request方法

i、获取cachedir和cacheobject对象
cachedir指的是缓存的目录(目录结构是把host用crc32算法做个hash,得到2级目录;接下来是host/context-path),cacheobject表示该目录下的文件。

ii. 判断是否有缓存文件
每个cachedir目录下的所有请求信息都记录在.cacheinfo中,包括地址,信息头等,每个请求根据类型以固定格式存进去,所以读取的时候能够直接判断大小,具体的可以参看cacheobject的save方法:

final public void save(DataOutputStream os) throws IOException
{
if(localname==null) return;

os.writeUTF(name);
os.writeUTF(ctype);
os.writeUTF(localname);
if(location!=null) os.writeUTF(location);
  else
    os.writeUTF("");
os.writeInt(size);
os.writeInt(httprc);
os.writeLong(expires);
os.writeLong(date);
os.writeLong(lastmod);
os.writeLong(lru);
// v4
if(etag!=null) os.writeUTF(etag); else os.writeUTF("");
// v3
if(encoding!=null) os.writeUTF(encoding); else os.writeUTF("");
os.writeBoolean(good);
}。.cacheinfo是由mgr线程定时去做更新处理,所以当前请求处理结束后不会立刻更新到.cacheinfo中。

if(localname==null) return;

os.writeUTF(name);
os.writeUTF(ctype);
os.writeUTF(localname);
if(location!=null) os.writeUTF(location);
  else
    os.writeUTF("");
os.writeInt(size);
os.writeInt(httprc);
os.writeLong(expires);
os.writeLong(date);
os.writeLong(lastmod);
os.writeLong(lru);
// v4
if(etag!=null) os.writeUTF(etag); else os.writeUTF("");
// v3
if(encoding!=null) os.writeUTF(encoding); else os.writeUTF("");
os.writeBoolean(good);



备注:.cacheinfo是由mgr线程定时去做更新处理,所以当前请求处理结束后不会立刻更新到.cacheinfo中。

iii. 如果缓存不存在,则重新去请求,再缓存结果。

参考cacheobject的load_object方法。注意保存文件的时候,作者也考虑到了content-type,如果需要压缩的话后缀加上.gz,如果是跳转的则加上_r。这个小细节处理的还不错。

iv. 如果缓存存在,则判断是否需要刷新,如果需要刷新的话,调用cacheobject的refresh_object方法

v.如果缓存存在,且不需要刷新,则调用cacheobject的send_fromcache方法。

这里就不用考虑是否为chunked的了。因为处理响应请求的时候已经解析过响应结果了。


五、提供目录重建(repaire)、删除cache文件(GC)功能。这里没有看。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值