lalla1 发表于 2015-11-19 11:55:28

怎样让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]
查看完整版本: 怎样让squid follow 302的响应