001: package org.xsocket.web.http;
002:
003: import java.io.IOException;
004: import java.nio.BufferUnderflowException;
005: import java.util.ArrayList;
006: import java.util.Collections;
007: import java.util.Enumeration;
008: import java.util.HashMap;
009: import java.util.List;
010: import java.util.Map;
011: import java.util.logging.Level;
012: import java.util.logging.Logger;
013:
014: import org.xsocket.IDataSource;
015:
016: abstract class Header implements IHeader {
017:
018: private static final Logger LOG = Logger.getLogger(Header.class
019: .getName());
020:
021: private String firstLine = null;
022: private Map<String, List<String>> headers = new HashMap<String, List<String>>();
023:
024: Header(String firstLine, String... headerLines) {
025: this .firstLine = firstLine;
026:
027: for (int i = 0; i < headerLines.length; i++) {
028: int idx = headerLines[i].indexOf(":");
029: if (idx != -1) {
030: addHeader(headerLines[i].substring(0, idx)
031: .toUpperCase(), headerLines[i].substring(
032: idx + 1, headerLines[i].length()).trim());
033: } else {
034: if (LOG.isLoggable(Level.FINE)) {
035: LOG.info("invalid header entry: " + headerLines[i]);
036: }
037: }
038: }
039: }
040:
041: protected final String getFirstLine() {
042: return firstLine;
043: }
044:
045: public final int getContentLength() {
046: String s = getHeader("Content-Length");
047: if (s == null) {
048: return -1;
049: } else {
050: return Integer.parseInt(s);
051: }
052: }
053:
054: public final String getTransferEncoding() {
055: return getHeader("Transfer-Encoding");
056: }
057:
058: public boolean hasBody() {
059: if (getContentLength() > 0) {
060: return true;
061: }
062:
063: String transferEncoding = getHeader("Transfer-Encoding");
064: if (transferEncoding == null) {
065: return false;
066: } else {
067: if (transferEncoding.equalsIgnoreCase("chunked")) {
068: return true;
069: }
070: }
071:
072: return false;
073: }
074:
075: public void addHeader(String headername, String headervalue) {
076: headername = headername.toUpperCase();
077: List<String> values = headers.get(headername);
078:
079: if (values == null) {
080: values = new ArrayList<String>();
081: headers.put(headername, values);
082: }
083:
084: values.add(headervalue);
085: }
086:
087: public boolean containsHeader(String headername) {
088: headername = headername.toUpperCase();
089: return headers.containsKey(headername);
090: }
091:
092: public final Enumeration getHeaderNames() {
093: return Collections.enumeration(headers.keySet());
094: }
095:
096: @SuppressWarnings("unchecked")
097: public final Enumeration getHeaders(String headername) {
098: headername = headername.toUpperCase();
099: if (headers.containsKey(headername)) {
100: return Collections.enumeration(headers.get(headername));
101: } else {
102: return Collections.enumeration(new ArrayList());
103: }
104: }
105:
106: public final String getHeader(String headername) {
107: headername = headername.toUpperCase();
108: List<String> values = headers.get(headername);
109: if (values != null) {
110: return values.get(0);
111: } else {
112: return null;
113: }
114: }
115:
116: @Override
117: public String toString() {
118: StringBuilder sb = new StringBuilder();
119:
120: // write request line
121: sb.append(getFirstLine() + "\r\n");
122:
123: // write message headers
124: for (Enumeration enName = getHeaderNames(); enName
125: .hasMoreElements();) {
126: String headername = (String) enName.nextElement();
127: for (Enumeration enValue = getHeaders(headername); enValue
128: .hasMoreElements();) {
129: String headerLine = headername + ": "
130: + enValue.nextElement();
131: sb.append(headerLine + "\r\n");
132: }
133: }
134:
135: // write blank line
136: sb.append("\r\n");
137: return sb.toString();
138: }
139:
140: static Header readFrom(IDataSource dataSource, int maxLength)
141: throws BufferUnderflowException, IOException {
142: String rawHeader = dataSource.readStringByDelimiter("\r\n\r\n",
143: "US-ASCII", maxLength);
144:
145: String firstLine = rawHeader.substring(0, rawHeader
146: .indexOf("\r\n"));
147: String[] headerLines = rawHeader.substring(
148: rawHeader.indexOf("\r\n") + 2, rawHeader.length())
149: .split("\r\n");
150:
151: if (firstLine.toUpperCase().startsWith("HTTP/")) {
152: return new ResponseHeader(firstLine, headerLines);
153: } else {
154: return new RequestHeader(firstLine, headerLines);
155: }
156: }
157: }
|