@@ -570,21 +570,49 @@ create_error(StatusCode, Error) ->
570570create_reply (StatusCode , ContentType , Reply ) when is_list (ContentType ) orelse is_binary (ContentType ) ->
571571 create_reply (StatusCode , #{" Content-Type" => ContentType }, Reply );
572572create_reply (StatusCode , Headers , Reply ) when is_map (Headers ) ->
573+ ReplyLen = iolist_length (Reply ),
574+ HeadersWithLen = ensure_content_length (Headers , ReplyLen ),
573575 [
574576 <<" HTTP/1.1 " >>, erlang :integer_to_binary (StatusCode ), <<" " >>, moniker (StatusCode ),
575577 <<" \r\n " >>,
576- io_lib :format (" Server: atomvm-~s \r\n " , [get_version_str (erlang : system_info ( atomvm_version ))]),
577- to_headers_list (Headers ),
578+ io_lib :format (" Server: atomvm-~s \r\n " , [get_version_str (get_atomvm_version ( ))]),
579+ to_headers_list (HeadersWithLen ),
578580 <<" \r\n " >>,
579581 Reply
580582 ].
581583
584+ % % @private
585+ ensure_content_length (Headers , ReplyLen ) ->
586+ LenBin = erlang :integer_to_binary (ReplyLen ),
587+ CleanHeaders = remove_content_length_header (Headers ),
588+ CleanHeaders #{<<" Content-Length" >> => LenBin }.
589+
590+ % % @private
591+ remove_content_length_header (Headers ) ->
592+ KeysToRemove = [
593+ " Content-Length" ,
594+ <<" Content-Length" >>,
595+ " content-length" ,
596+ <<" content-length" >>
597+ ],
598+ lists :foldl (fun (Key , Acc ) -> maps :remove (Key , Acc ) end , Headers , KeysToRemove ).
599+
582600% % @private
583601maybe_binary_to_string (Bin ) when is_binary (Bin ) ->
584602 erlang :binary_to_list (Bin );
585603maybe_binary_to_string (Other ) ->
586604 Other .
587605
606+ % % @private
607+ iolist_length (Bin ) when is_binary (Bin ) ->
608+ erlang :byte_size (Bin );
609+ iolist_length (Int ) when is_integer (Int ), Int >= 0 , Int =< 255 ->
610+ 1 ;
611+ iolist_length ([]) ->
612+ 0 ;
613+ iolist_length ([H | T ]) ->
614+ iolist_length (H ) + iolist_length (T ).
615+
588616% % @private
589617to_headers_list (Headers ) ->
590618 [io_lib :format (" ~s : ~s \r\n " , [maybe_binary_to_string (Key ), maybe_binary_to_string (Value )]) || {Key , Value } <- maps :to_list (Headers )].
@@ -596,6 +624,14 @@ get_version_str(Version) when is_binary(Version) ->
596624get_version_str (_ ) ->
597625 " unknown" .
598626
627+ get_atomvm_version () ->
628+ case catch erlang :system_info (atomvm_version ) of
629+ {'EXIT' , _ } ->
630+ undefined ;
631+ Version ->
632+ Version
633+ end .
634+
599635% % @private
600636moniker (? OK ) ->
601637 <<" OK" >>;
0 commit comments