I am running a Python HTTP server that host a captive portal. Basically I'm trying to upload a password protected file to the server. Right now I am able to upload files to the server with JavaScript and FileReader. This is how I do it:
var file_cli_cert = document.getElementById(id="exa_cli_cert").files[0];
const xmlhttp1 = new XMLHttpRequest();
let name = file_cert.name;
let reader = new FileReader();
reader.readAsText(file_cert);
xmlhttp1.open("POST", '/load/cert');
reader.onload = function(){
xmlhttp1.send(name "&CERT=" reader.result);
With non-password protected files this works well.
For password protected files my idea is to get the file and the password to access to the data. The problem is that I don't know how to access to password protected files in JS and i think it's not possible. So right now i am wondering how to send the file and the password to the server and access the file data there. If I send the file object with XMLHttpRequest.send(), on the server side I get the object in string format.
To read the POST message, in the server side, I do:
ctype, pdict = cgi.parse_header(self.headers['content-type'])
content_len = int(self.headers.get('Content-length'))
post_body = self.rfile.read(content_len) #read credentials
self.send_response(201)
self.end_headers()
if self.path.endswith('/load/cert'): #if user loads a certificate
post_body = post_body.decode()
post_body = post_body.split("&CERT=") #split name and file content
name_cert = post_body[0]
file_content = post_body[1]
f = open("./certs/" name_cert, "w")
f.write(file_content)
f.close()
I'm a newbie at this and I have been looking for a solution for hours. Any help will be appreciated.
CodePudding user response:
No python expert but reading a encrypted file as Text with FileReader could be problematic as it could lead to some data loss when encoding it as text. You should rather be reading it as binary using reader.readAsArrayBuffer()
But there is no need to read the content of the file into memory and allocate memory, just upload the blob/file directly to the server and it will take care of sending the data from the disc to the network without touching the main javascript thread without any text transformation.
const [ file ] = document.querySelector('#exa_cli_cert').files
fetch('/load/cert', {
method: 'POST',
body: file,
headers: {
'x-file-name': file.name
}
})
.then(r => r.arrayBuffer())