Carregar blobs como o upload em várias partes causa net :: ERR_FILE_NOT_FOUND no Chrome após 500mb
Estou tendo um problema muito estranho apenas no Google Chrome e Chromium.
O fundo é:
Carrego arquivos no meu servidor usando o método de upload em várias partes, o que significa que divido os arquivos em partes de 10mb e envio cada parte ao servidor. Isso funciona perfeitamente em todos os navegadores com arquivos de qualquer tamanho, o problema começou quando eu precisava criptografar cada pedaço.
Para criptografia, eu uso o CryptoJS e, antes de fazer o upload do pedaço, eu o criptografo e obtenho o resultadoBlob
para carregar, isso funciona bem no Chrome quando tenho que carregar menos de 50 pedaços (50 blobs, cerca de 500mb no total), depois disso recebo umPOST http://(...) net::ERR_FILE_NOT_FOUND
.
Estranhamente, isso funciona em todos os outros navegadores, incluindo o Opera, que é basicamente o Chrome atualmente, exceto o Chrome e o Chromium. Eu testei no IE, Firefox, Edge, Safari, Opera, Chrome e Chromium.
Abaixo, você pode ver como meu código funciona, para que vocês possam ter uma ideia. Esse não é o código real que eu uso no aplicativo, mas sim, é um código de teste que escrevi que produz o mesmo resultado.
Em vez de obter uma fatia (File.slice
) do arquivo que eu vou enviar como um pedaço e criptografá-lo para obter oblob
, Eu vou gerar um falsoblob
com o tamanho do meu pedaço. eu ponho osetTimeout
para simular o tempo necessário para criptografar um blob. Como eu disse antes, obtenho o mesmo resultado que meu código real ao fazer o seguinte:
function uploadNext(prevResponse) {
if (currentPart == totalPartsFile)
return;
//var chunk = getNextChunk();
var totalSize = file.size;
setTimeout(function() {
var blob = new Blob([new ArrayBuffer(constants.chunkSize)], {
type: 'application/octet-string',
name: file.name
});
console.log(blob);
blob.encrypted = true;
blob.key = encryptionKey;
blob.mimeType = file.mimeType;
blob.name = file.name;
blob.originalFileSize = originalFileSize || file.size;
uploadFile(objectId, currentPart, blob, totalSize, prevResponse, function(resp) {
uploadNext(resp);
});
}, 1000);
}
Então, o código acima é onde meu blob é gerado, abaixo está a parte do upload:
function uploadFile (objectId, index, blob, totalSize, prevResponse, callback) {
var format = "encrypted";
var params = "?format=" + format + (format === "encrypted" ? "&encoding=base64" : "");
var endPoint = constants.contentServiceUrl + resourceService.availableResources.addContents.link.split(':objectId').join(objectId) + params;
var formData = new FormData();
formData.append("totalFileSizeBytes", totalSize);
formData.append("partIndex", index);
formData.append("partByteOffset", previousOffset);
formData.append("chunkSize", blob.size);
formData.append("totalParts", totalPartsFile);
formData.append("filename", blob.name);
if (currentPart != 0) {
formData.append("uploadId", prevResponse.uploadId);
formData.append("bucket", prevResponse.bucket);
}
if (finalChunk) {
for (var key in etags1) {
formData.append("etags[" + key + "]", etags1[key]);
}
}
formData.append("data", blob);
previousOffset += blob.size;
var request = {
method: 'POST',
url: endPoint,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
}
$http(request)
.success(function(d) {
_.extend(etags1, d.etags);
console.log(d);
callback(d);
})
.error(function(d) {
console.log(d);
});
}
Claro que existem outras variáveis e códigos de suporte que eu não coloquei aqui, mas isso é suficiente para dar uma idéia do que estamos lidando.
Neste exemplo, estou usando AngularJS '$http
módulo, mas eu tentei com puroXMLHttpRequest
também e obtive o mesmo resultado.
Como eu disse, eu só recebo oPOST http://(...) net::ERR_FILE_NOT_FOUND
com arquivos maiores que 499mb (mais de 50 pedaços) e apenas no Chrome.
Estou postando isso aqui, enquanto procurava uma solução, mas não consegui encontrar nada relacionado a esse problema. A coisa mais próxima que encontrei na Internet foi esse problema no fórum do projeto Chromium:
https://code.google.com/p/chromium/issues/detail?id=375297
Neste ponto, eu realmente não sei mais o que fazer, então gostaria de saber se alguém já teve um problema semelhante no passado e poderia corrigi-lo de alguma forma.
Obrigado pelas respostas com antecedência.