I'm creating an update mechanism for my first program written in c++. Theory is:
Most of it works however the binary received is malformed. When I compare the malformed exe with the working exe I have differences at places where I have \r\ns in the compiled exe. Seems like the \r is doubled.
My c++ code for downloading:
void checkForUpdates () {
SOCKET sock = createHttpSocket (); // creates the socket, nothing wrong here, other requests work
char* msg = (char*)"GET /u/2 HTTP/1.1\r\nHost: imgup.hu\r\nUser-Agent: imgup uploader app\r\nVersion: 1\r\n\r\n";
if (send(sock, msg, strlen(msg), 0) == SOCKET_ERROR) {
error("send failed with error\n");
}
shutdown(sock, SD_SEND);
FILE *fp = fopen("update.exe", "w");
char answ[1024] = {};
int iResult;
bool first = false;
do {
if ((iResult = recv(sock, answ, 1024, 0)) < 0) {
error("recv failed with error\n");
}
if (first) {
info (answ); // debug purposes
first = false;
} else {
fwrite(answ, 1, iResult, fp);
fflush(fp);
}
} while (iResult > 0);
shutdown(sock, SD_RECEIVE);
if (closesocket(sock) == SOCKET_ERROR) {
error("closesocket failed with error\n");
}
fclose(fp);
delete[] answ;
}
and my php to process the request
<?php
if (!function_exists('getallheaders')) {
function getallheaders() {
$headers = '';
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
$version = '0';
foreach (getallheaders() as $name => $value) {
if (strtolower ($name) == 'version') {
$version = $value;
break;
}
}
if ($version == '0') {
exit('error');
}
if ($handle = opendir('.')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != '.' && $entry != '..' && $entry != 'u.php') {
if (intval ($entry) > intval($version)) {
header('Content-Version: ' . $entry);
header('Content-Length: ' . filesize($entry));
header('Content-Type: application/octet-stream');
echo "\r\n";
ob_clean();
flush();
readfile($entry);
exit();
}
}
}
closedir($handle);
}
echo 'error2';
?>
notice the way I flush content after I send the headers ob_clean(); flush(); so I don't have to parse them in c++. The first bytes written to the file are fine, so I doubt there is any problem here.
Also, example comparison of the binaries http://i.imgup.hu/meC16C.png
Question: Does http escape \r\n in binary file transfers? If not, what is causing this behavior and how do I solve this problem?
fopen opens a File in the mode you specified, first read/write/both, then Append, then a binary identifier.
r/w should be clear to you, append is also quite obvious. The Trick & Trouble in your case is the binary-mode.
If a file is threated as a Text-File (without the "b") then, depending on the environment where the application runs, some special character conversion may occur in input/output operations in text mode to adapt them to a system-specific text file format. On Windows this would be \r\n, on a linux machine you have \n and on some architectures exist, where it is \r.
In your case, the input file is read as a text file. This means, all your line-endings get converted when reading the file from the HTTP-Data.
Opening the File as a binary file (wich indeed it is!) avoids trouble that your file is not binary identically anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With