   @crlf "\r\n"
 
   @doc """
+  # NOTE set_body should add content-length otherwise we don't know if to delete it to match on other end, when serializing
+
   ## Examples
       iex> request = Raxx.request(:GET, "http://example.com/path?qs")
       ...> |> Raxx.set_header("accept", "text/plain")

      # "HTTP/1.1 200 OK\\r\\ncontent-length: 13\\r\\ncontent-type: text/plain\\r\\n\\r\\n"
      ...> body
      {:bytes, 13}

      > A server MUST NOT send a Content-Length header field in any response
      > with a status code of 1xx (Informational) or 204 (No Content).  A

    headers = [{"host", request.authority}] ++ payload_headers ++ request.headers
    head = [start_line(request), header_lines(headers), @crlf]
    {head, body}
  end

  @doc """
  ## Examples

      iex> "GET /path?qs HTTP/1.1\\r\\nhost: example.com\\r\\naccept: text/plain\\r\\n\\r\\n"
      ...> |> Raxx.HTTP1.parse_request()
      {:ok,
       %Raxx.Request{
         authority: "example.com",
         body: false,
         headers: [{"accept", "text/plain"}],
         method: :GET,
         mount: [],
         path: ["path"],
         query: "qs",
         raw_path: "/path",
         scheme: :http
       }, {:complete, ""}, ""}

      iex> "POST /path HTTP/1.1\\r\\nhost: example.com\\r\\ntransfer-encoding: chunked\\r\\ncontent-type: text/plain\\r\\n\\r\\n"
      ...> |> Raxx.HTTP1.parse_request()
      {:ok,
       %Raxx.Request{
         authority: "example.com",
         body: true,
         headers: [{"content-type", "text/plain"}],
         method: :POST,
         mount: [],
         path: ["path"],
         query: nil,
         raw_path: "/path",
         scheme: :http
       }, :chunked, ""}

      iex> "POST /path HTTP/1.1\\r\\nhost: example.com\\r\\ncontent-length: 13\\r\\n\\r\\n"
      ...> |> Raxx.HTTP1.parse_request()
      {:ok,
       %Raxx.Request{
         authority: "example.com",
         body: true,
         headers: [{"content-length", "13"}],
         method: :POST,
         mount: [],
         path: ["path"],
         query: nil,
         raw_path: "/path",
         scheme: :http
       }, {:bytes, 13}, ""}

      iex> "GET /path?qs HT"
      ...> |> Raxx.HTTP1.parse_request()
      {:more, "GET /path?qs HT"}

      iex> "GET /path?qs HTTP/1.1\\r\\nhost: exa"
      ...> |> Raxx.HTTP1.parse_request()
      {:more, "GET /path?qs HTTP/1.1\\r\\nhost: exa"}

  """
  def parse_request(buffer, scheme \\ :http) do
    case :erlang.decode_packet(:http_bin, buffer, []) do
      {:ok, {:http_request, method, {:abs_path, path_and_query}, _version}, rest} ->
        case parse_headers(rest) do
          {:ok, headers, rest2} ->
            case Enum.split_with(headers, fn {key, _value} -> key == "host" end) do
              {[{"host", host}], headers} ->
                {headers, body, state} = decode_payload(headers)

                request =
                  Raxx.request(method, path_and_query)
                  |> Map.put(:scheme, scheme)
                  |> Map.put(:authority, host)
                  |> Map.put(:headers, headers)
                  |> Map.put(:body, body)

                {:ok, request, state, rest2}
            end

          {:more, :undefined} ->
            {:more, buffer}
        end

      {:more, :undefined} ->
        {:more, buffer}
    end
  end

  defp parse_headers(buffer, headers \\ []) do
    case :erlang.decode_packet(:httph_bin, buffer, []) do
      {:ok, :http_eoh, rest} ->
        {:ok, Enum.reverse(headers), rest}

      {:ok, {:http_header, _, key, _, value}, rest} ->
        parse_headers(rest, [{String.downcase("#{key}"), value} | headers])

      {:more, :undefined} ->
        {:more, :undefined}
    end
  end

  @doc """
