梁兄的Java博客

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            2 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks
                   開發過web應用的人,應該都知道http重定向這個功能,html就有最簡單的方法:
          <meta http-equiv="refresh" content="5;url=http://www.cppblog.com/cool-liangbing/">,
          也就是告訴你的瀏覽器5秒之后自動跳轉到我的c++博客首頁http://www.cppblog.com/cool-liangbing/
                    重定向常常用于自動跳轉,從活動空間來看大概分兩類:服務器內部跳轉和服務器之間跳轉。
          服務器內部跳轉常見于“登陸成功!5秒之后將自動進入首頁”這種應用。而服務器之間跳轉,種類稍微
          多一些:(1)從服務器內跳往外部服務器; (2)從A服務器跳轉到B服務器,接著跳轉到C服務器;
          (3) 從A服務器跳轉到B服務器, 業務處理完畢之后又跳轉到A服務器; (4) 從用戶瀏覽器向A服務器
          發送請求,在出口網關處進行重定向,如通過iptable之類,重定向到一個認證服務器B,返回一個
          認證登陸的頁面,當用戶輸入了正確的用戶名和密碼等,認證服務器B再通過http重定向到A服務器.
                    以上所說的4種模式,前3種不值一提,而第4種則有些問題,不是那么容易跳轉成功的。
          不管你的認證服務器B是用現在的tomcat還是resin,或者其它流行的web服務器,最后發現總是
          不能從認證服務器B跳到A服務器. 剛開始懷疑html那種方法不行,就改用javascript寫法,改用jsp調用
          方法,甚至直接在servlet里調用重定向接口,一一試遍,都失敗了,這才懷疑可能不是程序寫法上
          的問題。
                    在萬般無奈情況下,使用CommView工具來抓包看看,從tcp包本身、http request和http response
          包內容來看,看不出什么不對。但發現整個跳轉只在一個tcp連接上進行,這使我想到iptable把向A服務器
          的請求偷偷轉發到認證服務器B, 而瀏覽器還認為認證服務器B就是A服務器, 所以只要這條tcp連接不斷,
          瀏覽器就一直認為這種映射關系正確,所以你怎么也跳轉不到真正的目的地-A服務器.
                    但是我們用老版本httpd或thttpd做web服務器,則可以正常跳轉,何故?http協議版本差別:
          老版本httpd或thttpd采用http1.0協議,而tomcat和resin這些jsp容器最新版本,大都已經實現了http1.1
          協議了,對我們這個問題就是connection是采用非持久的還是持久模式,提取兩個版本協議說明:
                (1) http1.0: 
               原文:Except for experimental applications, current practice requires that
                the connection be established by the client prior to each request and
                closed by the server after sending the response. 
               翻譯:實驗室應用除外,當前的做法是客戶端在每次請求之前建立連接,而服務器端在發送回應后關閉此連接。
                (2) http1.1:
               原文:In HTTP/1.0, most implementations used a new connection for each request/response exchange. 
              In HTTP/1.1, a connection may be used for one or more request/response exchanges, 
              although connections may be closed for a variety of reasons (see section 8.1). 
               翻譯:在HTTP/1.0協議下,大多數HTTP服務器實現對每一個請求/應答使用一個新連接. 而在HTTP/1.1協議下,一個或多個請求/應答使用同一個連接。
               (section 8.1詳細說明了為什么這么做)
                 從協議上分析清楚之后,我們怎么解決上面那個現實問題?肯定不能使用http1.1這種持久性連接。
          查了下tomcat docment說明,默認實現了http1.1,現在版本的connector已經早不提供http1.0支持了,
          難道我們要退回到http1.0的版本?那是多么痛苦的事情。再查查tomcat/conf/server.xml里關于connector
          的配置,有一個參數connecttimeout,默認是20000ms, 作為服務器不可能爭對socket accept()的,應該是
          socket recv()的超時,那么我們設置它為比我們<meta http-equiv="refresh" content="5;url=xxx">里
          秒數小就可以了,保證在跳轉之前以前的tcp連接被tomcat服務器斷開就可以了,當然iptable應該在認證成功
          之后不再對這個上網用戶發出的http請求重定向到認證服務器, 這個很容易做到,暫不提細節。
                 最后附上UML圖以方便理解:
                
          posted on 2008-08-26 00:05 梁兄 閱讀(5414) 評論(1)  編輯  收藏 所屬分類: Java網絡通訊

          Feedback

          # re: http重定向問題 2008-08-26 08:45 po
          好復雜,沒看懂~  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 湖南省| 那坡县| 南岸区| 福海县| 冕宁县| 边坝县| 民县| 安吉县| 龙山县| 虎林市| 县级市| 扎兰屯市| 三都| 浮山县| 霞浦县| 浦城县| 双峰县| 富源县| 万源市| 攀枝花市| 盐边县| 商城县| 浦东新区| 崇文区| 石阡县| 宁乡县| 宁国市| 吉木乃县| 富民县| 淮安市| 咸阳市| 诸城市| 延安市| 武宁县| 乡城县| 海城市| 隆回县| 普洱| 长子县| 龙山县| 工布江达县|