@@ -529,6 +529,136 @@ defmodule Mint.HTTP1 do
529529 "Use Mint.HTTP.set_mode/2 to set the connection to passive mode"
530530 end
531531
532+ @ doc """
533+ TODO
534+
535+ ## Examples
536+
537+ iex> {:ok, conn} = Mint.HTTP1.connect(:https, "httpbin.org", 443, mode: :passive)
538+ iex> {:ok, conn, ref} = Mint.HTTP1.request(conn, "GET", "/status/user-agent", [], nil)
539+ iex> {:ok, _conn, response} = Mint.HTTP1.recv_response(conn, ref, 5000)
540+ iex> response
541+ %{
542+ status: 201,
543+ headers: [
544+ {"date", ...},
545+ ...
546+ ],
547+ body: "{\\ n \\ "user-agent\\ ": \\ "mint/1.6.2\\ "\\ n}\\ n"
548+ }
549+ """
550+ def recv_response ( conn , ref , timeout ) do
551+ recv_response ( conn , ref , timeout , % { status: nil , headers: [ ] , body: "" } , fn
552+ conn , { :status , status } , acc ->
553+ { :cont , conn , % { acc | status: status } }
554+
555+ conn , { :headers , headers } , acc ->
556+ { :cont , conn , update_in ( acc . headers , & ( & 1 ++ headers ) ) }
557+
558+ conn , { :data , data } , acc ->
559+ { :cont , conn , update_in ( acc . body , & ( & 1 <> data ) ) }
560+
561+ conn , :done , acc ->
562+ { :cont , conn , acc }
563+ end )
564+ end
565+
566+ @ doc """
567+ TODO
568+
569+ ## Examples
570+
571+ iex> {:ok, conn} = Mint.HTTP1.connect(:https, "httpbin.org", 443, mode: :passive)
572+ iex> {:ok, conn, ref} = Mint.HTTP1.request(conn, "GET", "/user-agent", [], nil)
573+ iex> {:ok, _conn, _acc} =
574+ ...> Mint.HTTP1.recv_response(conn, ref, 5000, nil, fn
575+ ...> conn, entry, acc ->
576+ ...> IO.inspect(entry)
577+ ...> {:cont, conn, acc}
578+ ...> end)
579+
580+ Outputs:
581+
582+ {:status, 201}
583+ {:headers, [{"date", ...}, ...]}
584+ {:data, "{\\ n \\ "user-agent\\ ": \\ "mint/1.6.2\\ "\\ n}\\ n"}
585+ :done
586+ """
587+ def recv_response ( conn , ref , timeout , acc , fun ) do
588+ recv_response ( [ ] , acc , fun , conn , ref , timeout )
589+ end
590+
591+ defp recv_response ( [ { :status , ref , status } | rest ] , acc , fun , conn , ref , timeout ) do
592+ case fun . ( conn , { :status , status } , acc ) do
593+ { :cont , conn , acc } ->
594+ recv_response ( rest , acc , fun , conn , ref , timeout )
595+
596+ { :halt , conn , acc } ->
597+ { :ok , conn , acc }
598+
599+ other ->
600+ raise ArgumentError ,
601+ "expected {:cont, conn, acc} or {:halt, conn, acc}, got: #{ inspect ( other ) } "
602+ end
603+ end
604+
605+ defp recv_response ( [ { :headers , ref , headers } | rest ] , acc , fun , conn , ref , timeout ) do
606+ case fun . ( conn , { :headers , headers } , acc ) do
607+ { :cont , conn , acc } ->
608+ recv_response ( rest , acc , fun , conn , ref , timeout )
609+
610+ { :halt , conn , acc } ->
611+ { :ok , conn , acc }
612+
613+ other ->
614+ raise ArgumentError ,
615+ "expected {:cont, conn, acc} or {:halt, conn, acc}, got: #{ inspect ( other ) } "
616+ end
617+ end
618+
619+ defp recv_response ( [ { :data , ref , data } | rest ] , acc , fun , conn , ref , timeout ) do
620+ case fun . ( conn , { :data , data } , acc ) do
621+ { :cont , conn , acc } ->
622+ recv_response ( rest , acc , fun , conn , ref , timeout )
623+
624+ { :halt , conn , acc } ->
625+ { :ok , conn , acc }
626+
627+ other ->
628+ raise ArgumentError ,
629+ "expected {:cont, conn, acc} or {:halt, conn, acc}, got: #{ inspect ( other ) } "
630+ end
631+ end
632+
633+ defp recv_response ( [ { :done , ref } | _ ] , acc , fun , conn , ref , _timeout ) do
634+ case fun . ( conn , :done , acc ) do
635+ { :cont , conn , acc } ->
636+ { :ok , conn , acc }
637+
638+ { :halt , conn , acc } ->
639+ { :ok , conn , acc }
640+
641+ other ->
642+ raise ArgumentError ,
643+ "expected {:cont, conn, acc} or {:halt, conn, acc}, got: #{ inspect ( other ) } "
644+ end
645+ end
646+
647+ defp recv_response ( [ ] , acc , fun , conn , ref , timeout ) do
648+ start_time = System . monotonic_time ( :millisecond )
649+
650+ with { :ok , conn , entries } <- recv ( conn , 0 , timeout ) do
651+ timeout =
652+ if is_integer ( timeout ) do
653+ timeout - System . monotonic_time ( :millisecond ) - start_time
654+ else
655+ timeout
656+ end
657+
658+ recv_response ( entries , acc , fun , conn , ref , timeout )
659+ end
660+ end
661+
532662 @ doc """
533663 See `Mint.HTTP.set_mode/2`.
534664 """
0 commit comments