mochi / mochiweb

MochiWeb is an Erlang library for building lightweight HTTP servers.
Other
1.86k stars 474 forks source link

Remove leading and trailing whitespaces #247

Closed big-r81 closed 2 years ago

big-r81 commented 2 years ago

from field-values to be RFC 7230 compliant.

Fix #246

etrepum commented 2 years ago

On closer read the trim_and_reverse implementation does not quite do what we want here, but something like this might perform better than a regex:

-define(IS_WHITESPACE(C),
        (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)).

is_whitespace(C) ->
    ?IS_WHITESPACE(C).

trim_leading_and_trailing_ws(S) ->
    trim_trailing_ws(lists:dropwhile(fun is_whitespace/1, S), [], 0).

trim_trailing_ws([C | Rest], Acc, N) when ?IS_WHITESPACE(C) ->
    trim_trailing_ws(Rest, [C | Acc], 1 + N);
trim_trailing_ws([C | Rest], Acc, N) ->
    trim_trailing_ws(Rest, [C | Acc], 0);
trim_trailing_ws([], Acc, N) ->
    lists:reverse(lists:nthtail(Acc, N)).
big-r81 commented 2 years ago

On closer read the trim_and_reverse implementation does not quite do what we want here, but something like this might perform better than a regex:

But 2 timestrim_and_reverse would work too and it seems it's the fasted way to get our solution!

1> mochiweb_headers_playground:test().
T1 (trim_leading_and_trailing_ws)  : 13.43003
T2 (trim_and_reverse)              : 0.404285
T3 (trim_leading_and_trailing_ws_2): 0.609125

I made a small playground file which can be used to test this (with all your work and ideas)!

So, let us use the following?

trim_and_reverse(S) ->
    trim_and_reverse(trim_and_reverse(S, false), false).
etrepum commented 2 years ago

I'll merge this and apply the suggestions (a test and more performant implementation) in a follow-up