我的是個實踐型人員,因此打算看着jetty源碼,從頭開始組裝Jetty。html
首先從github.com裏找到jetty-project項目,用git下載源碼,本文以9.3.x爲例。java
首先Jetty做爲一個web server,必然須要支持HTTP。git
查看Jetty-http項目下http包下一共有下列幾個類:github
接口: HttpContent HttpFieldPreEncoder HttpParser.HttpHandler HttpParser.RequestHandler HttpParser.ResponseHandler HttpTokens 類: DateGenerator DateParser HttpPostHttpField Http1FieldPreEncoder HttpCookie HttpField HttpField.IntValueHttpField HttpField.LongValueHttpField HttpFields HttpGenerator HttpParser HttpStatus HttpURI MetaData MetaData.Request MetaData.Response MimeTypes PathMap PathMap.MappedEntry PathMap.PathSet PreEncodedHttpField ResourceHttpContent 枚舉類: HttpGenerator.Result HttpGenerator.State HttpHeader HttpHeaderValue HttpMethod HttpParser.State HttpScheme HttpStatus.Code HttpTokens.EndOfContent HttpVersion MimeTypes.Type 異常類: BadMessageException
上述類裏,須要關注的有下面幾個基礎類,分別進行解說。web
Http協議由請求消息和響應消息組成,其中請求消息由請求行、首部行(消息報頭)、實體主體組成;而響應消息由狀態行、首部行、實體主體組成。圍繞這些咱們須要研究的類有HttpContent、HttpCookie、HttpField、HttpFields、HttpStatus等。chrome
2.1 接口
app
public interface HttpContent { HttpField getContentType(); String getContentTypeValue(); String getCharacterEncoding(); Type getMimeType(); HttpField getContentEncoding(); String getContentEncodingValue(); HttpField getContentLength(); long getContentLengthValue(); HttpField getLastModified(); String getLastModifiedValue(); HttpField getETag(); String getETagValue(); ByteBuffer getIndirectBuffer(); ByteBuffer getDirectBuffer(); Resource getResource(); InputStream getInputStream() throws IOException; ReadableByteChannel getReadableByteChannel() throws IOException; void release(); HttpContent getGzipContent(); public interface Factory { HttpContent getContent(String path) throws IOException; } }
HttpContent接口定義了一系列實體主體部分的操做。eclipse
而且本接口涉及到HttpField,查看HttpField源碼。ide
public class HttpField { private final static String __zeroquality="q=0"; private final HttpHeader _header; private final String _name; private final String _value; // cached hashcode for case insensitive name private int hash = 0; public HttpField(HttpHeader header, String name, String value) { _header = header; _name = name; _value = value; } public HttpField(HttpHeader header, String value) { this(header,header.asString(),value); } public HttpField(HttpHeader header, HttpHeaderValue value) { this(header,header.asString(),value.asString()); } public HttpField(String name, String value) { this(HttpHeader.CACHE.get(name),name,value); } //header、name的getter方法,value的int、long、String、String[]getter方法。 /* value是否包含search----------------------------- */ /** Look for a value in a possible multi valued field * @param search Values to search for * @return True iff the value is contained in the field value entirely or * as an element of a quoted comma separated list. List element parameters (eg qualities) are ignored, * except if they are q=0, in which case the item itself is ignored. */ public boolean contains(String search){ ... } @Override public String toString() { String v=getValue(); return getName() + ": " + (v==null?"":v); } //header是否和field同名 public boolean isSameName(HttpField field) { if (field==null) return false; if (field==this) return true; if (_header!=null && _header==field.getHeader()) return true; if (_name.equalsIgnoreCase(field.getName())) return true; return false; } private int nameHashCode() { int h = this.hash; int len = _name.length(); if (h == 0 && len > 0) { for (int i = 0; i < len; i++) { // simple case insensitive hash char c = _name.charAt(i); // assuming us-ascii (per last paragraph on http://tools.ietf.org/html/rfc7230#section-3.2.4) if ((c >= 'a' && c <= 'z')) c -= 0x20; h = 31 * h + c; } this.hash = h; } return h; } @Override public int hashCode() { if (_header==null) return _value.hashCode() ^ nameHashCode(); return _value.hashCode() ^ _header.hashCode(); } @Override public boolean equals(Object o) { if (o==this) return true; if (!(o instanceof HttpField)) return false; HttpField field=(HttpField)o; if (_header!=field.getHeader()) return false; if (!_name.equalsIgnoreCase(field.getName())) return false; if (_value==null && field.getValue()!=null) return false; return Objects.equals(_value,field.getValue()); } //內部類 public static class IntValueHttpField extends HttpField { private final int _int; //構造方法和_int的getter } public static class LongValueHttpField extends HttpField { private final long _long; //與IntValueHttpField相同 } }
HttpField包含header、name和value屬性。能夠當作一個有header的Map類。this
HttpHeader是個枚舉類,主要由General Fields、Entity Fields、Request Fields、Response Fields、Other Fields和HTTP2 Fields幾塊內容組成。咱們在查看chrome的network裏的Headers頁籤時能看到的內容能夠查看到這General、Request和Response幾塊內容,而Other和HTTP2這裏不討論,剩下就是Entity部分其實也在Request裏體現了。這就是一個文件頭。
HttpFields是HttpField的集合類。
Http協議請求消息由請求行(HttpURI)、首部行(HttpHeader)、實體主體(HttpContent)組成;而響應消息由狀態行(HttpStatus)、首部行(HttpHeader)、實體主體(HttpContent)組成。