.. index:: single: http_client_core
.. _http_client_core/0:

.. rst-class:: right

**object**

``http_client_core``
====================

Portable stream-based HTTP client core predicates.

| **Availability:** 
|    ``logtalk_load(http_client_core(loader))``

| **Author:** Paulo Moura
| **Version:** 1:0:0
| **Date:** 2026-07-08

| **Compilation flags:**
|    ``static, context_switching_calls``


| **Imports:**
|    ``public`` :ref:`http_message_helpers <http_message_helpers/0>`
| **Uses:**
|    :ref:`http_core <http_core/0>`
|    :ref:`list <list/0>`

| **Remarks:**

   - Binary streams: All stream predicates expect binary input and output streams.
   - Per-message primitives: The ``write_request/2``, ``read_response/2``, and ``exchange/4`` predicates process a single HTTP exchange.
   - Connection sequence: The ``exchange_sequence/4`` predicate performs sequential exchanges on the same stream pair while HTTP persistence rules allow it.

| **Inherited public predicates:**
|    (none)

.. contents::
   :local:
   :backlinks: top

Public predicates
-----------------

.. index:: write_request/2
.. _http_client_core/0::write_request/2:

``write_request/2``
^^^^^^^^^^^^^^^^^^^

Writes exactly one normalized HTTP request term to a binary stream.

| **Compilation flags:**
|    ``static``

| **Template:**
|    ``write_request(Output,Request)``
| **Mode and number of proofs:**
|    ``write_request(+stream,+compound)`` - ``one_or_error``

| **Exceptions:**
|    ``Request`` is not a valid normalized HTTP request term:
|        ``domain_error(http_request,Request)``
|    The generated request violates normalized HTTP request semantics:
|        ``domain_error(http_header_semantics,Header)``
|    The generated request properties violate normalized HTTP request semantics:
|        ``domain_error(http_property_semantics,Property)``


------------

.. index:: read_response/2
.. _http_client_core/0::read_response/2:

``read_response/2``
^^^^^^^^^^^^^^^^^^^

Reads exactly one HTTP response from a binary stream and returns it as a normalized response term. Fails on clean end-of-file before reading any bytes. Responses may be status-bodyless, Content-Length framed, Transfer-Encoding chunked, or close-delimited by end-of-file. Close-delimited responses are annotated with a ``body_framing(close_delimited)`` property.

| **Compilation flags:**
|    ``static``

| **Template:**
|    ``read_response(Input,Response)``
| **Mode and number of proofs:**
|    ``read_response(+stream,--compound)`` - ``zero_or_one``

| **Exceptions:**
|    The input stream does not contain a valid normalized HTTP response message:
|        ``domain_error(http_response_stream,malformed_response(Bytes))``


------------

.. index:: exchange/4
.. _http_client_core/0::exchange/4:

``exchange/4``
^^^^^^^^^^^^^^

Writes one normalized request to a binary output stream and then reads one normalized response from a binary input stream.

| **Compilation flags:**
|    ``static``

| **Template:**
|    ``exchange(Input,Output,Request,Response)``
| **Mode and number of proofs:**
|    ``exchange(+stream,+stream,+compound,--compound)`` - ``one_or_error``

| **Exceptions:**
|    ``Request`` is not a valid normalized HTTP request term:
|        ``domain_error(http_request,Request)``
|    The generated request violates normalized HTTP request semantics:
|        ``domain_error(http_header_semantics,Header)``
|    The generated request properties violate normalized HTTP request semantics:
|        ``domain_error(http_property_semantics,Property)``
|    The input stream ends before a complete response is read:
|        ``domain_error(http_response_stream,unexpected_end_of_file)``
|    The input stream does not contain a valid normalized HTTP response status line:
|        ``domain_error(http_response_stream,malformed_status_line(Bytes))``
|    The input stream contains an unsupported response transfer encoding:
|        ``domain_error(http_response_stream,unsupported_transfer_encoding(Encodings))``
|    The input stream contains an invalid response line ending:
|        ``domain_error(http_response_stream,invalid_line_ending(CarriageReturn,LineFeed))``
|    The input stream contains a bare line feed:
|        ``domain_error(http_response_stream,bare_line_feed)``
|    The input stream does not contain a valid normalized HTTP response message:
|        ``domain_error(http_response_stream,malformed_response(Bytes))``
|    The response declares an invalid content length:
|        ``domain_error(non_negative_integer,Length)``


------------

.. index:: exchange_sequence/4
.. _http_client_core/0::exchange_sequence/4:

``exchange_sequence/4``
^^^^^^^^^^^^^^^^^^^^^^^

Performs a sequence of request-response exchanges on the same binary stream pair. If additional requests remain when HTTP persistence rules require connection closure, an error is thrown.

| **Compilation flags:**
|    ``static``

| **Template:**
|    ``exchange_sequence(Input,Output,Requests,Responses)``
| **Mode and number of proofs:**
|    ``exchange_sequence(+stream,+stream,++list(compound),--list(compound))`` - ``one_or_error``

| **Exceptions:**
|    ``Requests`` is not a valid list of normalized HTTP request terms:
|        ``domain_error(http_client_connection,Requests)``
|    A request in ``Requests`` is not a valid normalized HTTP request term:
|        ``domain_error(http_request,Request)``
|    HTTP persistence requires the connection to close while requests remain to be exchanged:
|        ``domain_error(http_client_connection,remaining_requests(Requests))``


------------

Protected predicates
--------------------

(no local declarations; see entity ancestors if any)

Private predicates
------------------

(no local declarations; see entity ancestors if any)

Operators
---------

(none)

