Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Prolog Web Services 0.1 (alpha) released

94 views
Skip to first unread message

pic...@alice.it

unread,
Apr 11, 2013, 11:57:48 AM4/11/13
to

I have finally found the time to upload an archive containing some of the material I infrequently developed in these last months.

It is released as alpha software and it is not complete as I would have preferred, but it is otherwise fully functional. It also includes a (limited, which is still better than none :) PlDoc-based documentation and a couple of examples. The major plan for future developments is the possibility to create/modify Prolog programs directly online (i.e. by means of a web-based interface), but much will depend on users' feedback (if any).

It can be found at http://sourceforge.net/projects/prolog-ws/.

I hope you will find it nice to play with.
Any feedback will be greatly appreciated.

Best wishes,
Mauro DiNuzzo


pic...@alice.it

unread,
May 8, 2013, 5:35:08 PM5/8/13
to
While trying to add support for PHP (as CGI process, of course) I realized that in my case the SWI Prolog HTTP server does not recognize "Location: xxx" header.

Conversely, throw(http_reply(moved, xxx)) works as expected.

Any suggestion?

Thank you very much.
Mauro

Jan Wielemaker

unread,
May 9, 2013, 3:49:38 AM5/9/13
to
On 2013-05-08, pic...@alice.it <pic...@alice.it> wrote:
> While trying to add support for PHP (as CGI process, of course) I realized that in my case the SWI Prolog HTTP server does not recognize "Location: xxx" header.

There is a file http_cgi.pl that is part of the SWI-Prolog website
sources (http://www.swi-prolog.org/git/plweb.git), which uses CGI to
run the GIT web frontend. It would be a bit of hacking, but I guess it
should be doable to change the HTTP reply code (that is the problem;
otherwise it just passes the header fields you give it).

> Conversely, throw(http_reply(moved, xxx)) works as expected.

Somewhat cleaner: http://www.swi-prolog.org/pldoc/doc_for?object=http_redirect/3
hides the ugly exception for you.

Cheers --- Jan

pic...@alice.it

unread,
May 9, 2013, 4:55:12 AM5/9/13
to

Sorry for my naive question, but do you mean that "Location: url" will not work if the HTTP reply code is, e.g., 200?

I read somewhere that issuing a "Location: url" header SHOULD automatically set the reply to 302 (if I remember correctly). Isn't it?

PS: I could not download http_cgi.pl. Can you help me?

Thank you so much for the hints.
Mauro

pic...@alice.it

unread,
May 9, 2013, 5:41:25 PM5/9/13
to

I got http_cgi.pl and I used something in there.

PHP is working fine with SWI Webserver. However, I was unable to solve the HTTP header issue. I do not want any workaround, as in most of the PHP-based software (notably CMS) one finds a lot of "header('Location: url');" which at the moment makes the interface useless.

Suggestions will be appreciated.
Thanks a lot!

pic...@alice.it

unread,
May 9, 2013, 5:50:40 PM5/9/13
to

By the way, I would like to use the "Location" header as in the following:

:- http_server(http_dispatch, [port(80)]).

:- http_handler(root(google), go_to_google, []).

go_to_google(_) :- write('Location: http://www.google.com\n\n').

I am happy with throw(http_reply(moved, url)) or with the more elegant http_redirect(moved, url, Request) but I would like to use the "Location" header with the same nonchalance of most PHP programmers...

Best,
Mauro

pic...@alice.it

unread,
May 10, 2013, 10:44:55 AM5/10/13
to

I solved by adding these lines in my http handler:

...,
current_output(CGI),
cgi_property(CGI, header(Header)),
( memberchk(location(Location), Header)
-> throw(http_reply(moved(Location)))
; true
).

Do you think it can be considered safe?

I hope this could be of help.
All the best,
Mauro

pic...@alice.it

unread,
May 11, 2013, 11:34:47 AM5/11/13
to

I am playing with my new PHP installation under SWI Prolog webserver. It is working quite well. Unfortunately, so far I could not let PhpMyAdmin working.

Anyway, while using Fiddler to monitor HTTP traffic, I noticed that the SWI Prolog server (almost) systematically send "too much" data. I get a violation of the HTTP protocol with respect to Content-Length. Specifically, the server response is 16 bytes longer than indicated in the header. This is not causing any problem, but it would be nice not to see that warning.

Apparently, it seems I am the only wishing to use PHP on the SWI Prolog server... :( I hope not to be the only _using_ the SWI Prolog server. Nonetheless, I will keep you informed on my progresses.

Best wishes,
Mauro

Jan Wielemaker

unread,
May 13, 2013, 3:22:41 PM5/13/13
to
On 2013-05-10, pic...@alice.it <pic...@alice.it> wrote:
>
> I solved by adding these lines in my http handler:
>
> ...,
> current_output(CGI),
> cgi_property(CGI, header(Header)),
> ( memberchk(location(Location), Header)
> -> throw(http_reply(moved(Location)))
> ; true
> ).
>
> Do you think it can be considered safe?

Yes. Considering the situation I think it is better if this was moved
into the standard HTTP handling code. However, even if it is, the above
should work fine.

Cheers --- Jan

Jan Wielemaker

unread,
May 13, 2013, 3:33:48 PM5/13/13
to
On 2013-05-11, pic...@alice.it <pic...@alice.it> wrote:
>
> I am playing with my new PHP installation under SWI Prolog webserver. It is working quite well. Unfortunately, so far I could not let PhpMyAdmin working.
>
> Anyway, while using Fiddler to monitor HTTP traffic, I noticed that the SWI Prolog server (almost) systematically send "too much" data. I get a violation of the HTTP protocol with respect to Content-Length. Specifically, the server response is 16 bytes longer than indicated in the header. This is not causing any problem, but it would be nice not to see that warning.

Do you have a complete example of this behaviour?

> Apparently, it seems I am the only wishing to use PHP on the SWI Prolog server... :( I hope not to be the only _using_ the SWI Prolog server. Nonetheless, I will keep you informed on my progresses.

The server is definitely not designed to be a replacement for Apache.
The basic design is to allow Prolog code to respond to HTTP queries
while maintaining state (i.e., not running Prolog as a CGI script). But
yes, it has facilities to serve static files as these are needed by many
services. CGI support was added as a library for the SWI-Prolog website
to reuse the Perl gitweb code. It seems sensible to add CGI to the HTTP
package.

Cheers --- Jan

pic...@alice.it

unread,
May 13, 2013, 9:50:25 PM5/13/13
to

>
> The server is definitely not designed to be a replacement for Apache.
>
> The basic design is to allow Prolog code to respond to HTTP queries
>
> while maintaining state (i.e., not running Prolog as a CGI script).
>

Yes, I am aware of that. I understand your point and completely agree.

I am just experimenting and the inclusion of PHP was a two-hours diversion.

My primary aim was to develop a web-based front-end for prolog source files (sort of programming over the internet). I am working on it in my free time.

In fact, my original intentions (with respect to this small project) were to publicize Prolog by exploiting popular applications such as "intelligent" CMS (I would call them internet expert systems ;). Too much if one just wish to play...

Ciao,
Mauro

janwie...@gmail.com

unread,
May 15, 2013, 9:33:18 AM5/15/13
to
On Monday, May 13, 2013 9:33:48 PM UTC+2, Jan Wielemaker wrote:
> On 2013-05-11, pic...@alice.it <pic...@alice.it> wrote:

> > Anyway, while using Fiddler to monitor HTTP traffic, I noticed that the SWI Prolog server (almost) systematically send "too much" data. I get a violation of the HTTP protocol with respect to Content-Length. Specifically, the server response is 16 bytes longer than indicated in the header. This is not causing any problem, but it would be nice not to see that warning.

So, added handling of Location (and Status) to the core HTTP server libs.
I tried to reproduce the above, but I failed. Seems this depends on the
specific handler code, the OS, version, ... You'll have to give details
(preferably a fully running example). Preferably make a report on the
SWI-Prolog Bugzilla at http://www.swi-prolog.org/bugzilla/

Cheers --- Jan

pic...@alice.it

unread,
May 15, 2013, 3:23:06 PM5/15/13
to
>
> So, added handling of Location (and Status) to the core HTTP server libs.
>

Thank you so much.

>
> I tried to reproduce the above, but I failed. Seems this depends on the
> specific handler code, the OS, version, ... You'll have to give details
> (preferably a fully running example). Preferably make a report on the
> SWI-Prolog Bugzilla at http://www.swi-prolog.org/bugzilla/
>

Probably it is something that I did because I realized that it only happens with ".psp" files. The good is that now you have a running example ;)

I will try to figure out where is the problem.

A note on the implementation of the server. Why did you choose to send http reply via throw/1? I ask this because I had troubles with normal exception handling and I had to add a rule to intercept http_reply exception. This is by no means criticism, but what was the rationale?

Jan Wielemaker

unread,
May 16, 2013, 7:52:48 AM5/16/13
to
On 2013-05-15, pic...@alice.it <pic...@alice.it> wrote:
>>
>> So, added handling of Location (and Status) to the core HTTP server libs.
>>
>
> Thank you so much.

Comments make things better :-)

> A note on the implementation of the server. Why did you choose to send http reply via throw/1? I ask this because I had troubles with normal exception handling and I had to add a rule to intercept http_reply exception. This is by no means criticism, but what was the rationale?

Hmmm. The HTTP server libs have a long history, starting as a small
hack before there were even threads in SWI-Prolog and incrementally
extended to handle more and more demands. I think there are two reaons.

First of all, one needs the infrastructure to handle exceptions from
the handler anyway to avoid the server from dying and to produce a
sensible error reply.

Second, the default handler writes current output to a special
location. In old versions this was a temporary (memory) file. Now,
if you want tasks such as serving a large plain file, you do not want
the handler to write the content of the file to current_output into
the memory file, compute a header from it and send the memory file to
the client over the socket connection. It just means a lot of memory
usage and needless copying of data. So, instead, you want to serve
the file directly from disk. This implies you want to get out of the
current redirected output mode and do something else. That was
already implemented for dealing with exceptions and thus it seemed
sensible to reuse that code.

The alternative that I didn't see those days is to formulate the
alternative action as a CGI header. Something like

send_file(File) :-
mime_type(File, Type),
format('Content-type: ~w~n', [Type]),
format('Send-file: ~w~n~n', [File]).

This would be more elegant in the sense that I think that exceptions
are called such because they are not supposed to be used as part of
the normal control flow. On the other hand, http_reply_file/3 deals
with these details, and so does http_redirect/3 and http_404/2. These
predicates where introduced to shield the underlying exception
mechanism from the user. A nice bonus is that you can document
predicates and find them.

Cheers --- Jan

P.s. Updated http_cgi.pl on the plweb git repo: documentation and
added a lot more to the CGI environment. Planning to move
this library to the core, so further comments, fixes and
additions are welcome.


pic...@alice.it

unread,
May 16, 2013, 12:33:48 PM5/16/13
to

>
> P.s. Updated http_cgi.pl on the plweb git repo: documentation and
> added a lot more to the CGI environment. Planning to move
> this library to the core, so further comments, fixes and
> additions are welcome.

I'm currently using a modified version of your http_cgi.pl module (you can find it inside my prologws pack, file http_prologws.pl). However, I will be happy to use your own when it will be included in the core.

A first comment on this is that your code don't work for me unless I tell explicitly how many bytes (i.e. content length) to copy from the current request input stream to the input stream of the cgi process.

Furthermore, I always had to use pipe(In) for input stream (not std) regardless of the request method (i.e. presence of data or not).

My knowledge stops here!

Best wishes,
Mauro
0 new messages