Re: Error when referencing http_parameters

Jan Wielemaker <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 12/20/2013 03:38 AM, Anne Ogborn wrote:
> Jan - I've had this issue, and now Phillip is finding it awkward. Is
> there some way to make references to http_params idempotic?

Hi Anne,

Yes, I recall this discussion. The problem is that POST data can be
really bulky. The only way I see for implementing this is to store the
entire POSTed form in a global variable on the first call inside a query
and reuse this on possible subsequent calls. Most of the time, you'll
just spend a lot of memory for no good reason :-( Note that you can not
save the _converted_ data, as a subsequent call to http_parameters might
come with different types and defaults. E.g., first you could have asked
for `integer', translating "007" into 7. In the next call you ask for
untranslated, to get '007' (should become "007").

An alternative I see to avoid the confusion is to deprecate using
http_parameters/2,3 for POST requests and add
http_read_post_parameters/2,3 to deal with POST request. The `read'
quite clearly indicates that you can do this only once.

Another alternative might be to set some flag on the first call to
http_parameters/2,3 on a POST request, such that we can raise a clear
exception when trying again. That should also avoid the confusion, but
at a lower price.

We could consider some global variable API, where the variable only
survives the current request (as opposed to session data).  On the
other hand, what is wrong with good old Prolog style:

handler(Request) :-
	http_parameters(Request, [], [ form_data(Form) ]),
	handle(Form, Request).

At some point, the form data will become a dict, so you get all
the nice stuff to select your request processing quickly.  This
could look like:

handler(Request) :-
	http_parameters(Request, [], [ form_dict(Dict) ]),
	process(Dict.put(request, Request)).

process(Dict) :-
	_{user:User, passwd:Passwd} :< Dict, !,
	...
process(Dict) :-
	_{user:User} :< Dict, !,
	...

That would work nice if you handle many different requests on the
same handler, deciding on the action based on a combination of the
provided parameters.  I doubt that is a good design though ...

	Cheers --- Jan

> ________________________________ From: Phillip Soltan
> <[email protected]> To: Anne Ogborn <[email protected]> Sent:
> Thursday, December 19, 2013 4:25 PM Subject: Re: [SWIPL] Error when
> referencing http_parameters
>
>
>
> Hi Anne,
>
> That would explain the problem. �When I change the form request to a
> GET the problem goes away. I would consider it more than a wart
> though. �I need to reuse predicates to avoid cutting-and-pasting the
> same code in different places and this makes it more difficult. �I'll
> have to think of something.
>
> Thanks for you help!
>
> Phillip Soltan
>
>
>
> On Thu, Dec 19, 2013 at 3:40 PM, Anne Ogborn <[email protected]>
> wrote:
>
> yes - with POST the query string type data gets passed in the body of
> the request.�
>> �the post data gets read the first time http_parameters gets
>> called, and the second time it hangs.
>>
>>
>> It's a bit of a wart. 8c/ �
>>
>>
>> change your request to a GET temporarily and see if it clears up.
>> If so, that's your problem.�
>>
>>
>>
>> ________________________________ From: Phillip Soltan
>> <[email protected]> To: [email protected]
>> Sent: Thursday, December 19, 2013 2:18 PM Subject: [SWIPL] Error
>> when referencing http_parameters
>>
>>
>> Hello,
>>
>> I recently discovered that an HTTP package was added to SWI Prolog
>> and I thought this was the perfect solution for me.� Between the
>> documentation, reading the module code and stepping through the
>> modules with the debugger, I think it is going to be suitable for a
>> web site I'm building.
>>
>> I've run into a problem and I'm wondering if someone could help.�
>> I've created a predicate that handles showing the login page:
>>
>> login_page(Request)
> :-
>> html_set_options([dialect('html5')]),
>> (http_session_data(lang(_));http_session_asserta(lang('en'))),
>> (memberchk(method(post),Request) -> http_parameters(Request, � � �
>> � � � � � � � � � [ email(Email_value, [default('empty')]), � � � �
>> � � � � � � � � � password(Pass_value, [default('empty')]) � � � �
>> � � � � � � � � ]); � � � � Email_value = '[email protected]', � � � �
>> Pass_value = 'password' � � ), reply_html_page( [title('Login
>> Page')], � � � � �  ........ snip .......
>>
>> It gets called directly from the handler when there is a GET to the
>> login url (http://localhost/login) and also gets called from the
>> login action predicate:
>>
>> % handle case of invalid email address login_action_page(Request)
>> :- http_parameters(Request, � � � � � � � � � � � � [ email(Email,
>> [default('empty')]), � � � � � � � � � � � � � password(_Pass,
>> [default('empty')]) � � � � � � � � � � � � ]), � �
>> \+epassword(Email,_), � � asserta(login_error('unrecognized
>> email')), login_page(Request).
>>
>>
>> The login_action_page handles the POST request when the submit
>> button is pressed.� It calls login_page to show the login page
>> again showing which field has erroneous data.
>>
>> The POST request times out and return the
> error:
>>
>> *copy_stream_data/3: Timeout in read from <stream>(0x888eaa0)*
>>
>>
>> This is the result of the second call to http_parameters.� I guess
>> my questions are:
>>
>> Why?� Is there some reason I can't call http_parameters twice with
>> the same request?
>>
>>
>> Thank you in advance,
>>
>> Phillip Soltan email: [email protected] -------------- next
>> part -------------- HTML attachment scrubbed and removed
>> _______________________________________________ SWI-Prolog mailing
>> list [email protected]
>> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>>
>>
>>
> -------------- next part -------------- HTML attachment scrubbed and
> removed _______________________________________________ SWI-Prolog
> mailing list [email protected]
> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>

_______________________________________________
SWI-Prolog mailing list
[email protected]
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.