怎样让squid follow 302的响应
http://blog.iyunv.com/uid-8474831-id-3463461.html大家都知道,http的302响应,是一种跳转。比如用户访问url:
http://www.sina.com/ 时,
点击(此处)折叠或打开
[*]GET / HTTP/1.1
[*]User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
[*]Host: www.sina.com
[*]Accept: */*
sina的服务器会返回一个301的响应(302也类似),让你的浏览器去访问 http://www.sina.com.cn/
点击(此处)折叠或打开
[*]HTTP/1.0 301 Moved Permanently
[*]Date: Sun, 06 Jan 2013 10:16:17 GMT
[*]Server: Apache
[*]Location: http://www.sina.com.cn/
[*]Cache-Control: max-age=3600
[*]Expires: Sun, 06 Jan 2013 11:16:17 GMT
[*]Vary: Accept-Encoding
[*]Content-Length: 231
[*]Content-Type: text/html; charset=iso-8859-1
[*]Age: 3015
[*]X-Cache: HIT from sh201-12.sina.com.cn
[*]Connection: close
squid在处理301或302的响应时,只能把这个30x响应给到客户端,然后由客户端发起对http://www.sina.com.cn/ 的请求。
那么,能不能让squid在客户端请求http://www.sina.com/ 的时候,直接返回http://www.sina.com.cn/ 的200内容呢?
其实非常简单,只要几十行代码就搞定!
接下来我就手把手教给你怎么做
首先,在client_side.c里面,加上这个函数clientProcess302Header
点击(此处)折叠或打开
[*]//add by xiaosi start
[*]
[*]static void clientProcess302Header(void *data, HttpReply * rep)
[*]
[*]{
[*]
[*] clientHttpRequest *http = data;
[*]
[*] HttpHeaderEntry *location_entry = httpHeaderFindEntry(&rep->header, HDR_LOCATION);
[*]
[*] if(!location_entry)
[*]
[*] {
[*]
[*] http->orig_header_callback(data, rep);
[*]
[*] return;
[*]
[*] }
[*]
[*]
[*]
[*] char *location = xstrdup(strBuf(location_entry->value));
[*]
[*] http->location = location;
[*]
[*] http->out.offset = 0;
[*]
[*] http->out.size = 0;
[*]
[*] StoreEntry *e;
[*]
[*] if ((e = http->entry))
[*]
[*] {
[*]
[*] http->entry = NULL;
[*]
[*] storeClientUnregister (http->sc, e, http);
[*]
[*] http->sc = NULL;
[*]
[*] storeUnlockObject (e);
[*]
[*] }
[*]
[*] /* old_entry might still be set if we didn'tyet get the reply
[*]
[*] * code in clientHandleIMSReply() */
[*]
[*] if ((e = http->old_entry))
[*]
[*] {
[*]
[*] http->old_entry = NULL;
[*]
[*] storeClientUnregister (http->old_sc, e, http);
[*]
[*] http->old_sc = NULL;
[*]
[*] storeUnlockObject (e);
[*]
[*] }
[*]
[*] clientRedirectStart(http);
[*]
[*]}
[*]
[*]//add by xiaosi end
然后修改storeClientCopyHeaders,改成下面的样子。注意add by xiaosi注释里面的代码
点击(此处)折叠或打开
[*]void
[*]
[*]storeClientCopyHeaders(store_client * sc, StoreEntry * e, STHCB * callback, void *callback_data)
[*]
[*]{
[*]
[*] clientHttpRequest *http = callback_data;
[*]
[*]//add by xiaosi start
[*]
[*]// http->header_callback = callback;
[*]
[*] http->header_callback = clientProcess302Header;
[*]
[*] http->orig_header_callback = callback;
[*]
[*]//add by xiaosi end
[*]
[*] http->header_entry = e;
[*]
[*] storeClientCopy(http->sc, e, 0, 0, STORE_CLIENT_BUF_SZ, memAllocate(MEM_STORE_CLIENT_BUF), storeClientCopyHeadersCB, http);
[*]
[*]}
然后修改client_side_rewrite.c里面的clientRedirectStart,注意add by xiaosi注释里面的代码
点击(此处)折叠或打开
[*]void
[*]
[*]clientRedirectStart(clientHttpRequest * http)
[*]
[*]{
[*]
[*] debug(33, 5) ("clientRedirectStart: '%s'\n", http->uri);
[*]
[*] //add by xiaosi start
[*]
[*] if(http->location)
[*]
[*] {
[*]
[*] http->redirect_state = REDIRECT_PENDING;
[*]
[*] char *location = xstrdup(http->location);
[*]
[*] safe_free(http->location);
[*]
[*] clientRedirectDone (http, location);
[*]
[*] safe_free(location);
[*]
[*] return;
[*]
[*] }
[*]
[*] //add by xiaosi end
[*]
[*] if (Config.Program.url_rewrite.command == NULL) {
[*]
[*] clientRedirectDone(http, NULL);
[*]
[*] return;
[*]
[*] }
[*]
[*] if (Config.accessList.url_rewrite) {
[*]
[*] http->acl_checklist = clientAclChecklistCreate(Config.accessList.url_rewrite, http);
[*]
[*] aclNBCheck(http->acl_checklist, clientRedirectAccessCheckDone, http);
[*]
[*] } else {
[*]
[*] redirectStart(http, clientRedirectDone, http);
[*]
[*] }
[*]
[*]}
注意,我们在clientHttpRequest中加入了2个成员,location和orig_header_callback。在structs.h的struct _clientHttpRequest 结构的末尾加上他们。注意add by xiaosi注释里面的代码
点击(此处)折叠或打开
[*]struct _clientHttpRequest {
[*]
[*]// bla bla bla…
[*]
[*]// bla bla bla…
[*]
[*]// bla bla bla…
[*]
[*]
[*]
[*] dlink_node active;
[*]
[*] squid_off_t maxBodySize;
[*]
[*] STHCB *header_callback; /* Temporarily here for storeClientCopyHeaders */
[*]
[*] StoreEntry *header_entry; /* Temporarily here for storeClientCopyHeaders */
[*]
[*] int is_modified;
[*]
[*] //add by xiaosi start
[*]
[*] char *location;
[*]
[*] STHCB *orig_header_callback; /* Temporarily here for storeClientCopyHeaders */
[*]
[*]//add by xiaosi end
[*]
[*]};
基本上就完工了。重新编译安装,重启squid。再通过squid请求一下http://www.sina.com/ 是不是看到200了呢?
页:
[1]