Seguinte, escrevi um servlet que pega um arquivo no servidor e manda para o browser. O código do método é bem trivial:
public static void returnFile(String filename, OutputStream out)
throws FileNotFoundException, IOException {
InputStream in = null;
try {
in = new BufferedInputStream(filename);
byte[] buf = new byte[4 * 1024]; // 4K buffer
int bytesRead;
while ((bytesRead = in.read(buf)) != -1) {
out.write(buf, 0, bytesRead);
}
} finally {
if (in != null) in.close( );
}
}
A idéia é servir o arquivo e saber quando o cliente conseguiu fazer o download, gravando a situação num HashMap “fileStatus”, assim, no corpo do método doGet() tenho algo assim
OutputStream out = response.getOutputStream();
try {
// Marca que está fazendo o download
fileStatus.put(filename, STATUS_DL);
returnFile(filename, out);
// Se chegou aqui sem nenhuma exception
fileStatus.put(filename, STATUS_OK);
}
catch(Exception ex) {
fileStatus.put(filename, STATUS_ERROR);
}
finally {
out.close();
}
STATUS_DL, STATUS_OK e STATUS_ERROR são constantes definidas por mim. O problema é que quando o cliente cancela a transferência, o arquivo está ficando com STATUS_OK.
Em meus testes locais conectando direto ao tomcat, a Exception era lançada e o arquivo marcado com STATUS_ERROR. Agora as hipóteses:
- Apache e mod_jk estão obfuscando o que aconteceu com o cliente
- O tomcat está lendo o arquivo inteiro muito rápido (o servidor é um quad xeon com 4gb ram) e marca o STATUS_OK mesmo sem ele ter recebido o arquivo todo (depois que o cliente desconecta). O estranho é que durante o download ele fica marcado com STATUS_DL.
Agora finalmente: Alguém sabe o que pode ser feito ? Talvez algum método do (pensei algo do tipo out.flush) que me assegure que o cliente recebeu aquele pedaço do arquivo (existe esse tipo de verificação no http?).
Desde já agradeço qualquer comentário
Abraços
gui