@Override protected SessionInputBuffer createSessionInputBuffer( final Socket socket, int buffersize, final HttpParams params) throws IOException { if (buffersize == -1) { buffersize = 8192; } SessionInputBuffer inbuffer = super.createSessionInputBuffer( socket, buffersize, params); if (wireLog.isDebugEnabled()) { inbuffer = new LoggingSessionInputBuffer( inbuffer, new Wire(wireLog), HttpProtocolParams.getHttpElementCharset(params)); } return inbuffer; }
/** * Initializes this connection object with {@link SessionInputBuffer} and * {@link SessionOutputBuffer} instances to be used for sending and * receiving data. These session buffers can be bound to any arbitrary * physical output medium. * <p> * This method will invoke {@link #createHttpResponseFactory()}, * {@link #createRequestWriter(SessionOutputBuffer, HttpParams)} * and {@link #createResponseParser(SessionInputBuffer, HttpResponseFactory, HttpParams)} * methods to initialize HTTP request writer and response parser for this * connection. * * @param inbuffer the session input buffer. * @param outbuffer the session output buffer. * @param params HTTP parameters. */ protected void init( final SessionInputBuffer inbuffer, final SessionOutputBuffer outbuffer, final HttpParams params) { if (inbuffer == null) { throw new IllegalArgumentException("Input session buffer may not be null"); } if (outbuffer == null) { throw new IllegalArgumentException("Output session buffer may not be null"); } this.inbuffer = inbuffer; this.outbuffer = outbuffer; if (inbuffer instanceof EofSensor) { this.eofSensor = (EofSensor) inbuffer; } this.responseParser = createResponseParser( inbuffer, createHttpResponseFactory(), params); this.requestWriter = createRequestWriter( outbuffer, params); this.metrics = createConnectionMetrics( inbuffer.getMetrics(), outbuffer.getMetrics()); }
/** * Initializes this connection object with {@link SessionInputBuffer} and * {@link SessionOutputBuffer} instances to be used for sending and * receiving data. These session buffers can be bound to any arbitrary * physical output medium. * <p> * This method will invoke {@link #createHttpRequestFactory}, * {@link #createRequestParser(SessionInputBuffer, HttpRequestFactory, HttpParams)} * and {@link #createResponseWriter(SessionOutputBuffer, HttpParams)} * methods to initialize HTTP request parser and response writer for this * connection. * * @param inbuffer the session input buffer. * @param outbuffer the session output buffer. * @param params HTTP parameters. */ protected void init( final SessionInputBuffer inbuffer, final SessionOutputBuffer outbuffer, final HttpParams params) { if (inbuffer == null) { throw new IllegalArgumentException("Input session buffer may not be null"); } if (outbuffer == null) { throw new IllegalArgumentException("Output session buffer may not be null"); } this.inbuffer = inbuffer; this.outbuffer = outbuffer; if (inbuffer instanceof EofSensor) { this.eofSensor = (EofSensor) inbuffer; } this.requestParser = createRequestParser( inbuffer, createHttpRequestFactory(), params); this.responseWriter = createResponseWriter( outbuffer, params); this.metrics = createConnectionMetrics( inbuffer.getMetrics(), outbuffer.getMetrics()); }
/** * Creates an instance of this class. * * @param buffer the session input buffer. * @param parser the line parser. * @param params HTTP parameters. */ public AbstractMessageParser( final SessionInputBuffer buffer, final LineParser parser, final HttpParams params) { super(); if (buffer == null) { throw new IllegalArgumentException("Session input buffer may not be null"); } if (params == null) { throw new IllegalArgumentException("HTTP parameters may not be null"); } this.sessionBuffer = buffer; this.maxHeaderCount = params.getIntParameter( CoreConnectionPNames.MAX_HEADER_COUNT, -1); this.maxLineLen = params.getIntParameter( CoreConnectionPNames.MAX_LINE_LENGTH, -1); this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT; this.headerLines = new ArrayList<CharArrayBuffer>(); this.state = HEAD_LINE; }
@Override protected SessionInputBuffer createSessionInputBuffer(final Socket socket, int buffersize, final HttpParams params) throws IOException { if (buffersize == -1) { buffersize = 8192; } SessionInputBuffer inbuffer = super.createSessionInputBuffer(socket, buffersize, params); if (wireLog.isDebugEnabled()) { inbuffer = new LoggingSessionInputBuffer(inbuffer, new Wire(wireLog), HttpProtocolParams.getHttpElementCharset(params)); } return inbuffer; }
@Override protected SessionInputBuffer createSessionInputBuffer( final Socket socket, final int buffersize, final HttpParams params) throws IOException { SessionInputBuffer inbuffer = super.createSessionInputBuffer( socket, buffersize > 0 ? buffersize : 8192, params); if (wireLog.isDebugEnabled()) { inbuffer = new LoggingSessionInputBuffer( inbuffer, new Wire(wireLog), HttpProtocolParams.getHttpElementCharset(params)); } return inbuffer; }
@Test public void testResponseParsingWithSomeGarbage() throws Exception { final String s = "garbage\r\n" + "garbage\r\n" + "more garbage\r\n" + "HTTP/1.1 200 OK\r\n" + "header1: value1\r\n" + "header2: value2\r\n" + "\r\n"; final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII); final HttpMessageParser<HttpResponse> parser = new DefaultHttpResponseParser(inbuffer); final HttpResponse response = parser.parse(); Assert.assertNotNull(response); Assert.assertEquals(HttpVersion.HTTP_1_1, response.getProtocolVersion()); Assert.assertEquals(200, response.getStatusLine().getStatusCode()); final Header[] headers = response.getAllHeaders(); Assert.assertNotNull(headers); Assert.assertEquals(2, headers.length); Assert.assertEquals("header1", headers[0].getName()); Assert.assertEquals("header2", headers[1].getName()); }
@Test(expected=ProtocolException.class) public void testResponseParsingWithTooMuchGarbage() throws Exception { final String s = "garbage\r\n" + "garbage\r\n" + "more garbage\r\n" + "HTTP/1.1 200 OK\r\n" + "header1: value1\r\n" + "header2: value2\r\n" + "\r\n"; final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII); final HttpMessageParser<HttpResponse> parser = new DefaultHttpResponseParser(inbuffer) { @Override protected boolean reject(final CharArrayBuffer line, final int count) { return count >= 2; } }; parser.parse(); }
@Override protected SessionInputBuffer createSessionInputBuffer( final Socket socket, int buffersize, final HttpParams params) throws IOException { if (buffersize == -1) { buffersize = 8192; } SessionInputBuffer inbuffer = super.createSessionInputBuffer( socket, buffersize, params); if (wireLog.isDebugEnabled()) { inbuffer = new LoggingSessionInputBuffer(inbuffer, new Wire(wireLog)); } return inbuffer; }
private void acceptClient(@NotNull Socket client) throws IOException { final SessionInputBuffer inputBuffer = wrapInputStream(client.getInputStream()); final HttpMessageParser<HttpRequest> parser = new DefaultHttpRequestParser(inputBuffer, new BasicLineParser(), new DefaultHttpRequestFactory(), MessageConstraints.DEFAULT ); final SessionOutputBuffer outputBuffer = wrapOutputStream(client.getOutputStream()); final HttpMessageWriter<HttpResponse> writer = new DefaultHttpResponseWriter(outputBuffer); while (!socket.isClosed()) { try { service(inputBuffer, outputBuffer, parser, writer); } catch (ConnectionClosedException ignored) { break; } catch (HttpException e) { log.error(e.getMessage(), e); break; } } }
@Override protected HttpMessageParser<HttpResponse> createResponseParser( final SessionInputBuffer buffer, final HttpResponseFactory responseFactory, final HttpParams params) { // override in derived class to specify a line parser return new DefaultHttpResponseParser (buffer, null, responseFactory, params); }
/** * Create an instance that wraps the specified session input buffer. * @param in The session input buffer. * @param wire The wire log to use. * @param charset protocol charset, <code>ASCII</code> if <code>null</code> */ public LoggingSessionInputBuffer( final SessionInputBuffer in, final Wire wire, final String charset) { super(); this.in = in; this.eofSensor = in instanceof EofSensor ? (EofSensor) in : null; this.wire = wire; this.charset = charset != null ? charset : Consts.ASCII.name(); }
public DefaultResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); if (responseFactory == null) { throw new IllegalArgumentException ("Response factory may not be null"); } this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); this.maxGarbageLines = getMaxGarbageLines(params); }
public DefaultHttpResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); if (responseFactory == null) { throw new IllegalArgumentException ("Response factory may not be null"); } this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); }
/** * Creates a {@link BasicHttpEntity} based on properties of the given * message. The content of the entity is created by wrapping * {@link SessionInputBuffer} with a content decoder depending on the * transfer mechanism used by the message. * <p> * This method is called by the public * {@link #deserialize(SessionInputBuffer, HttpMessage)}. * * @param inbuffer the session input buffer. * @param message the message. * @return HTTP entity. * @throws HttpException in case of HTTP protocol violation. * @throws IOException in case of an I/O error. */ protected BasicHttpEntity doDeserialize( final SessionInputBuffer inbuffer, final HttpMessage message) throws HttpException, IOException { BasicHttpEntity entity = new BasicHttpEntity(); long len = this.lenStrategy.determineLength(message); if (len == ContentLengthStrategy.CHUNKED) { entity.setChunked(true); entity.setContentLength(-1); entity.setContent(new ChunkedInputStream(inbuffer)); } else if (len == ContentLengthStrategy.IDENTITY) { entity.setChunked(false); entity.setContentLength(-1); entity.setContent(new IdentityInputStream(inbuffer)); } else { entity.setChunked(false); entity.setContentLength(len); entity.setContent(new ContentLengthInputStream(inbuffer, len)); } Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE); if (contentTypeHeader != null) { entity.setContentType(contentTypeHeader); } Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING); if (contentEncodingHeader != null) { entity.setContentEncoding(contentEncodingHeader); } return entity; }
/** * Wraps session input stream and reads chunk coded input. * * @param in The session input buffer */ public ChunkedInputStream(final SessionInputBuffer in) { super(); if (in == null) { throw new IllegalArgumentException("Session input buffer may not be null"); } this.in = in; this.pos = 0; this.buffer = new CharArrayBuffer(16); this.state = CHUNK_LEN; }
/** * Creates an instance of this class. * * @param buffer the session input buffer. * @param parser the line parser. * @param responseFactory the factory to use to create * {@link HttpResponse}s. * @param params HTTP parameters. */ public HttpResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); if (responseFactory == null) { throw new IllegalArgumentException("Response factory may not be null"); } this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); }
@Override protected HttpMessage parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException, ParseException { this.lineBuf.clear(); int i = sessionBuffer.readLine(this.lineBuf); if (i == -1) { throw new NoHttpResponseException("The target server failed to respond"); } //create the status line from the status string ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); return this.responseFactory.newHttpResponse(statusline, null); }
/** * Wraps session input stream and reads input until the the end of stream. * * @param in The session input buffer */ public IdentityInputStream(final SessionInputBuffer in) { super(); if (in == null) { throw new IllegalArgumentException("Session input buffer may not be null"); } this.in = in; }
/** * Creates an instance of this class. * * @param buffer the session input buffer. * @param parser the line parser. * @param responseFactory the factory to use to create * {@link HttpResponse}s. * @param params HTTP parameters. */ public DefaultHttpResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); if (responseFactory == null) { throw new IllegalArgumentException("Response factory may not be null"); } this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); }
@Override protected HttpResponse parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException, ParseException { this.lineBuf.clear(); int i = sessionBuffer.readLine(this.lineBuf); if (i == -1) { throw new NoHttpResponseException("The target server failed to respond"); } //create the status line from the status string ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); return this.responseFactory.newHttpResponse(statusline, null); }
/** * Wraps a session input buffer and cuts off output after a defined number * of bytes. * * @param in The session input buffer * @param contentLength The maximum number of bytes that can be read from * the stream. Subsequent read operations will return -1. */ public ContentLengthInputStream(final SessionInputBuffer in, long contentLength) { super(); if (in == null) { throw new IllegalArgumentException("Input stream may not be null"); } if (contentLength < 0) { throw new IllegalArgumentException("Content length may not be negative"); } this.in = in; this.contentLength = contentLength; }
/** * Creates an instance of this class. * * @param buffer the session input buffer. * @param parser the line parser. * @param requestFactory the factory to use to create * {@link HttpRequest}s. * @param params HTTP parameters. */ public DefaultHttpRequestParser( final SessionInputBuffer buffer, final LineParser parser, final HttpRequestFactory requestFactory, final HttpParams params) { super(buffer, parser, params); if (requestFactory == null) { throw new IllegalArgumentException("Request factory may not be null"); } this.requestFactory = requestFactory; this.lineBuf = new CharArrayBuffer(128); }
@Override protected HttpRequest parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException, ParseException { this.lineBuf.clear(); int i = sessionBuffer.readLine(this.lineBuf); if (i == -1) { throw new ConnectionClosedException("Client closed connection"); } ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor); return this.requestFactory.newHttpRequest(requestline); }
/** * Creates an instance of this class. * * @param buffer the session input buffer. * @param parser the line parser. * @param requestFactory the factory to use to create * {@link HttpRequest}s. * @param params HTTP parameters. */ public HttpRequestParser( final SessionInputBuffer buffer, final LineParser parser, final HttpRequestFactory requestFactory, final HttpParams params) { super(buffer, parser, params); if (requestFactory == null) { throw new IllegalArgumentException("Request factory may not be null"); } this.requestFactory = requestFactory; this.lineBuf = new CharArrayBuffer(128); }
@Override protected HttpMessage parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException, ParseException { this.lineBuf.clear(); int i = sessionBuffer.readLine(this.lineBuf); if (i == -1) { throw new ConnectionClosedException("Client closed connection"); } ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor); return this.requestFactory.newHttpRequest(requestline); }
/** * Creates a new {@link SessionInputBuffer} bounded to a given maximum length. * * @param buffer the buffer to wrap * @param length the maximum number of bytes to read (from the buffered stream). */ public BoundSessionInputBuffer(final SessionInputBuffer buffer, final long length) { super(new HttpTransportMetricsImpl(), BUFFER_SIZE, 0, null, null); this.bounded = new ContentLengthInputStream(buffer, length); this.input = new CountingInputStream(this.bounded); super.bind(this.input); this.length = length; }
public static String[] readCRLFSeparatedBlock(SessionInputBuffer input) throws IOException { CharArrayBuffer line = new CharArrayBuffer(128); List<String> ret = new ArrayList<>(); for (;;) { if (input.readLine(line) == -1) break; if (line.length() == 0) break; ret.add(line.toString()); line.clear(); } return ret.toArray(new String[ret.size()]); }
public WarcRecord(SessionInputBuffer buffer) throws IOException { this.warcHeaders = readCRLFSeparatedBlock(buffer); if (this.warcHeaders.length == 0) throw new EOFException(); long contentLength = contentLength(this.warcHeaders); if (contentLength == -1) throw new WarcFormatException("Can't find Content-Length"); final HeaderGroup hg = toHeaderGroup(this.warcHeaders); date = WarcHeader.parseDate(WarcHeader.getFirstHeader(hg, WarcHeader.Name.WARC_DATE).getValue()); uuid = WarcHeader.parseId(WarcHeader.getFirstHeader(hg, WarcHeader.Name.WARC_RECORD_ID).getValue()); this.payload = new byte[(int)contentLength]; for (int read = 0; read < contentLength; read ++) this.payload[read] = (byte)buffer.read(); }
public HttpResponseWarcRecord(SessionInputBuffer buffer) throws IOException { super(buffer); buffer = warpSessionInputBuffer(new ByteArrayInputStream(this.payload)); this.headers = readCRLFSeparatedBlock(buffer); long contentLength = contentLength(this.headers); InputStream blockStream = new ContentLengthInputStream(buffer, contentLength); this.entity = new byte[(int)contentLength]; blockStream.read(this.entity); blockStream.close(); }
@Override protected HttpMessageParser<HttpResponse> createResponseParser(final SessionInputBuffer buffer, final HttpResponseFactory responseFactory, final HttpParams params) { // override in derived class to specify a line parser return new DefaultHttpResponseParser(buffer, null, responseFactory, params); }
protected InputStream createInputStream( final long len, final SessionInputBuffer inbuffer) { if (len == ContentLengthStrategy.CHUNKED) { return new ChunkedInputStreamHC4(inbuffer); } else if (len == ContentLengthStrategy.IDENTITY) { return new IdentityInputStreamHC4(inbuffer); } else { return new ContentLengthInputStreamHC4(inbuffer, len); } }
/** * @deprecated (4.3) use {@link DefaultHttpResponseParser#DefaultHttpResponseParser( * SessionInputBuffer, LineParser, HttpResponseFactory, MessageConstraints)} */ @Deprecated public DefaultHttpResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); Args.notNull(responseFactory, "Response factory"); this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); }
/** * Wraps session input stream and reads chunk coded input. * * @param in The session input buffer */ public ChunkedInputStreamHC4(final SessionInputBuffer in) { super(); this.in = Args.notNull(in, "Session input buffer"); this.pos = 0; this.buffer = new CharArrayBuffer(16); this.state = CHUNK_LEN; }
@Override protected HttpResponse parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException, ParseException { this.lineBuf.clear(); final int i = sessionBuffer.readLine(this.lineBuf); if (i == -1) { throw new NoHttpResponseException("The target server failed to respond"); } //create the status line from the status string final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); return this.responseFactory.newHttpResponse(statusline, null); }
@Override protected HttpRequest parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException, ParseException { this.lineBuf.clear(); final int i = sessionBuffer.readLine(this.lineBuf); if (i == -1) { throw new ConnectionClosedException("Client closed connection"); } final ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); final RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor); return this.requestFactory.newHttpRequest(requestline); }
/** * Creates an instance of AbstractMessageParserHC4. * * @param buffer the session input buffer. * @param parser the line parser. * @param params HTTP parameters. * * @deprecated (4.3) use {@link AbstractMessageParserHC4#AbstractMessageParserHC4(SessionInputBuffer, * LineParser, MessageConstraints)} */ @Deprecated public AbstractMessageParserHC4( final SessionInputBuffer buffer, final LineParser parser, final HttpParams params) { super(); Args.notNull(buffer, "Session input buffer"); Args.notNull(params, "HTTP parameters"); this.sessionBuffer = buffer; this.messageConstraints = HttpParamConfig.getMessageConstraints(params); this.lineParser = (parser != null) ? parser : BasicLineParserHC4.INSTANCE; this.headerLines = new ArrayList<CharArrayBuffer>(); this.state = HEAD_LINE; }
/** * Creates new instance of AbstractMessageParserHC4. * * @param buffer the session input buffer. * @param lineParser the line parser. If <code>null</code> {@link BasicLineParserHC4#INSTANCE} * will be used. * @param constraints the message constraints. If <code>null</code> * {@link MessageConstraints#DEFAULT} will be used. * * @since 4.3 */ public AbstractMessageParserHC4( final SessionInputBuffer buffer, final LineParser lineParser, final MessageConstraints constraints) { super(); this.sessionBuffer = Args.notNull(buffer, "Session input buffer"); this.lineParser = lineParser != null ? lineParser : BasicLineParserHC4.INSTANCE; this.messageConstraints = constraints != null ? constraints : MessageConstraints.DEFAULT; this.headerLines = new ArrayList<CharArrayBuffer>(); this.state = HEAD_LINE; }