contentType += "; charset=" + CONFIG.getEncoding();
}
response.setContentType(contentType);
}
StaticFileOutputStream out = null;
try {
out = ((HttpServletResponseImpl) response)
.getStaticFileOutputStream();
long fileLen = file.length();
String range = request.getHeader("Range");
if (range == null) {
out.write(file);
} else {
String[] rangesSpecifier = StringUtils.split(range, '=');
if (rangesSpecifier.length != 2) {
response.setStatus(416);
out.write(RANGE_ERROR_HTML.getBytes(CONFIG.getEncoding()));
return;
}
String byteRangeSet = rangesSpecifier[1].trim();
String[] byteRangeSets = StringUtils.split(byteRangeSet, ',');
if (byteRangeSets.length > 1) { // multipart/byteranges
String boundary = "ff10" + RandomUtils.randomString(13);
if (byteRangeSets.length > CONFIG.getMaxRangeNum()) {
log.error("multipart range more than {}",
CONFIG.getMaxRangeNum());
response.setStatus(416);
out.write(RANGE_ERROR_HTML.getBytes(CONFIG
.getEncoding()));
return;
}
// multipart output
List<MultipartByteranges> tmpByteRangeSets = new ArrayList<MultipartByteranges>(
CONFIG.getMaxRangeNum());
// long otherLen = 0;
for (String t : byteRangeSets) {
String tmp = t.trim();
String[] byteRange = StringUtils.split(tmp, '-');
if (byteRange.length == 1) {
long pos = Long.parseLong(byteRange[0].trim());
if (pos == 0)
continue;
if (tmp.charAt(0) == '-') {
long lastBytePos = fileLen - 1;
long firstBytePos = lastBytePos - pos + 1;
if (firstBytePos > lastBytePos)
continue;
MultipartByteranges multipartByteranges = getMultipartByteranges(
contentType, firstBytePos, lastBytePos,
fileLen, boundary);
tmpByteRangeSets.add(multipartByteranges);
} else if (tmp.charAt(tmp.length() - 1) == '-') {
long firstBytePos = pos;
long lastBytePos = fileLen - 1;
if (firstBytePos > lastBytePos)
continue;
MultipartByteranges multipartByteranges = getMultipartByteranges(
contentType, firstBytePos, lastBytePos,
fileLen, boundary);
tmpByteRangeSets.add(multipartByteranges);
}
} else {
long firstBytePos = Long.parseLong(byteRange[0]
.trim());
long lastBytePos = Long.parseLong(byteRange[1]
.trim());
if (firstBytePos > fileLen
|| firstBytePos >= lastBytePos)
continue;
MultipartByteranges multipartByteranges = getMultipartByteranges(
contentType, firstBytePos, lastBytePos,
fileLen, boundary);
tmpByteRangeSets.add(multipartByteranges);
}
}
if (tmpByteRangeSets.size() > 0) {
response.setStatus(206);
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Type",
"multipart/byteranges; boundary=" + boundary);
for (MultipartByteranges m : tmpByteRangeSets) {
long length = m.lastBytePos - m.firstBytePos + 1;
out.write(m.head.getBytes(CONFIG.getEncoding()));
out.write(file, m.firstBytePos, length);
}
out.write((CRLF + "--" + boundary + "--" + CRLF)
.getBytes(CONFIG.getEncoding()));
log.debug("multipart download|{}", range);
} else {
response.setStatus(416);
out.write(RANGE_ERROR_HTML.getBytes(CONFIG
.getEncoding()));
return;
}
} else {
String tmp = byteRangeSets[0].trim();
String[] byteRange = StringUtils.split(tmp, '-');
if (byteRange.length == 1) {
long pos = Long.parseLong(byteRange[0].trim());
if (pos == 0) {
response.setStatus(416);
out.write(RANGE_ERROR_HTML.getBytes(CONFIG
.getEncoding()));
return;
}
if (tmp.charAt(0) == '-') {
long lastBytePos = fileLen - 1;
long firstBytePos = lastBytePos - pos + 1;
writePartialFile(request, response, out, file,
firstBytePos, lastBytePos, fileLen);
} else if (tmp.charAt(tmp.length() - 1) == '-') {
writePartialFile(request, response, out, file, pos,
fileLen - 1, fileLen);
} else {
response.setStatus(416);
out.write(RANGE_ERROR_HTML.getBytes(CONFIG
.getEncoding()));
return;
}
} else {
long firstBytePos = Long.parseLong(byteRange[0].trim());
long lastBytePos = Long.parseLong(byteRange[1].trim());
if (firstBytePos > fileLen
|| firstBytePos >= lastBytePos) {
response.setStatus(416);
out.write(RANGE_ERROR_HTML.getBytes(CONFIG
.getEncoding()));
return;
}
if (lastBytePos >= fileLen)
lastBytePos = fileLen - 1;
writePartialFile(request, response, out, file,
firstBytePos, lastBytePos, fileLen);
}
log.debug("single range download|{}", range);
}
}
} catch (Throwable e) {
throw new HttpServerException("get static file output stream error");
} finally {
if (out != null)
try {
// System.out.println("close~~");
out.close();
} catch (IOException e) {
throw new HttpServerException(
"static file output stream close error");
}
}