1 /* 2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractMessageParser.java $ 3 * $Revision: 576077 $ 4 * $Date: 2007-09-16 04:50:22 -0700 (Sun, 16 Sep 2007) $ 5 * 6 * ==================================================================== 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 * ==================================================================== 24 * 25 * This software consists of voluntary contributions made by many 26 * individuals on behalf of the Apache Software Foundation. For more 27 * information on the Apache Software Foundation, please see 28 * <http://www.apache.org/>. 29 * 30 */ 31 32 package org.apache.http.impl.io; 33 34 import java.io.IOException; 35 import java.util.ArrayList; 36 37 import org.apache.http.Header; 38 import org.apache.http.HttpException; 39 import org.apache.http.HttpMessage; 40 import org.apache.http.ParseException; 41 import org.apache.http.ProtocolException; 42 import org.apache.http.io.HttpMessageParser; 43 import org.apache.http.io.SessionInputBuffer; 44 import org.apache.http.message.LineParser; 45 import org.apache.http.message.BasicLineParser; 46 import org.apache.http.params.CoreConnectionPNames; 47 import org.apache.http.params.HttpParams; 48 import org.apache.http.util.CharArrayBuffer; 49 50 /** 51 * Message parser base class. 52 * 53 * @author Michael Becke 54 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> 55 * 56 * @deprecated Please use {@link java.net.URL#openConnection} instead. 57 * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 58 * for further details. 59 */ 60 @Deprecated 61 public abstract class AbstractMessageParser implements HttpMessageParser { 62 63 private final SessionInputBuffer sessionBuffer; 64 private final int maxHeaderCount; 65 private final int maxLineLen; 66 protected final LineParser lineParser; 67 68 AbstractMessageParser( final SessionInputBuffer buffer, final LineParser parser, final HttpParams params)69 public AbstractMessageParser( 70 final SessionInputBuffer buffer, 71 final LineParser parser, 72 final HttpParams params) { 73 super(); 74 if (buffer == null) { 75 throw new IllegalArgumentException("Session input buffer may not be null"); 76 } 77 if (params == null) { 78 throw new IllegalArgumentException("HTTP parameters may not be null"); 79 } 80 this.sessionBuffer = buffer; 81 this.maxHeaderCount = params.getIntParameter( 82 CoreConnectionPNames.MAX_HEADER_COUNT, -1); 83 this.maxLineLen = params.getIntParameter( 84 CoreConnectionPNames.MAX_LINE_LENGTH, -1); 85 this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT; 86 } 87 88 /** 89 * Parses HTTP headers from the data receiver stream according to the generic 90 * format as given in Section 3.1 of RFC 822, RFC-2616 Section 4 and 19.3. 91 * 92 * @param inbuffer Session input buffer 93 * @param maxHeaderCount maximum number of headers allowed. If the number 94 * of headers received from the data stream exceeds maxCount value, an 95 * IOException will be thrown. Setting this parameter to a negative value 96 * or zero will disable the check. 97 * @param maxLineLen maximum number of characters for a header line, 98 * including the continuation lines 99 * @return array of HTTP headers 100 * 101 * @throws HttpException 102 * @throws IOException 103 */ parseHeaders( final SessionInputBuffer inbuffer, int maxHeaderCount, int maxLineLen, LineParser parser)104 public static Header[] parseHeaders( 105 final SessionInputBuffer inbuffer, 106 int maxHeaderCount, 107 int maxLineLen, 108 LineParser parser) 109 throws HttpException, IOException { 110 111 if (inbuffer == null) { 112 throw new IllegalArgumentException("Session input buffer may not be null"); 113 } 114 if (parser == null) 115 parser = BasicLineParser.DEFAULT; 116 117 ArrayList headerLines = new ArrayList(); 118 119 CharArrayBuffer current = null; 120 CharArrayBuffer previous = null; 121 for (;;) { 122 if (current == null) { 123 current = new CharArrayBuffer(64); 124 } else { 125 current.clear(); 126 } 127 int l = inbuffer.readLine(current); 128 if (l == -1 || current.length() < 1) { 129 break; 130 } 131 // Parse the header name and value 132 // Check for folded headers first 133 // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2 134 // discussion on folded headers 135 if ((current.charAt(0) == ' ' || current.charAt(0) == '\t') && previous != null) { 136 // we have continuation folded header 137 // so append value 138 int i = 0; 139 while (i < current.length()) { 140 char ch = current.charAt(i); 141 if (ch != ' ' && ch != '\t') { 142 break; 143 } 144 i++; 145 } 146 if (maxLineLen > 0 147 && previous.length() + 1 + current.length() - i > maxLineLen) { 148 throw new IOException("Maximum line length limit exceeded"); 149 } 150 previous.append(' '); 151 previous.append(current, i, current.length() - i); 152 } else { 153 headerLines.add(current); 154 previous = current; 155 current = null; 156 } 157 if (maxHeaderCount > 0 && headerLines.size() >= maxHeaderCount) { 158 throw new IOException("Maximum header count exceeded"); 159 } 160 } 161 Header[] headers = new Header[headerLines.size()]; 162 for (int i = 0; i < headerLines.size(); i++) { 163 CharArrayBuffer buffer = (CharArrayBuffer) headerLines.get(i); 164 try { 165 headers[i] = parser.parseHeader(buffer); 166 } catch (ParseException ex) { 167 throw new ProtocolException(ex.getMessage()); 168 } 169 } 170 return headers; 171 } 172 parseHead(SessionInputBuffer sessionBuffer)173 protected abstract HttpMessage parseHead(SessionInputBuffer sessionBuffer) 174 throws IOException, HttpException, ParseException; 175 parse()176 public HttpMessage parse() throws IOException, HttpException { 177 HttpMessage message = null; 178 try { 179 message = parseHead(this.sessionBuffer); 180 } catch (ParseException px) { 181 throw new ProtocolException(px.getMessage(), px); 182 } 183 Header[] headers = AbstractMessageParser.parseHeaders( 184 this.sessionBuffer, 185 this.maxHeaderCount, 186 this.maxLineLen, 187 this.lineParser); 188 message.setHeaders(headers); 189 return message; 190 } 191 192 } 193