You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@trafficserver.apache.org by Or Kaplan <ka...@gmail.com> on 2011/04/18 14:26:25 UTC

Supporting Transfer-Encoding: chunked

Hi All,

I played a little with the ATS and the example plug ins.
It seems that the bnull_transform plugin does not support buffering of pages
that implemented HTTP Transfer-Encoding: chunked (the main page of the
Israeli news site: globes dot co dot il uses this method, and it did not
work out of the box).

I took the challenge and fixed the handle_buffering function in this plugin!

Enclosed is the updated handle_buffering function in this plugin after doing
a small refactoring to it.
You could find the interesting parts in bold.

*P.S* I joined the Google Summer of Code, so I hope you will pick me in the
draft :-)

Bests,
Or Kaplan

static int handle_buffering(TSCont contp, MyData * data) {
TSVIO write_vio;
int towrite, towriteLeft, avail;

/* Create the output buffer and its associated reader */
if (!data->output_buffer) {
data->output_buffer = TSIOBufferCreate();
 TSAssert(data->output_buffer);
data->output_reader = TSIOBufferReaderAlloc(data->output_buffer);
 TSAssert(data->output_reader);
}
if (!data->postTransformBuffer) {
 data->postTransformBuffer = TSIOBufferCreate();
TSAssert(data->postTransformBuffer);
data->postTransformBuffeReader =
TSIOBufferReaderAlloc(data->postTransformBuffer);
 TSAssert(data->postTransformBuffeReader);
}

/* Get the write VIO for the write operation that was performed on ourself.
This VIO contains the buffer that we are to read from
     as well as the continuation we are to call when the buffer is empty. */
write_vio = TSVConnWriteVIOGet(contp);
 /* We also check to see if the write VIO's buffer is non-NULL. A NULL
buffer indicates that the write operation has been
    shutdown and that the continuation does not want us to send any more
WRITE_READY or WRITE_COMPLETE events. For this buffered
    transformation that means we're done buffering data. */
if (!TSVIOBufferGet(write_vio)) {
data->state = STATE_OUTPUT_DATA;
 return 0;
}

/* Determine how much data we have left to read. For this bnull transform
plugin this is also
 the amount of data we have left to write to the output connection. */
towrite = TSVIONTodoGet(write_vio);
 avail = TSIOBufferReaderAvail(TSVIOReaderGet(write_vio));
* /* chunked data case */*
* if (towrite < 0 && avail > 0) {*
* towrite = avail;*
* }*
 /* The amount of data left to read needs to be truncated by the amount of
data actually in the read buffer. */
 if (towrite > 0 && towrite > avail) {
towrite = avail;
}

        if (towrite > 0) {
/* Copy the data from the read buffer to the input buffer. */
if (TSIOBufferCopy(data->output_buffer, TSVIOReaderGet(write_vio), towrite,
0) == TS_ERROR) {
 TSError("[bnull-transform] Unable to copy read buffer\n");
goto Lerror;
}

/* Tell the read buffer that we have read the data and are no longer
interested in it. */
TSIOBufferReaderConsume(TSVIOReaderGet(write_vio), towrite);

/* Modify the write VIO to reflect how much data we've completed. */
TSVIONDoneSet(write_vio, TSVIONDoneGet(write_vio) + towrite);
 }

avail = TSIOBufferReaderAvail(TSVIOReaderGet(write_vio));
 /* Now we check the write VIO to see if there is data left to read. */
towriteLeft = TSVIONTodoGet(write_vio);
 *if (towriteLeft != 0) {*
if (towrite > 0) {
 /* Call back the write VIO continuation to let it know that we are ready
for more data. */
TSContCall(TSVIOContGet(write_vio), TS_EVENT_VCONN_WRITE_READY, write_vio);
 }
} else {
data->state = STATE_OUTPUT_DATA;

/* Call back the write VIO continuation to let it know that we have
completed the write operation. */
TSContCall(TSVIOContGet(write_vio), TS_EVENT_VCONN_WRITE_COMPLETE,
write_vio);
 }

return 1;

Lerror:

/* If we are in this code path then something is seriously wrong. */
 TSError("[bnull-transform] Fatal error in plugin");
TSReleaseAssert(!"[bnull-transform] Fatal error in plugin\n");
 return 0;
}