Subject: Range requests (information only)

From: "Dave Wain" <[email-masked]>
Date: Tue, 22 Dec 2015 10:10:59 -0000

A typical Java get with a range request looks like this:

	/**
	 * Retrieves the part of the file required via HTTP.
	 */
	private byte[] getHttpBytes(HeaderAndData hnd, long index, int
nbytes)
	{
		// Allocate a new buffer
		final byte[] bytes = new byte[nbytes];

		try {
			// Create a header to read the correct data
			final URLConnection uc = hnd.data.openConnection();
			final long last = index + nbytes - 1;
	
uc.setRequestProperty("Range","bytes="+index+"-"+last);
			uc.setRequestProperty("Accept-Encoding","gzip,
deflate");
			uc.setUseCaches(false); //BUG applets

			// Do the request
			final InputStream raw = uc.getInputStream();
			final String encoding =
uc.getHeaderField("Content-Encoding");
			final InputStream in;
			if ("gzip".equals(encoding)) {
				in = new GZIPInputStream(raw);
			} else if ("deflate".equals(encoding)) {
				in = new InflaterInputStream(raw);
			} else {
				in = raw;
			}

			// Read the required data
			int nread = 0;
			for (int result; nread<nbytes; nread+=result) {
				result = in.read(bytes, nread,
nbytes-nread);
				if (result < 0) break;
			}

			// Check for incomplete reads
			if (nread < nbytes) {
	
DEMViewer.log("Incomplete,nbytes="+nbytes+",nread="+nread);
			}

			// Clear and close (implies Stay-Alive)
			while (raw.available() > 0) raw.read();
			raw.close();
		}
		catch(IOException ex) {
			DEMViewer.log(ex+",index="+index+",nbytes"+nbytes);
		}

		return bytes;
	}

Hope this helps :)

DW

Note: This message is private and confidential and hence
must be received without interception or distortion by the
intended recipients only. Permission to use the information
explicitly must come from the sender (and recipients).

My personal web site and alternate contact details are at:
http://homepage.ntlworld.com/dave.wain/.

---

From: Matthew Kerwin <[email-masked]>
Date: Tue, 22 Dec 2015 20:42:29 +1000

Ugh, that's why we can't have nice things... This is using
Transfer-Encoding, but is calling it Content-Encoding. It will probably
work in the wild because you'll either get a 200 (complete response) with
Content-Encoding:gzip, *or* a 206 (partial response) without. If you
happened on both at once, and the range didn't start at zero, your
`in.read(...)` would fail with a ZipException because of the missing gzip
header.

I'm assuming differentiation of 200/206 and Content-Range are elided for
brevity; but that 'clear and close' line makes me nervous.

-- 
  Matthew Kerwin
  http://matthew.kerwin.net.au/