onLine will get called for every line the server sends. So the first lines will be the headers. Grab the content length and store it somewhere. Then wait for the double return that indicates the end of the headers, and set the tcp object to binary mode. onBinChunk will get called every so and so number of bytes received, so compare that with the number of bytes that you expect, and when all bytes are received, save the buffer to a file and delete the now useless tcpobject.
Here's code doing that that I wrote a long time ago (copy over the important stuff)
zgui_updater.server = "www.zeblote.com";
zgui_updater.port = "80";
zgui_updater.filepath = "/bl/stuff/ZGUI/Client_ZGUI.zip";
zgui_updater.destination = "Add-Ons/Client_ZGUI_new.zip";
//...
function zgui_updater::downloadUpdate(%this)
{
%tcp = new TCPObject(zgui_dlupdatetcp){};
%tcp.connect(%this.server @ ":" @ %this.port);
}
function zgui_dlupdatetcp::onConnectFailed(%this)
{
%this.delete();
zgui_updater.showPage("Error");
}
function zgui_dlupdatetcp::onDNSFailed(%this)
{
%this.delete();
zgui_updater.showPage("Error");
}
function zgui_dlupdatetcp::onConnected(%this)
{
%this.send("GET" SPC zgui_updater.filepath SPC "HTTP/1.1\r\nHost:" SPC zgui_updater.server @ "\r\n\r\n");
}
function zgui_dlupdatetcp::onLine(%this, %Line)
{
if(strstr(%line, "Content-Length:") == 0) //length of file
{
%this.haslen = 1;
%this.len = getword(%line, 1);
}
if(%line $= "" && %this.haslen) //File starts here
{
%this.setbinarysize(%this.len);
}
}
function zgui_dlupdatetcp::onBinChunk(%this, %len)
{
if(%len >= %this.len)
{
%this.saveBufferToFile(zgui_updater.destination);
%this.delete();
return;
}
}
//...