All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.client.util.BufferingResponseListener Maven / Gradle / Ivy

There is a newer version: 11.0.0.beta1
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.client.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Response.Listener;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.util.BufferUtil;

/**
 * 

Implementation of {@link Listener} that buffers the content up to a maximum length * specified to the constructors.

*

The content may be retrieved from {@link #onSuccess(Response)} or {@link #onComplete(Result)} * via {@link #getContent()} or {@link #getContentAsString()}.

*/ public abstract class BufferingResponseListener extends Listener.Adapter { private final int maxLength; private volatile ByteBuffer buffer; private volatile String mediaType; private volatile String encoding; /** * Creates an instance with a default maximum length of 2 MiB. */ public BufferingResponseListener() { this(2 * 1024 * 1024); } /** * Creates an instance with the given maximum length * * @param maxLength the maximum length of the content */ public BufferingResponseListener(int maxLength) { this.maxLength = maxLength; } @Override public void onHeaders(Response response) { super.onHeaders(response); HttpFields headers = response.getHeaders(); long length = headers.getLongField(HttpHeader.CONTENT_LENGTH.asString()); if (length > maxLength) { response.abort(new IllegalArgumentException("Buffering capacity exceeded")); return; } buffer = BufferUtil.allocate(length > 0 ? (int)length : 1024); String contentType = headers.get(HttpHeader.CONTENT_TYPE); if (contentType != null) { String media = contentType; String charset = "charset="; int index = contentType.toLowerCase(Locale.ENGLISH).indexOf(charset); if (index > 0) { media = contentType.substring(0, index); String encoding = contentType.substring(index + charset.length()); // Sometimes charsets arrive with an ending semicolon. int semicolon = encoding.indexOf(';'); if (semicolon > 0) encoding = encoding.substring(0, semicolon).trim(); // Sometimes charsets are quoted. int lastIndex = encoding.length() - 1; if (encoding.charAt(0) == '"' && encoding.charAt(lastIndex) == '"') encoding = encoding.substring(1, lastIndex).trim(); this.encoding = encoding; } int semicolon = media.indexOf(';'); if (semicolon > 0) media = media.substring(0, semicolon).trim(); this.mediaType = media; } } @Override public void onContent(Response response, ByteBuffer content) { int length = content.remaining(); if (length > BufferUtil.space(buffer)) { int requiredCapacity = buffer == null ? 0 : buffer.capacity() + length; if (requiredCapacity > maxLength) response.abort(new IllegalArgumentException("Buffering capacity exceeded")); int newCapacity = Math.min(Integer.highestOneBit(requiredCapacity) << 1, maxLength); buffer = BufferUtil.ensureCapacity(buffer, newCapacity); } BufferUtil.append(buffer, content); } @Override public abstract void onComplete(Result result); public String getMediaType() { return mediaType; } public String getEncoding() { return encoding; } /** * @return the content as bytes * @see #getContentAsString() */ public byte[] getContent() { if (buffer == null) return new byte[0]; return BufferUtil.toArray(buffer); } /** * @return the content as a string, using the "Content-Type" header to detect the encoding * or defaulting to UTF-8 if the encoding could not be detected. * @see #getContentAsString(String) */ public String getContentAsString() { String encoding = this.encoding; if (encoding == null) return getContentAsString(StandardCharsets.UTF_8); return getContentAsString(encoding); } /** * @param encoding the encoding of the content bytes * @return the content as a string, with the specified encoding * @see #getContentAsString() */ public String getContentAsString(String encoding) { if (buffer == null) return null; return BufferUtil.toString(buffer, Charset.forName(encoding)); } /** * @param encoding the encoding of the content bytes * @return the content as a string, with the specified encoding * @see #getContentAsString() */ public String getContentAsString(Charset encoding) { if (buffer == null) return null; return BufferUtil.toString(buffer, encoding); } /** * @return Content as InputStream */ public InputStream getContentAsInputStream() { if (buffer == null) return new ByteArrayInputStream(new byte[]{}); return new ByteArrayInputStream(buffer.array(), buffer.arrayOffset(), buffer.remaining()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy