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

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

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

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.io.input.CountingInputStream;
import org.archive.util.binsearch.impl.HTTPSeekableLineReader;

public class ApacheHttp31SLR extends HTTPSeekableLineReader {
	
	private HttpClient http;
	private String url;
	private long length = -1;
	
	protected CountingInputStream cin;
		
	private GetMethod activeMethod;
		
	public ApacheHttp31SLR(HttpClient http, String url) {
		this.http = http;
		this.url = url;
	}
	
	private void acquireLength() throws URISyntaxException, HttpException, IOException {
		HttpMethod head = new HeadMethod(url);
		int code = http.executeMethod(head);
		if(code != 200) {
			throw new IOException("Unable to retrieve from " + url);
		}
		Header lengthHeader = head.getResponseHeader(CONTENT_LENGTH);
		if(lengthHeader == null) {
			throw new IOException("No Content-Length header for " + url);
		}
		String val = lengthHeader.getValue();
		try {
			length = Long.parseLong(val);
		} catch(NumberFormatException e) {
			throw new IOException("Bad Content-Length value " +url+ ": " + val);
		}
	}
	
	protected String getHeader(String header) throws URISyntaxException, HttpException, IOException {
		HttpMethod head = new HeadMethod(url);
		int code = http.executeMethod(head);
		if(code != 200) {
			throw new IOException("Unable to retrieve from " + url);
		}
		Header theHeader = head.getResponseHeader(header);
		if(theHeader == null) {
			throw new IOException("No " + header + " header for " + url);
		}
		String val = theHeader.getValue();
		return val;
	}	
	
	/* (non-Javadoc)
	 * @see org.archive.util.binsearch.impl.HTTPSeekableLineReader#getUrl()
	 */
	@Override
	public String getUrl()
	{
		return url;
	}
			
//	public void seek(long offset, boolean gzip) throws IOException {		
//		is = doSeekLoad(offset, -1);
//				
//		if (gzip) {
//    		is = new GZIPMembersInputStream(is, blockSize);
//    	}
//	}
	
//	public void seekWithMaxRead(long offset, boolean gzip, int maxLength) throws IOException {
//		is = doSeekLoad(offset, maxLength);
//		
//		if (bufferFully && (maxLength > 0) && (maxLength < 1e10)) {
//			try {
//				byte[] buffer = new byte[maxLength];
//				ByteStreams.readFully(is, buffer);
//				is.close();
//				
//				// Create new stream
//				is = new ByteArrayInputStream(buffer);
//			} finally {
//				activeMethod.releaseConnection();
//				activeMethod = null;				
//			}
//		}
//    	
//		if (gzip) {
//    		is = new GZIPMembersInputStream(is, blockSize);
//    	} 
//    }
	
	protected InputStream doSeekLoad(long offset, int maxLength) throws IOException {
		if (activeMethod != null) {
			doClose();
		}
		
		br = null;
		
		try {
		
			activeMethod = new GetMethod(url);
			
			String rangeHeader = makeRangeHeader(offset, maxLength);
			
			if (rangeHeader != null) {
				activeMethod.setRequestHeader("Range", rangeHeader);
			}
			
			if (this.isNoKeepAlive()) {
				activeMethod.setRequestHeader("Connection", "close");
			}
			
			if (this.getCookie() != null) {
				activeMethod.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
				activeMethod.setRequestHeader("Cookie", this.getCookie());
			}
			
			int code = http.executeMethod(activeMethod);
			
			connectedUrl = activeMethod.getURI().toString();
			
			if ((code != 206) && (code != 200)) {
				throw new BadHttpStatusException(code, connectedUrl + " " + rangeHeader);
			}
			
			InputStream is = activeMethod.getResponseBodyAsStream();
			cin = new CountingInputStream(is);
			return cin;
			
		} catch (IOException io) {
			if (saveErrHeader != null) {
				errHeader = getHeaderValue(saveErrHeader);	
			}
			
			connectedUrl = activeMethod.getURI().toString();
			doClose();
			throw io;
		}
	}
	
	public GetMethod getHttpMethod()
	{
		return activeMethod;
	}

	public void doClose() throws IOException {
		
		if (activeMethod == null) {
			return;
		}
		
		try {
			long contentLength = activeMethod.getResponseContentLength();
			
			long bytesRead = (cin != null ? cin.getByteCount() : 0);
			
			// If fully read, close gracefully, otherwise abort
			if ((contentLength > 0) && (contentLength == bytesRead)) {
//				try {
//					cin.close();
//				} catch (IOException e) {
//					activeMethod.abort();
//				}
			} else {
				activeMethod.abort();
			}
			
			activeMethod.releaseConnection();
			activeMethod = null;
			
		} finally {
			if (activeMethod != null) {
				activeMethod.abort();
				activeMethod.releaseConnection();
				activeMethod = null;
			}
		}
		
		cin = null;
		is = null;
		br = null;
	}

	/* (non-Javadoc)
	 * @see org.archive.util.binsearch.impl.HTTPSeekableLineReader#getSize()
	 */
	@Override
	public long getSize() throws IOException {
		if (length < 0) {
			try {
				if (activeMethod != null) {
					length = activeMethod.getResponseContentLength();
				} else {
					acquireLength();
				}
			} catch (URISyntaxException e) {
				throw new IOException(e);
			}
		}
		return length;
	}

	/* (non-Javadoc)
	 * @see org.archive.util.binsearch.impl.HTTPSeekableLineReader#getHeaderValue(java.lang.String)
	 */
	@Override
	public String getHeaderValue(String headerName) {
		if (activeMethod == null) {
			return null;
		}
		
		Header header = activeMethod.getResponseHeader(headerName);
		
		if (header == null) {
			return null;
		}
		
		return header.getValue();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy