001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.impl.io;
029
030import java.io.IOException;
031
032import org.apache.http.HttpException;
033import org.apache.http.HttpResponse;
034import org.apache.http.HttpResponseFactory;
035import org.apache.http.NoHttpResponseException;
036import org.apache.http.ParseException;
037import org.apache.http.StatusLine;
038import org.apache.http.config.MessageConstraints;
039import org.apache.http.impl.DefaultHttpResponseFactory;
040import org.apache.http.io.SessionInputBuffer;
041import org.apache.http.message.LineParser;
042import org.apache.http.message.ParserCursor;
043import org.apache.http.params.HttpParams;
044import org.apache.http.util.Args;
045import org.apache.http.util.CharArrayBuffer;
046
047/**
048 * HTTP response parser that obtain its input from an instance
049 * of {@link SessionInputBuffer}.
050 *
051 * @since 4.2
052 */
053@SuppressWarnings("deprecation")
054public class DefaultHttpResponseParser extends AbstractMessageParser<HttpResponse> {
055
056    private final HttpResponseFactory responseFactory;
057    private final CharArrayBuffer lineBuf;
058
059    /**
060     * Creates an instance of this class.
061     *
062     * @param buffer the session input buffer.
063     * @param lineParser the line parser.
064     * @param responseFactory the factory to use to create
065     *    {@link HttpResponse}s.
066     * @param params HTTP parameters.
067     *
068     * @deprecated (4.3) use
069     *   {@link DefaultHttpResponseParser#DefaultHttpResponseParser(SessionInputBuffer, LineParser,
070     *     HttpResponseFactory, MessageConstraints)}
071     */
072    @Deprecated
073    public DefaultHttpResponseParser(
074            final SessionInputBuffer buffer,
075            final LineParser lineParser,
076            final HttpResponseFactory responseFactory,
077            final HttpParams params) {
078        super(buffer, lineParser, params);
079        this.responseFactory = Args.notNull(responseFactory, "Response factory");
080        this.lineBuf = new CharArrayBuffer(128);
081    }
082
083    /**
084     * Creates new instance of DefaultHttpResponseParser.
085     *
086     * @param buffer the session input buffer.
087     * @param lineParser the line parser. If {@code null}
088     *   {@link org.apache.http.message.BasicLineParser#INSTANCE} will be used
089     * @param responseFactory the response factory. If {@code null}
090     *   {@link DefaultHttpResponseFactory#INSTANCE} will be used.
091     * @param constraints the message constraints. If {@code null}
092     *   {@link MessageConstraints#DEFAULT} will be used.
093     *
094     * @since 4.3
095     */
096    public DefaultHttpResponseParser(
097            final SessionInputBuffer buffer,
098            final LineParser lineParser,
099            final HttpResponseFactory responseFactory,
100            final MessageConstraints constraints) {
101        super(buffer, lineParser, constraints);
102        this.responseFactory = responseFactory != null ? responseFactory :
103            DefaultHttpResponseFactory.INSTANCE;
104        this.lineBuf = new CharArrayBuffer(128);
105    }
106
107    /**
108     * @since 4.3
109     */
110    public DefaultHttpResponseParser(
111            final SessionInputBuffer buffer,
112            final MessageConstraints constraints) {
113        this(buffer, null, null, constraints);
114    }
115
116    /**
117     * @since 4.3
118     */
119    public DefaultHttpResponseParser(final SessionInputBuffer buffer) {
120        this(buffer, null, null, MessageConstraints.DEFAULT);
121    }
122
123    @Override
124    protected HttpResponse parseHead(
125            final SessionInputBuffer sessionBuffer)
126        throws IOException, HttpException, ParseException {
127
128        this.lineBuf.clear();
129        final int i = sessionBuffer.readLine(this.lineBuf);
130        if (i == -1) {
131            throw new NoHttpResponseException("The target server failed to respond");
132        }
133        //create the status line from the status string
134        final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length());
135        final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
136        return this.responseFactory.newHttpResponse(statusline, null);
137    }
138
139}