[Cherokee-dev] _step question: I really want to understand something...

Alvaro Lopez Ortega alvaro at gnu.org
Sun Aug 3 17:18:24 CEST 2008


On 3 Aug 2008, at 14:57, Stefan de Konink wrote:

>         if (hdl->buffer.len > 0) {
>                 cherokee_buffer_add_buffer (buffer, &hdl->buffer);
>                 cherokee_buffer_move_to_begin (&hdl->buffer, buffer- 
> >size);
>                 if (hdl->buffer.len == 0)
>                         return ret_eof_have_data;

This snipped does not make much sense because a number of reasons:

- cherokee_buffer_add_buffer() appends the whole buffer, so it  
wouldn't make sense to move the rest to the begin, because you already  
know that it has been added completely.  If you wanted to clean the  
buffer, a call to cherokee_buffer_clean() would have the same result.

- The call the cherokee_buffer_move_to_begin() is also wrong because  
of the buffer->size parameter. A buffer has three properties: ->buf, - 
 >len and ->size. The first one holds a pointer to the char *, the  
second stores de length of the information, and the last one stores  
the allocated memory size (which will always be equal or greater than - 
 >len).

In this case, the correct call would be:
  cherokee_buffer_move_to_begining (&hdl->buffer, buffer->len);

>         } else
>                 return ret_eagain;

If there is nothing on the buffer, I would say that you should rather  
return ret_eof. (If your handler is collecting data asynchronously  
that could be different though).

> vs
>
> ret_t
> cherokee_handler_server_info_step (cherokee_handler_server_info_t  
> *hdl,
> cherokee_buffer_t *buffer)
> {
>     cherokee_buffer_add_buffer (buffer, &hdl->buffer);
>     return ret_eof_have_data;
> }

In this case, the handler does know that there will only be a single  
call to the _step() method. That's why it copies all the information  
that has previously built and returns eof_have_data (the last data  
package before closing the connection. It is like ret_ok + ref_oef).

A more generic implementation of this method, following the direction  
that you pointed with you example would be:

ret_t
cherokee_handler_example_step (cherokee_handler_example_t *hdl,
                                cherokee_buffer_t          *buf)
{
    if (cherokee_buffer_is_empty (&hdl->prebuilt))
       return ret_eof;

    cherokee_buffer_add (buf, &hdl->prebuilt, 1024);
    cherokee_buffer_move_to_begin (&hdl->prebuilt, 1024);

    if (cherokee_buffer_is_empty (&hdl->prebuilt))
       return ret_eof_have_data;

    return ret_ok;
}

This method would be iterating along an internal buffer, sending  
chunks of 1k bytes, until the buffer is empty.

> Why is implementation 1 not defaultly used. Why doesn't  
> implementation 2
> with for example java when sending large documents? It would mean the
> world for me if you elaborate on these examples and maybe the  
> 'chunked'
> variant.

Well, if you knew the response length in advance it would be better if  
you added the Content-Length header. In case you do not know it, then  
the chunked encoding is the way to go.

The only thing you will have to do in order to reply a request with a  
chunked response is to add the encoding header in the _add_headers()  
method, and then use the cherokee_buffer_add_buffer_chunked() instead  
of the cherokee_buffer_add_buffer() function. The rest is exactly the  
same.

Good luck!.. and do not hesitate to ask anything :-)

--
Greetings, alo.
http://www.alobbs.com/



More information about the Cherokee-dev mailing list