rla / simple-template

Text templating processor for SWI-Prolog.
Other
32 stars 9 forks source link

How to calculate the length for Content-Length header before sending the entity #19

Open vasily-kartashov opened 3 years ago

vasily-kartashov commented 3 years ago

What is the best, i.e. fast and thread safe way to calculate the length of the rendered entity before sending it to the output. Here's my attempt but it doesn't produce any output in multi-threaded context:

https://github.com/vasily-kartashov/FrameworkBenchmarks/blob/8928cadec95cb94fe80ded0c98fa48c8baeb79a2/frameworks/Prolog/SWI-Prolog/app/server.pl#L55

rla commented 3 years ago

This should not be a responsibility of this library. SWI-Prolog http does buffering and calculates the content-length itselt. If you want to calculate content-length, then it needs to be byte length, not length in code points.

vasily-kartashov commented 3 years ago

I didn't think this is the responsibility of a template library, but I hoped that you could provide an example of how to integrate it with http_server in case one needs an additional Content-Length header.

rla commented 3 years ago

I think it could be calculated by writing the result into memory file and then getting the size of the memory file in binary encoding:

new_memory_file(MemoryFile),
open_memory_file(MemoryFile, write, WriteStream),
st_render_file(Template, Data, WriteStream, _{ cache: true })),
close(WriteStream),
size_memory_file(MemoryFile, ContentLength, binary),
open_memory_file(MemoryFile, read, ReadStream),
format('Content-Length: ~d~n~n', [ContentLength]),
current_output(Output),
copy_stream_data(ReadStream, Output),
close(ReadStream),
free_memory_file(MemoryFile)

This code needs approariate catch/3 calls to properly close the streams and memory file if some network write operation fails.