[Answer]-Django – HTTPStream of gzip file creaed on the fly

1πŸ‘

βœ…

I found the solution to both problems, the handler that was supposed to be passed to the HTTPStream is the StringIO one, not the Gzip handler, also the StringIO handler is seekable so that way I can check the size of the data after gzipped, another trick is to call the close method on the gzip handler so it will add the crc32 and size to the gzip file otherwise the data sent will be 0, for the StringIO don’t call the close method, because the HTTPStream will need the handler open to stream the data, the garbage collector will close it after the Stream is done.

This is the final code:

# Use cStringIO to create the file on the fly
cebd_xml_file = StringIO.StringIO()

# Create the file name ...
base_file_name = "cebd"

# Get the XML String
xml_string = get_xml_cebd(cebds)

# Create the Gzip file handler, with the StringIO in the fileobj
gzip_handler = gzip.GzipFile(
    fileobj=cebd_xml_file,
    filename=base_file_name + '.xml',
    mode='wb'
)

# Write the XML data into the gziped file
gzip_handler.write(xml_string)

# Flush the data
gzip_handler.flush()

# Close the Gzip handler, the close method will add the CRC32 and the size
gzip_handler.close()

# Generate the response using the file warpper, content type: x-gzip
# Since this file can be big, best to use the StreamingHTTPResponse
# that way we can garantee that the file will be sent entirely
response = StreamingHttpResponse(
    cebd_xml_file.getvalue(),
    content_type='application/x-gzip'
)

# Add content disposition so the browser will download the file, don't use mime type !
response['Content-Disposition'] = ('attachment; filename=' +
    base_file_name + '.xml.gz')

# Content size
cebd_xml_file.seek(0, os.SEEK_END)
response['Content-Length'] = cebd_xml_file.tell()

# Send back the response to the request, don't close the StringIO handler !
return response

Cheers, hope this can help anyone.

πŸ‘€e-nouri

Leave a comment