zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

parse.ex (2514B)


      1 defmodule Mint.HTTP1.Parse do
      2   @moduledoc false
      3 
      4   alias Mint.Core.Util
      5 
      6   defmacro is_digit(char), do: quote(do: unquote(char) in ?0..?9)
      7   defmacro is_alpha(char), do: quote(do: unquote(char) in ?a..?z or unquote(char) in ?A..?Z)
      8   defmacro is_whitespace(char), do: quote(do: unquote(char) in '\s\t')
      9   defmacro is_comma(char), do: quote(do: unquote(char) == ?,)
     10   defmacro is_vchar(char), do: quote(do: unquote(char) in 33..126)
     11 
     12   defmacro is_tchar(char) do
     13     quote do
     14       is_digit(unquote(char)) or is_alpha(unquote(char)) or unquote(char) in '!#$%&\'*+-.^_`|~'
     15     end
     16   end
     17 
     18   def ignore_until_crlf(<<>>), do: :more
     19   def ignore_until_crlf(<<"\r\n", rest::binary>>), do: {:ok, rest}
     20   def ignore_until_crlf(<<_char, rest::binary>>), do: ignore_until_crlf(rest)
     21 
     22   def content_length_header(string) do
     23     case Integer.parse(String.trim_trailing(string)) do
     24       {length, ""} when length >= 0 -> {:ok, length}
     25       _other -> {:error, {:invalid_content_length_header, string}}
     26     end
     27   end
     28 
     29   def connection_header(string) do
     30     split_into_downcase_tokens(string)
     31   end
     32 
     33   def transfer_encoding_header(string) do
     34     split_into_downcase_tokens(string)
     35   end
     36 
     37   defp split_into_downcase_tokens(string) do
     38     case token_list_downcase(string) do
     39       {:ok, []} -> {:error, :empty_token_list}
     40       {:ok, list} -> {:ok, list}
     41       :error -> {:error, {:invalid_token_list, string}}
     42     end
     43   end
     44 
     45   # Made public for testing.
     46   def token_list_downcase(string), do: token_list_downcase(string, [])
     47 
     48   defp token_list_downcase(<<>>, acc), do: {:ok, :lists.reverse(acc)}
     49 
     50   # Skip all whitespace and commas.
     51   defp token_list_downcase(<<char, rest::binary>>, acc)
     52        when is_whitespace(char) or is_comma(char),
     53        do: token_list_downcase(rest, acc)
     54 
     55   defp token_list_downcase(rest, acc), do: token_downcase(rest, _token_acc = <<>>, acc)
     56 
     57   defp token_downcase(<<char, rest::binary>>, token_acc, acc) when is_tchar(char),
     58     do: token_downcase(rest, <<token_acc::binary, Util.downcase_ascii_char(char)>>, acc)
     59 
     60   defp token_downcase(rest, token_acc, acc), do: token_list_sep_downcase(rest, [token_acc | acc])
     61 
     62   defp token_list_sep_downcase(<<>>, acc), do: {:ok, :lists.reverse(acc)}
     63 
     64   defp token_list_sep_downcase(<<char, rest::binary>>, acc) when is_whitespace(char),
     65     do: token_list_sep_downcase(rest, acc)
     66 
     67   defp token_list_sep_downcase(<<char, rest::binary>>, acc) when is_comma(char),
     68     do: token_list_downcase(rest, acc)
     69 
     70   defp token_list_sep_downcase(_rest, _acc), do: :error
     71 end