Author Topic: Downloading an Image  (Read 1975 times)

It's using POST because frankly there's no real reason not to. I adapted it from a script where it would POST variables so I never changed it, and there's really no reason to.
There is a reason to change it. Using a GET request is the correct way to grab a resource off a website. POST requires extra headers that a GET request doesn't - such as content-type or content-length, because a POST request is meant to have a body. A GET request only needs the essential headers in a request and will require less processing on the server-side (you might find issues with caching as well). In the long run, using a GET request uses less bandwidth.
No matter how I change it, I keep getting a bad request error. I'm too tired to really fix up the code to work with chunked downloading (why would you even do that badspot, why) so you should just use Plornt's code which should look oddly familiar (hint: it's derived from mine)
Because it's faster (especially for CDNs). When you're telling a server you're running HTTP 1.1, you're practically screaming "I love chunked encoding, please give it to me!". Try sending the header as HTTP 1.0.

There is a reason to change it. Using a GET request is the correct way to grab a resource off a website. POST requires extra headers that a GET request doesn't - such as content-type or content-length, because a POST request is meant to have a body. A GET request only needs the essential headers in a request and will require less processing on the server-side (you might find issues with caching as well). In the long run, using a GET request uses less bandwidth.
Okay, but using a POST request isn't breaking anything. Change the word and remove the headers if you really really want. The reason I said I didn't see a reason to change it was because the intent of the script was originally to receive images using POST on a php script, and it works with images anyway. And the few bytes of extra data it has to send for the extra headers is entirely negligible on current internet connections and CPU processing so again there's really no big reason to change it.

Because it's faster (especially for CDNs). When you're telling a server you're running HTTP 1.1, you're practically screaming "I love chunked encoding, please give it to me!". Try sending the header as HTTP 1.0.
I can't believe that actually worked. Plornt's going to stuff himself, he worked so hard figuring out how to handle chunked encoding.

FileDownloader.downloadFile("image.blockland.us", "/detail.php?q=74.52.20.186:28100", "base/client/ui/loadingBG.png"); is giving an empty file still, instead of badspot's pirate DM image
Code: [Select]
package ServerPreview
{
function ConnectToServer(%a, %b, %c, %d)
{
echo("triggered");
%value = parent::ConnectToServer(%a, %b, %c, %d);
%ip = getSubStr(%a,0,strPos(%a,":"));
%port = getSubStr(%a,strPos(%a,":")+1,strLen(%a));
%address = strreplace(%ip,".","-") @ "_" @ %port;
new tcpObject(FileDownloader);
FileDownloader.downloadFile("image.blockland.us", "/detail.php?q=" @ %address, "base/client/ui/loadingBG.png");
echo("ended");
return %value;
}
};
activatePackage(ServerPreview);

function FileDownloader::DownloadFile(%this, %addr, %file, %saveto)
{
%this.addr = %addr;
%this.file = %file;
%this.saveTo = %saveto;
%this.connect(%addr @ ":80");
}

function FileDownloader::onConnected(%this)
{
%this.send("GET " @ %this.file @ " HTTP/1.0\r\nHost: "@ %this.addr @"\r\n\r\n");
}

function FileDownloader::onLine(%this, %line)
{
if(%line $= "" && %this.binSize)
%this.setBinarySize(%this.binSize);
if(getWord(%line,0) $= "Content-Length:")
%this.binSize = getWord(%line,1);
}

function FileDownloader::onBinChunk(%this)
{
cancel(%this.saveSched);
%this.saveSched = %this.schedule(1000, onSaveFinal, %this.saveto);
}

function FileDownloader::onSaveFinal(%this, %saveto)
{
%this.saveBufferToFile(%saveto);
echo("done loading");
schedule(500, 0, resetLoading);
}

function resetLoading()
{
canvas.popDialog(LoadingGui);
canvas.pushDialog(LoadingGui);
}
i feel like i must've forgotten to change something in here, and done loading never echos

happens with both the if(%line $= "" && %this.binSize) %this.setBinarySize(%this.binSize); and the other one

FileDownloader.downloadFile("image.blockland.us", "/detail.php?q=74.52.20.186:28100", "base/client/ui/loadingBG.png"); is giving an empty file still, instead of badspot's pirate DM image
Code: [Select]
function FileDownloader::onBinChunk(%this)
{
cancel(%this.saveSched);
%this.saveSched = %this.schedule(1000, onSaveFinal, %this.saveto);
}

function FileDownloader::onSaveFinal(%this, %saveto)
{
%this.saveBufferToFile(%saveto);
echo("done loading");
schedule(500, 0, resetLoading);
}
i feel like i must've forgotten to change something in here, and done loading never echos

happens with both the if(%line $= "" && %this.binSize) %this.setBinarySize(%this.binSize); and the other one
FileDownloader.saveto isn't declared in this code, you have to declare it or save to a set spot.

i thought %this.saveBufferToFile(%saveto); was the saving code?

i thought %this.saveBufferToFile(%saveto); was the saving code?
That's because it is.

i thought %this.saveBufferToFile(%saveto); was the saving code?
Oh, I actually didn't read through your code I saw the top part and figured you were using Plornt's. Ignore that post. With HTTP/1.0 the server image still doesn't send a content-length header so you need to use the dynamic saving, meaning edit
Code: [Select]
if(%line $= "" && %this.binSize)
%this.setBinarySize(%this.binSize);
to
Code: [Select]
if(%line $= "")
%this.setBinary(1);

file is still empty with that
Code: [Select]
package ServerPreview
{
function ConnectToServer(%a, %b, %c, %d)
{
echo("triggered");
%value = parent::ConnectToServer(%a, %b, %c, %d);
%ip = getSubStr(%a,0,strPos(%a,":"));
%port = getSubStr(%a,strPos(%a,":")+1,strLen(%a));
%address = strreplace(%ip,".","-") @ "_" @ %port;
new tcpObject(FileDownloader);
FileDownloader.downloadFile("image.blockland.us", "/detail.php?q=" @ %address, "base/client/ui/loadingBG.png");
echo("ended");
return %value;
}
};
activatePackage(ServerPreview);

function FileDownloader::DownloadFile(%this, %addr, %file, %saveto)
{
%this.addr = %addr;
%this.file = %file;
%this.saveTo = %saveto;
%this.connect(%addr @ ":80");
}

function FileDownloader::onConnected(%this)
{
%this.send("GET " @ %this.file @ " HTTP/1.0\r\nHost: "@ %this.addr @"\r\n\r\n");
}

function FileDownloader::onLine(%this, %line)
{
if(%line $= "")
%this.setBinary(1);
if(getWord(%line,0) $= "Content-Length:")
%this.binSize = getWord(%line,1);
}

function FileDownloader::onBinChunk(%this)
{
cancel(%this.saveSched);
%this.saveSched = %this.schedule(1000, onSaveFinal, %this.saveto);
}

function FileDownloader::onSaveFinal(%this, %saveto)
{
%this.saveBufferToFile(%saveto);
echo("done loading");
schedule(500, 0, resetLoading);
}

function resetLoading()
{
canvas.popDialog(LoadingGui);
canvas.pushDialog(LoadingGui);
}



Problem was that you were saving the response header into beginning of your image file. I solved this by saving the buffer once the header was done which clears the buffer and gets overwritten with the actual data.

Also, this code has no problem with chunked responses (HTTP 1.1), so changed that back.

Cheers!

Code: [Select]
package ServerPreview
{
function ConnectToServer(%a, %b, %c, %d)
{
echo("triggered");
%value = parent::ConnectToServer(%a, %b, %c, %d);
%ip = getSubStr(%a,0,strPos(%a,":"));
%port = getSubStr(%a,strPos(%a,":")+1,strLen(%a));
%address = strreplace(%ip,".","-") @ "_" @ %port;
new tcpObject(FileDownloader);
FileDownloader.downloadFile("image.blockland.us", "/detail.php?q=" @ %address, "base/client/ui/loadingBG.png");
echo("ended");
return %value;
}
};
activatePackage(ServerPreview);

function FileDownloader::DownloadFile(%this, %addr, %file, %saveto)
{
%this.addr = %addr;
%this.file = %file;
%this.saveTo = %saveto;
%this.connect(%addr @ ":80");
}

function FileDownloader::onConnected(%this)
{
%this.send("GET " @ %this.file @ " HTTP/1.1\r\nHost: "@ %this.addr @"\r\n\r\n");
}

function FileDownloader::onLine(%this, %line)
{
if(%line $= "" && %this.binSize)
{
%this.setBinarySize(%this.binSize);
// flush the header out of the buffer
%this.saveBufferToFile(%saveto);
}
if(getWord(%line,0) $= "Content-Length:")
%this.binSize = getWord(%line,1);

}

function FileDownloader::onBinChunk(%this)
{
cancel(%this.saveSched);
%this.saveSched = %this.schedule(1000, onSaveFinal, %this.saveto);
}

function FileDownloader::onSaveFinal(%this, %saveto)
{
%this.saveBufferToFile(%saveto);
echo("done loading");
schedule(500, 0, resetLoading);
}

function resetLoading()
{
canvas.popDialog(LoadingGui);
canvas.pushDialog(LoadingGui);
}

« Last Edit: September 07, 2012, 04:51:55 PM by Irk89 »

Can you use this to spam the image hosting page to death

Forgot to mention, this won't actually work because http://image.blockland.us/detail.php is returning a jpeg image...not a png image. You could delete all files named "loadingBG" in that folder and then save as loadingBG.jpg.

To make this even better, you should look at the Content-Type in the header and determine what extension to save the file as. See: http://www.webmaster-toolkit.com/mime-types.shtml
« Last Edit: September 06, 2012, 04:27:00 PM by Irk89 »