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

org.archive.util.binsearch.impl.http.ApacheHttp43SLR Maven / Gradle / Ivy

There is a newer version: 1.1.9
Show newest version
package org.archive.util.binsearch.impl.http;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;

import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.impl.DefaultBHttpClientConnection;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.util.EntityUtils;
import org.archive.util.binsearch.impl.HTTPSeekableLineReader;
import org.archive.util.zip.GZIPMembersInputStream;

public class ApacheHttp43SLR extends HTTPSeekableLineReader {

	private String urlString;
	
	private int connectTimeout = 0;
	private int readTimeout = 0;
	
	private Socket socket = null;
	private DefaultBHttpClientConnection activeConn = null;
	private HttpResponse response = null;
	
	private final static int BUFF_SIZE = 8192;
	
	public ApacheHttp43SLR(String url)
	{
		urlString = url;
	}
	
	public ApacheHttp43SLR(String url, int connectTimeout, int readTimeout)
	{
		this.urlString = url;
		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
	}
	
	@Override
    public String getUrl() {
	    return urlString;
    }

	@Override
    public long getSize() throws IOException {
		if (response == null) {
			return 0;
		}
		
		return response.getEntity().getContentLength();
    }

	@Override
    public String getHeaderValue(String headerName) {
		if (response == null) {
			return null;
		}
		
		Header header = response.getFirstHeader(headerName);
		if (header == null) {
			return null;
		}
		
		return header.getValue();
	}
	
	protected static int getPort(URL url)
	{
		int port = url.getPort();
		
		if (port > 0) {
			return port;
		}
		
		return url.getDefaultPort();
	}
	
    protected InputStream doSeekLoad(long offset, int maxLength, URL url)
            throws IOException {
		
		try {
			SocketAddress endpoint = new InetSocketAddress(url.getHost(), getPort(url));
			
			socket = new Socket();
			socket.connect(endpoint, connectTimeout);
			
			activeConn = new DefaultBHttpClientConnection(BUFF_SIZE);
			activeConn.bind(socket);
			activeConn.setSocketTimeout(readTimeout);
			
			HttpRequest request = new BasicHttpRequest("GET", url.getFile(), HttpVersion.HTTP_1_1);
			
			String rangeHeader = makeRangeHeader(offset, maxLength);
			
			if (rangeHeader != null) {
				request.setHeader("Range", rangeHeader);
			}
			
			if (this.isNoKeepAlive()) {
				request.setHeader("Connection", "close");
			} else {
				request.setHeader("Connection", "keep-alive");
			}
			
			if (this.getCookie() != null) {
				request.setHeader("Cookie", this.getCookie());
			}
			
			request.setHeader("Accept", "*/*");
			request.setHeader("Host", url.getHost());
			
			activeConn.sendRequestHeader(request);
			activeConn.flush();
						
			response = activeConn.receiveResponseHeader();
			
			int code = response.getStatusLine().getStatusCode();
			
			connectedUrl = url.toString();
			
			if (code > 300 && code < 400) {
				Header header = response.getFirstHeader("Location");
				
				doClose();
				
				if (header != null) {
					URL redirectURL = new URL(header.getValue());
					return doSeekLoad(offset, maxLength, redirectURL);
				}
			}
			
			if (code != 200 && code != 206) {
				throw new BadHttpStatusException(code, connectedUrl + " " + rangeHeader);
			}
			
			activeConn.receiveResponseEntity(response);
			
			return response.getEntity().getContent();
			
		} catch (HttpException e) {
			doClose();
			throw new IOException(e);
			
        } catch (IOException io) {
        	
			if (saveErrHeader != null) {
				errHeader = getHeaderValue(saveErrHeader);	
			}
			
			connectedUrl = url.toString();
			
			doClose();
			throw io;
        }
    }
    
    @Override
	public void seekWithMaxRead(long offset, boolean gzip, int maxLength) throws IOException
	{
		if (closed) {
			throw new IOException("Seek after close()");
		}
		
		br = null;
		
		try {
			doSeekLoad(offset, maxLength);
		
			if (bufferFully && (maxLength > 0)) {
				byte[] buffer = EntityUtils.toByteArray(response.getEntity());
				
				doClose();
				
				is = new ByteArrayInputStream(buffer);
			}
		
	    	if (gzip) {
	    		is = new GZIPMembersInputStream(is, blockSize);
	    	}
	    	
		} catch (IOException io) {
			doClose();
			throw io;
		}
	}

	@Override
    protected void doClose() throws IOException {
		if (activeConn != null) {
			activeConn.close();
			activeConn = null;
			socket = null;
		} else if (socket != null) {
			socket.close();
			socket = null;
		}
		response = null;
	}

	@Override
    protected InputStream doSeekLoad(long offset, int maxLength)
            throws IOException {
		
		return doSeekLoad(offset, maxLength, new URL(urlString));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy