Strictly speaking, you might be able to do this by making two HTTP requests:
- Make a
HEAD
request, which should return a Content-Length
header, which tells you the size of the file.
- Do a
GET
request with a Content-Range
header to request the last N bytes of the file.
Of course, this only works if the lines in the file tend to stay close to a particular average length. So if you know the lines in the file tend to have around 100 bytes, and you want the last 20 lines, you could request the last, say, 2,400 bytes (20 lines ✕ 100 bytes + 20% for good measure). Then you could parse the response to get the last 20 lines.
This is untested (since I don't have a server handy to test against) and doesn't have any error handling, but something like this ought to work, assuming lighttpd is configured to return the Content-Range
header with responses to HEAD requests:
var url = "http://example.com/some-file.txt",
averageLineLength = 100,
numLinesToFetch = 20,
marginForError = 0.2,
bytesToFetch = averageLineLength * numLinesToFetch * (1 + marginForError)
;
$.ajax({ url: url, type: "HEAD" })
.then( function(_, _, xhr) {
var fileSize = parseInt(xhr.getResponseHeader('Content-Length')),
contentRangeStart = fileSize - bytesToFetch,
contentRangeEnd = fileSize - 1,
contentRange = contentRangeStart + "-" + contentRangeEnd + "/" + fileSize,
headers = { "Content-Length": bytesToFetch,
"Content-Range": "bytes " + contentRange }
;
return $.ajax({ url: url, type: "GET", headers: headers });
} )
.then( function(data, statusText, xhr) {
var lines = data.split("\n");
lines = lines.slice(numLinesToFetch * -1);
console.log( "Last " + numLinesToFetch + " lines:\n",
lines );
} )
;
It's kind of convoluted, and requires requesting extra data every time (and if you're getting a lot of data there are memory implications, especially with the naive data.split
), and I'm not sure if lighthttp is equipped to do this out of the box, but it's an idea!