http reply_from_files permissions on linux

39 views
Skip to first unread message

RdR

unread,
Jan 13, 2016, 1:46:17 AM1/13/16
to SWI-Prolog
I encountered a problem porting http server code from Windows to Linux. 

An example:

% test server
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_files)).
:- use_module(library(http/html_write)).

:- http_handler(root(.), hello,[prefix]).
:- http_handler(root(pages), http_reply_from_files(pages,[]),[prefix]).

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

hello(_Request):-
    reply_html_page(title('Hello World'),[h1('Hello World')]).

The "hello world" is displayed correctly on both Windows and Linux, but a file in the pages directory has problems in Linux.

In Windows, assuming I have a file ("test.htm") in the sub-directory "pages", then the URL http://localhost:8080/pages/test.htm will show the contents of the file.  But on Linux, I get the following error:

Internal server error

No permission to read file `'/test.htm''


The sub-directory "pages" has permission 755 (read and execute) and the file has permission 644 (read).  I've tried other permissions, but still no success.

The test server program is executed from the directory above "pages" by the same user as the owner of the directories, by starting swipl and then loading the program and executing "server." at the prolog command prompt.

Any ideas on how to resolve this?

cheers,

RdR

Jan Wielemaker

unread,
Jan 13, 2016, 3:15:13 AM1/13/16
to RdR, SWI-Prolog
On 01/13/2016 07:46 AM, RdR wrote:
> I encountered a problem porting http server code from Windows to Linux.
>
> An example:
>
> % test server
> :- use_module(library(http/thread_httpd)).
> :- use_module(library(http/http_dispatch)).
> :- use_module(library(http/http_files)).
> :- use_module(library(http/html_write)).
>
> :- http_handler(root(.), hello,[prefix]).
> :- http_handler(root(pages), http_reply_from_files(pages,[]),[prefix]).
>
> server:- http_server(http_dispatch,[port(8080)]).
>
> hello(_Request):-
> reply_html_page(title('Hello World'),[h1('Hello World')]).
>
> The "hello world" is displayed correctly on both Windows and Linux, but
> a file in the pages directory has problems in Linux.
>
> In Windows, assuming I have a file ("test.htm") in the sub-directory
> "pages", then the URL http://localhost:8080/pages/test.htm will show the
> contents of the file. But on Linux, I get the following error:
>
>
> Internal server error
>
> No permission to read file `'/test.htm''
>
>
> The sub-directory "pages" has permission 755 (read and execute) and the
> file has permission 644 (read). I've tried other permissions, but still
> no success.

Read carefully! It says "/test.htm", note the "/". Now I have no clue why
this works on Windows, but you do need a rule like this binding the alias
to a physical location.

user:file_search_path(pages, pages).

If you need to debug this, run ?- tspy(http_reply_from_files). and reload
the page. That should bring up the graphical debugger, allowing you to
inspect the search.


Cheers --- Jan



>
> The test server program is executed from the directory above "pages" by
> the same user as the owner of the directories, by starting swipl and
> then loading the program and executing "server." at the prolog command
> prompt.
>
> Any ideas on how to resolve this?
>
> cheers,
>
> RdR
>
> --
> You received this message because you are subscribed to the Google
> Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to swi-prolog+...@googlegroups.com
> <mailto:swi-prolog+...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/swi-prolog.
> For more options, visit https://groups.google.com/d/optout.

RdR

unread,
Jan 13, 2016, 4:49:06 AM1/13/16
to SWI-Prolog, richard....@gmail.com
Thanks for the speedy reply, Jan.

I tried adding various forms of user:file_search_path.  For example:

% test server
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_files)).
:- use_module(library(http/html_write)).
 
:- http_handler(root(.), hello,[prefix]).
:- http_handler(root(pages), http_reply_from_files(pages,[]),[prefix]).
 
   user:file_search_path(pages, '/media/www/wiki/pages').  % this tries to specify the absolute file path

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

hello(_Request):-
     reply_html_page(title('Hello World'),[h1('Hello World')]).


When I step through tspy, I'm not entirely sure what I'm looking at, but it seems that  the request_uri and the path are both '/pages/test.html' and the path_info is '/test.htm' -- even at the very beginning (the call to http_reply_from_files).  Not sure at what point that would transform to the absolute path.

In any case, it doesn't seem to resolve properly.  Is there some way to specify the locations as relative to root (on the presumption that root is the directory where the server starts from)?

cheers,
RdR

RdR

unread,
Jan 13, 2016, 3:35:26 PM1/13/16
to SWI-Prolog, richard....@gmail.com
Hmm,

Not sure what's going on with "path_info" in the Request.  In the end, I solved it by writing a my own generic file reply, to use instead of reply_from_files:

files(Request):-
    memberchk(path(P),Request),
    atom_pref(P,'/',_,Path),               % support pred to strip leading slash
    ( exists_file(Path) ->
        http_reply_file(Path,[],Request);
        http_404([],Request)
    ),!.

The key predicate here -- http_reply_file -- does much of the same work as reply_from_files (safety checking, mime typing, etc), and so provides a convenient work-around.

Thanks for the help -- the pointer to the path problems in the Request was what I needed.

cheers,

RdR
Reply all
Reply to author
Forward
0 new messages