Battling to understand abstract paths

With the web application tutorial I’ve been developing slowly at https://github.com/roblaing/swipl-webapp-howto I’ve been battling to understand abstract paths.

In unit 1 and unit 5 I have nearly exactly the same basic code:

:- 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/http_files)).
:- use_module(library(http/http_unix_daemon)).

:- initialization http_daemon.

:- multifile http:location/3.
:- dynamic   http:location/3.
http:location(files, root(files), []).
user:file_search_path(folders, library('images/styles/scripts')).

:- http_handler(root(.),     http_reply_from_files('.', [indexes(['./index.html'])]), [prefix]).
:- http_handler(root(about), http_reply_from_files('.', [indexes(['./about.html'])]), [prefix]).
:- http_handler(files(.),    http_reply_from_files(folders, []), [prefix]).
:- http_handler(root(user/User), my_handler_code(User), []).

Whereas in unit 1 the server sees the file in /styles, in unit 5 I can’t get the server to see the graphics in /images

What am I doing wrong?

I think this should be folders('.')

1 Like

Still no luck with the code in unit 5 which now looks like this (but gives a 404 Not Found error for http://localhost:3030/images/01d.png

My code (nearly identical to the previous for unit 1) looks like this:

:- 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/http_files)).
:- use_module(library(http/http_unix_daemon)).
:- use_module(library(http/http_open)).
:- use_module(library(http/http_ssl_plugin)).
:- use_module(library(http/json)).
:- use_module(library(sgml)).
:- use_module(library(xpath)).

:- initialization http_daemon.

:- multifile http:location/3.
:- dynamic   http:location/3.
http:location(files, root(files), []).
user:file_search_path(folders, library('images/styles/scripts')).

:- http_handler(root(.), weatherapp_json, []).
:- http_handler(root(xml), weatherapp_xml, []).
:- http_handler(files(.), http_reply_from_files(folders('.'), []), [prefix]).

I don’t know what unit 5 is. But, you ask for /images/01d.png, while you only have handles for /, /xml and /files/*

Note that you can do ?- edit('/images/01d.png).` to edit the handler serving this page. You can then set break/spy points. In this case it probably tells you there is nothing to edit though as no path matches.

1 Like

But shouldn’t

:- http_handler(files(.), http_reply_from_files(folders('.'), []), [prefix]).

serve everything in the directories listed in

user:file_search_path(folders, library('images/styles/scripts')).?

Yes, but the handler is associated with the HTTP location files(.), which is an alias for root(files) and thus (by default) /files/*. You ask for ‘/images/*’

1 Like

Many thanks for the prompt reply Jan.

To get the three directories I want to split my web application into, I’ve deleted user:file_search_path(folders, library('images/styles/scripts')). and used the following code:

:- multifile http:location/3.
:- dynamic   http:location/3.
http:location(images, root(images), []).
http:location(styles, root(styles), []).
http:location(scripts, root(scripts), []).

:- http_handler(images(.), http_reply_from_files('./images', []), [prefix]).
:- http_handler(styles(.), http_reply_from_files('./styles', []), [prefix]).
:- http_handler(scripts(.), http_reply_from_files('./scripts', []), [prefix]).