package io.craft.atom.protocol.http.model; import static io.craft.atom.protocol.http.HttpConstants.S_COLON; import static io.craft.atom.protocol.http.HttpConstants.S_COMMA; import static io.craft.atom.protocol.http.HttpConstants.S_CR; import static io.craft.atom.protocol.http.HttpConstants.S_EQUAL_SIGN; import static io.craft.atom.protocol.http.HttpConstants.S_LF; import static io.craft.atom.protocol.http.HttpConstants.S_SEMICOLON; import static io.craft.atom.protocol.http.HttpConstants.S_SP; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import lombok.Getter; import lombok.Setter; import lombok.ToString; /** * Represents a HTTP header field. * * <p> * The HTTP header fields follow the same generic format as that given in * Section 3.1 of RFC 822. Each header field consists of a name followed by a * colon (":") and the field value. Field names are case-insensitive. The field * value MAY be preceded by any amount of LWS(Linear White Space), though a single SP is preferred. * * <pre> * LWS = [CRLF] 1*( SP | HT ) * HT = Horizontal Tab * SP = Space * CRLF = Carriage return/Line feed * </pre> * * <pre> * message-header = field-name ":" [ field-value ] * field-name = token * field-value = *( field-content | LWS ) * field-content = <the OCTETs making up the field-value * and consisting of either *TEXT or combinations * of token, separators, and quoted-string> * </pre> * * @author mindwind * @version 1.0, Feb 1, 2013 * @see HttpMessage */ @ToString(of = { "name", "value" }) public class HttpHeader implements Serializable { private static final long serialVersionUID = -689954816191532018L; @Getter @Setter private String name ; @Getter @Setter private String value; // ~ ----------------------------------------------------------------------------------------------------------- public HttpHeader() { super(); } public HttpHeader(String name, String value) { this.name = name; this.value = value; } // ~ ----------------------------------------------------------------------------------------------------------- public void appendValue(String valuePart) { if (value == null) { value = valuePart; } else { this.value += valuePart; } } /** * Parses the header string value and return a list of {@code HttpHeaderValueElement} * * @return a list of {@code HttpHeaderValueElement} */ public List<HttpHeaderValueElement> getValueElements() { List<HttpHeaderValueElement> elements = new ArrayList<HttpHeaderValueElement>(); if (value == null || value.length() == 0) { return elements; } String[] earr = value.split(S_COMMA); for (String es : earr) { HttpHeaderValueElement hve = new HttpHeaderValueElement(); String[] nvs = es.split(S_SEMICOLON); parseNameValue(hve, nvs[0]); for (int i = 1; i < nvs.length; i++) { parseParams(hve, nvs[i]); } elements.add(hve); } return elements; } private void parseParams(HttpHeaderValueElement hve, String pnv) { String[] nvpair = pnv.split(S_EQUAL_SIGN); if (nvpair.length > 1) { hve.addParam(nvpair[0], nvpair[1]); } else { hve.addParam(nvpair[0], null); } } private void parseNameValue(HttpHeaderValueElement hve, String nv) { String[] nvpair = nv.split(S_EQUAL_SIGN); hve.setName(nvpair[0]); if (nvpair.length > 1) { hve.setValue(nvpair[1]); } } public String toHttpString() { StringBuilder sb = new StringBuilder(); sb.append(getName()).append(S_COLON).append(S_SP).append(getValue()).append(S_CR).append(S_LF); return sb.toString(); } }