<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0
    基于抽象和聚合原則,Jetty中需要一個單獨的類來專門處理HTTP響應消息和請求消息的生成和發送,Jetty的作者將該抽象(接口)命名為Generator,它有兩個實現類:HttpGenerator和NestedGenerator。其類圖如下:

    Generator接口

    HTTP請求消息分為請求行、消息報頭、請求正文三部分,HTTP響應消息分為狀態行、消息報頭、消息正文。在HTTP請求消息和響應消息格式的唯一區別是請求行和狀態行,因而只需要將這一行的內容區分開來,其他的可以共享邏輯。

    請求行和響應行設置
    請求行包括請求方法、URI、HTTP協議版本,響應行包括HTTP協議版本、狀態碼、狀態短語,因而在Generator接口中定義了各自的設置方法:

        // 設置_method、_uri字段,如果當前_version是HTTP/0.9,則_noContent置為true
        void setRequest(String method, String uri);
        // 設置_status、_reason字段,對_reason字段,將所有'\r', '\n'替換成空格(' ')。清除_method字段。如果Generator已經開始生成效應消息,則不可再調用該方法。
        void setResponse(int status, String reason);
        // 設置HTTP協議版本,這里的值9表示HTTP/0.9, 10表示HTTP/1.0,11表示HTTP/1.1。對HTTP/0.9的請求消息,不能包含請求內容。如果Generator已經開始生成效應消息,則不可再調用該方法。
        void setVersion(int version);

    HTTP消息報頭設置
    在Generator中,通過completeHeader中的HttpFields參數傳入HTTP消息報頭,而其中的allContentAdded參數用于檢查并設置_last字段狀態。
    //通過傳入的HttpFields參數設置HTTP消息報頭,allContentAdded參數用于檢查并設置_last字段狀態。
    public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
    void setDate(Buffer timeStampBuffer);
    void setSendServerVersion(boolean sendServerVersion);
    void setContentLength(long length);
    void setPersistent(boolean persistent);
    在該方法的實現中:
    1. 向_header緩存中寫入請求行或響應行(對HTTP/0.9的特殊處理不詳述)。對HTTP響應消息,如果狀態碼是[100-200)、204、304,這些響應消息不能有響應消息體。對狀態碼是100的響應消息還不能有其他消息頭。
    2. 如果設置了_date值(狀態碼在200及以上,這里貌似木有考慮請求消息),在消息頭中包含"Date"消息頭。
    3. 對fields參數中的所有消息頭,依次寫入到_header緩存中(消息頭名移除'\r', '\n', ':'字符,消息頭值移除'\r', '\n'字符)。對"Content-Length"頭,記錄_contentLength字段;對"Content-Type"為"multipart/byteranges"頭,設置_contentLength為SLEF_DEFINING_CONTENT;對"Transfer-Encoding"頭,并且_contentLength的值為CHUNKED_CONTENT,則添加"Transfer-Encoding: chunked\r\n"頭(或用戶自定義的以"chunked"開頭的值);對"Server"頭,且設置了"sendServerVersion"字段,則添加"Server"頭;對"Connection"頭,在請求消息中直接設置該頭,同時更新"keep_alive"的值("close"->keep_alive=false, "keep-alive"->keep_alive=true),在響應消息中,更新"keep_alive"和"_persistent"的值,對"upgrade"值,直接添加,而對其他值,根據"keep_alive"和"_persistent"的值以及HTTP版本號添加"close"或"keep-alive"的值,以及用戶自定義的值;根據當前_contentLength值設置"Content-Length"頭;最后添加"\r\n"到_header緩存表示消息頭結束。
    4. 將_state狀態從STATE_HEADER更新到STATE_CONTENT。

    HTTP消息體設置
    Generator中有兩個方法用于向其添加HTTP消息體:
    void addContent(Buffer content, boolean last) throws IOException;
    boolean addContent(byte b) throws IOException;
    這兩個方法的實現:
    1. 如果當前已存在未刷新的_content內容或者_contentLength為CHUNKED_CONTENT,則先刷新緩存。
    2. 更新_content字段和_contentWritten字段。
    3. 將_content的值寫入_buffer字段中。
    在刷新緩存時:
    1. 準備Buffer:將_content值寫入_buffer中,并清除_content引用;如果_contentLength為CHUNKED_CONTENT,設置_bufferChunk為true,并且對chunked內容,先寫入16進制的size,緊跟"\r\n",然后是正真的內容;對最后一個chunk,添加"\r\n\r\n"。
    2. 然后根據_header, _buffer, _content狀態,將它們中的內容寫入到Endpoint中。
    3. 如果當前狀態是STATE_FLUSHING,則將_state狀態置為STATE_END。

    HTTP消息完成生成
    Generator調用complete方法表示生成已經完成:
    public void complete() throws IOException
    在該方法中,它將_state狀態設置為STATE_FLUSHING,并刷新緩存。

    Generator中的其他方法
    在Generator/HttpGenerator中還有一些發送響應消息的方法:
    void sendError(int code, String reason, String content, boolean close) throws IOException;
    public void send1xx(int code) throws IOException
    public void sendResponse(Buffer response) throws IOException
    其中sendError是Generator接口中的方法,它是一個工具方法用于一次將一個HTTP響應消息寫入到Endpoint中:
        public void sendError(int code, String reason, String content, boolean close) throws IOException {
            if (close)
                _persistent=false;
            if (!isCommitted()) {
                setResponse(code, reason);
                if (content != null)  {
                    completeHeader(nullfalse);
                    addContent(new View(new ByteArrayBuffer(content)), Generator.LAST);
                } else {
                    completeHeader(nulltrue);
                }
                complete();
            }
        }
    sendResponse方法是HttpGenerator中的方法,它將response參數直接作為響應消息體,并設置_state為STATE_FLUSHING,是一個工具方法。
    send1xx方法是HttpGenerator中的方法,它將1xx的響應消息直接寫入到Endpoint中。
    posted on 2014-04-20 15:58 DLevin 閱讀(1282) 評論(2)  編輯  收藏 所屬分類: Jetty

    FeedBack:
    # re: 深入Jetty源碼之HttpGenerator
    2014-04-21 10:51 | 種植技術網
    看來博主英文水平不錯的  回復  更多評論
      
    # re: 深入Jetty源碼之HttpGenerator
    2014-04-21 10:52 | 無添加
    技術博客含金量高  回復  更多評論
      
    主站蜘蛛池模板: 午夜爱爱免费视频| 日本高清免费中文在线看| 国产亚洲精品免费视频播放| 麻豆最新国产剧情AV原创免费| 99麻豆久久久国产精品免费| 亚洲GV天堂无码男同在线观看| 亚洲日韩中文字幕| 亚洲AV无码乱码在线观看富二代| 亚洲?V无码成人精品区日韩| 我想看一级毛片免费的| 久久久久久夜精品精品免费啦| eeuss影院免费92242部| 色网站在线免费观看| 亚洲欧美日韩久久精品| 精品国产成人亚洲午夜福利| 亚洲毛片一级带毛片基地| 亚洲第一区香蕉_国产a| 久久精品国产精品亚洲精品| 亚洲综合色区在线观看| 亚洲午夜福利精品久久 | 亚洲粉嫩美白在线| 亚洲精品第五页中文字幕| 亚洲av无码潮喷在线观看| 亚洲精品无码AV人在线播放| 亚洲日韩在线观看免费视频| www.亚洲一区| 久久久久亚洲AV成人网| 久久亚洲高清综合| 亚洲色精品aⅴ一区区三区| 亚洲日韩国产精品第一页一区| 亚洲日韩精品射精日| 亚洲国产精品久久久天堂| 亚洲an天堂an在线观看| 中文字幕亚洲精品| 亚洲美女aⅴ久久久91| 亚洲国产美女在线观看| 亚洲人成77777在线播放网站不卡| 亚洲精品亚洲人成在线播放| 亚洲中文字幕AV每天更新| 亚洲AV无码一区二区三区性色| 亚洲va中文字幕|