The handler (e.g., home_page/1 above) is called with the 
parsed request (see section 3.13) as 
argument and
current_output set to a temporary buffer. Its task is 
closely related to the task of a CGI script; it must write a header 
declaring at least the Content-type field and a body. Below 
is a simple body writing the request as an HTML table.3Note 
that writing an HTML reply this way is deprecated. In fact, the code is 
subject to injection attacks as the HTTP request field values 
are literally injected in the output while HTML reserved characters 
should be properly escaped.
reply(Request) :-
        format('Content-type: text/html~n~n', []),
        format('<html>~n', []),
        format('<table border=1>~n'),
        print_request(Request),
        format('~n</table>~n'),
        format('</html>~n', []).
print_request([]).
print_request([H|T]) :-
        H =.. [Name, Value],
        format('<tr><td>~w<td>~w~n', [Name, Value]),
        print_request(T).
The infrastructure recognises the header fields described below. 
Other header lines are passed verbatim to the client. Typical examples 
are
Set-Cookie and authentication headers (see section 
3.7).
text/* or the type matches with UTF-8 
(case insensitive), the server uses UTF-8 encoding. The user may force 
UTF-8 encoding for arbitrary content types by adding ; 
charset=UTF-8 to the end of the Content-type header.chunked option in http_handler/3.Status header to force 
a
redirect response to the given URL. The message body 
must be empty. Handling this header is primarily intended for 
compatibility with the CGI conventions. Prolog code should use
http_redirect/3.Location, where Status 
must be one of 301 (moved), 302 (moved temporary, default) or 303 (see 
other). Using the status field also allows for formulating replies such 
as 201 (created).
Note that the handler may send any type of document instead of HTML. 
After the header has been written, the encoding of the
current_output stream encoding is established as follows:
text/* the stream is switched to 
UTF-8 encoding. If the content type does not provide attributes, ; charset=UTF-8 
is added.UTF-8 the stream is switched 
to UTF-8 encoding.http_header. The current list deals with JSON, Turtle 
and SPARQL.
Besides returning a page by writing it to the current output stream, 
the server goal can raise an exception using throw/1 
to generate special pages such as not_found, moved, 
etc. The defined exceptions are:
http_reply(Reply, HdrExtra,[]).http_reply(Reply, [],[]).http_reply(not_modified,[]). This exception 
is for backward compatibility and can be used by the server to indicate 
the referenced resource has not been modified since it was requested 
last time.
In addition, the normal "200 OK" reply status may be 
overruled by writing a CGI Status header prior to the 
remainder of the message. This is particularly useful for defining REST 
APIs. The following handler replies with a "201 Created" 
header:
handle_request(Request) :-
        process_data(Request, Id),      % application predicate
        format('Status: 201~n'),
        format('Content-type: text/plain~n~n'),
        format('Created object as ~q~n', [Id]).