Not sure whether we must read the \n
. That would be something for the multipart parser though, not the position logic. That seems fine:
test :-
size_file('winraw.txt', Bytes),
open('winraw.txt', read, S, [type(binary)]),
stream_property(S, position(P0)),
pp(P0),
multipart_open(S, M, [boundary('------------------------2cb10ec902817054')]),
read_line_to_codes(M, Codes),
format('Got \"~s\"~n', [Codes]),
stream_property(S, position(P1)),
pp(P1),
stream_position_data(byte_count, P1, Here),
Left is Bytes-Here,
copy_stream_data(S, current_output, Left),
( at_end_of_stream(S)
-> writeln(ok)
; read_string(S, Rest, Str),
format('Left ~D bytes: ~s~n', [Rest, Str])
).
Running this gives:
?- test.
P0 = '$stream_position'(0,1,0,0)
Got "Content-Disposition: form-data; name="file"; filename="test_attachement.txt""
P1 = '$stream_position'(206,1,0,206)
Content-Disposition: form-data; name="file"; filename="readme.txt"
Content-Type: text/plain
12345
67890
--------------------------2cb10ec902817054--
ok
true.
I.e., we can read the remainder of the body based on the Content-length
.
Right. It is up to the handler to read the request. If you use http_read_data/4 you should be safe. If all goes right this predicate should have read all data. If there is an error, http_wrapper.pl forces the connection to close except for some exceptions that are not really errors, such as switching protocols or reply with a static file.
I think it would be worthwhile to see whether we can handle this more robustly in http_wrapper.pl, i.e., always validate that all data is read if the connection is a keep-alive connection. If there is a lot of data in this case, should we consider closing the connection instead? That is the policy that is implemented by http_open/3: when using a keep-alive connection: if the client has not read all data and it is not much, we read the remainder, else we close the connection.
P.s. The new ChatGPT assistent was of great help. See ChatGPT SWI-Prolog assistent. You need to be careful though as its first answer was completely wrong, claiming http_wrapper.pl was dealing with all of this … After pointing at the non-existence of claimed predicates and asking it to re-read the source it came with a quite adequate answer!