Newbie questions about Pliant

Newbie questions about Pliant

keep-alive connections

WWW::Mechanize automation
Message posted by maybe Boris Reitman on 2006/09/22 23:56:46

I don't have a concrete example, just wonder if you have any quick thoughs 
on this issue.  The svar code works fine with ie and mozilla, but 
with WWW::Mechanize something is funny. I suspect it is with the way connections are managed.
WWW::Mechanize doesn't send "Connection: keep-alive",
but I read that this is not required when talking to HTTP/1.1 servers.  

What happents is that the "if" in cookie.pli replace_http_headers that checks the size of the stream 
fails all the time, and the cookie is not set.  
I tried adding the cookie to answer_extra field in HttpRequest, and when I dump the 
values in answer_extra in server.pli:send_header routine they don't show up.
It makes me think that I am updating an HttpRequest object that is not initialized
properly or one that will not be used for sending response.  Could the reason be that 
the handler for svar be invoked in one thread/connection but the response sent 
in another thread/connection ?

In any case, the replace_http_header in cookie.pli that you have suggested seems like 
a hack, do you think using answer_extra is better/cleaner ?

    var Str cookie := "Set-Cookie: " + cookie_name + "=" + cookie_value + "; expires=" + expires_date + "; path=" + path    
    page:http_request:answer_extra append addressof:(new Str cookie)

Also, I am a bit confused: the HttpRequest:stream field represents a response or request ?  
If response, then what is the use of HttpRequest:answer_stream
Usually one would expect in a server implemention to find a response and request object,
but in Pliant's case, there is only request object. Does this choice reflect the fact 
that you use keep-alive connections and the request object represent a union of 
communication over time ?

Message posted by hubert.tonneau on 2006/09/23 00:33:05
> What happents is that the "if" in cookie.pli replace_http_headers that checks
> the size of the stream fails all the time

The default size for a Pliant stream buffer is 4 KB.
So, we when you call 'set_cookie', there is already nearly 4 KB pending.
Seems strange to me. Might be that you are sending a lot of CSS informations.
Just try to dump the HTTP answer buffer to see what is consuming so much.

> In any case, the replace_http_header in cookie.pli that you have suggested seems like 
> a hack, do you think using answer_extra is better/cleaner ?

The problem is when do you call 'set_cookie' ?
If you call it when executing the .page code, the the HTTP answer header has
already been pushed to the output stream buffer.
Using 'answer_extra' is cleaner, but can be done only when the HTTP answer
header has not been pushed yet.

> Also, I am a bit confused: the HttpRequest:stream field represents a response or request ?

A Pliant stream is bidirectionnal, so it can be both the request and the answer.
Also, the answer might be encoded, so 'HttpRequest:stream' is the real answer
stream, and 'HttpRequest:answer_stream' is a filtering stream that will apply
encoding and push the encoded content to 'HttpRequest:stream'
Message posted by maybe Boris Reitman on 2006/09/23 01:42:56
You are right, the buffer is full at 4k. For some reason the first buffer doesn't 
start with HTTP headers.  I am calling set_cookie already too late.  The first 
I am calling set_cookie at the right time is in buffer_14.txt.

Here's the code I used to dump the buffer:

gvar Int XXX := 0
method p replace_http_header replace with -> status
  arg_rw HtmlPage p ; arg Str replace with ; arg Status status
  var Pointer:Stream stream :> p:http_request stream
  var Address start := stream stream_write_buf
  var Address cur := stream stream_write_cur
  var Address stop := stream stream_write_stop

  console "Buffer: " eol
  var Stream f
  f open "file:/tmp/buffer_"+string:XXX+".txt" out
  XXX := XXX + 1
  var Address x := start
  while x <> stop
    var Str s 
    s set x 1 false
    x := x translate Byte 1
    f writechars s
  f close  
  if (cast stop Int).-.(cast cur Int) >= with:len-replace:len  
I only kept those buffer_X.txt files that are different.

Message posted by hubert.tonneau on 2006/09/23 02:01:44
Avoid sending so much with each page.
If you want to use CSS, use an external one instead.
Message posted by maybe Boris Reitman on 2006/09/23 11:19:34
Its not CSS, its just strait up html. my CSS is external.
I send keywords with every page, they take a lot.  But thats how a 
todays websites are.
Message posted by hubert.tonneau on 2006/09/23 12:07:57
So the problem is probably that you use 'svar' too late, I mean your .page
already sent too much before discovering that it will need a session
Either you write your style that will handle the session notion right
from the beginning of any page, or you move your 'svar' variables
declarations at the top of the page,
or you write kind of meta to add the proper code in front of the page
when some 'svar' is used. Also it would still have a problem if the 'svar'
in not in the .page but in an external function called.
Message posted by maybe Boris Reitman on 2006/09/23 21:45:39
Ok, this makes sense. The only thing I don't understand is why his doesn't happen
with IE and Mozilla, but only with WWW::Mechanize.