Can't retract http_session

I’m using: SWI-Prolog version 8.2.1

I want the code to:
retract the http session using http_session_retract.
But what I’m getting is:
Internal server error
My code looks like this:

http_session_assert(check_session(isset)). %creating
http_session_retract(check_session(isset)). %deleting

check_session():

check_session(_) :-
	not(http_session_data(check_session(isset))), !.
	
check_session(Request) :-
	http_redirect(moved, root(user), Request).

So asserting is working, because I get the redirect to /user.
And one another question: how can I see what I have in the session?

Please create a self contained small program so we can see what you are doing precisely. Retracting facts from the session generally works, so there is something specific in what you are doing causing the problem.

So I want to do this: if the session exists, you get a redirect from the index page to /user, and if not - each handler redirects you to the index page. Here is an example.

:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_error)).
:- use_module(library(http/html_write)).
:- use_module(library(http/html_head)).
:- use_module(library(http/http_client)).
:- use_module(library(http/http_session)).

server(Port) :-
        http_server(http_dispatch, [port(Port)]).

:- http_handler(root(.), index_controller, []).
:- http_handler(root(user), user_controller, []).
:- http_handler(root('add-session'), session_controller, []).

index_controller(Request) :-
	check_session(Request),
	format('Content-type: text/html~n~n', []),
	format('Hi!', []).

check_session(Request) :-
	http_session_data(check_session(isset)),
	http_redirect(moved, root(user), Request).
	
user_controller(_Request) :-
	format('Content-type: text/html~n~n', []),
	format('Username here', []).
	
session_controller(_Request) :-
	http_session_assert(check_session(isset)),
	format('Content-type: text/html~n~n', []),
	format('Adding a session', []).

Thanks. That is getting a bit clearer. The index_controller/1 is definitely wrong. First of all, HTTP handlers must succeed: failing or raising an exception is translated into an HTTP error code.

check_session/1 may fail as http_session_data/1 may fail. If this succeeds though, it will redirect and never reach the remainder of index_controller/1.

Hope this helps getting started. What you really want it probably to protect the logged in part of the server using a single handler that has prefix and authentication(Type) set for the root of the protected area. Now any attempt to get to one of the handlers below will call the authentication hook. You can use one of the basic implementations or add your own to deal with the login as you please.

Okay, let me get this straight. For example, I need to protect routes: /user, /user/*, so I set prefix and authentication options like this:

:- http_handler(root(user), user_controller, [authentication(basic), prefix]).

Is that correct?

P.S.
Is it me or the official documentation is written badly? Because I’ve tried to use http_write_passwd_file/2 as the documentation says http_write_passwd_file(+File, +Data:list):

index_controller(_Request) :-
	http_write_passwd_file(passwd, [user, \crypt('12345')]).

And I get this: Type error: 'passwd_entry' expected, found 'user' (an atom)
What is wrong with parameters?

Sorry I never used http_write_passwd_file/2, but docs seems pretty clear to me: Data is a list of entries as ... passwd(User, Hash, Fields).

When in doubt, you can inspect the inlined source code of the predicate clicking on the :- orange button after the determinacy specifier ([det] here).

Yes. That is, if you want classical HTTP authentication.

The description of Data is a bit clear. Why there is no information about File? How should I write the path to the file? Is it an absolute or abstract path? I’ve always written imperative code and used official websites for infromation. But now it’s so hard for me to understand this logic.

Thank you for your answer. Could you please tell me what I am doing wrong with http_write_passwd_file?

You find an example in the SWISH code, e.g. https://github.com/SWI-Prolog/swish/blob/c0e750f9cc569031f91bee18733c292fa5ce5fb5/lib/plugin/http_authenticate.pl#L297