c ++ — удаляются символы при получении файлов из простого сервиса php с использованием WinHttpReadData

У меня есть простая служба php, настроенная на веб-сервере IIS. Он используется моим клиентом для получения файлов с сервера. Это выглядит так:

<?php

if (isset($_GET['file']))
{
$filepath = "C:\\files\\" . $_GET['file'];

if (!strpos(pathinfo($filepath, PATHINFO_DIRNAME), "..") && file_exists($filepath) && !is_dir($filepath))
{
set_time_limit(0);
$fp = @fopen($filepath, "rb");

while(!feof($fp))
{
print(@fread($fp, 1024*8));
ob_flush();
flush();
}
}
else
{
echo "ERROR at www.testserver.com\r\n";
}

exit;
}

?>

Я получаю файлы, используя WinHttp WinHttpReadData в C ++.

РЕДАКТИРОВАТЬ № 2: Вот код C ++. Это не совсем так, как это выглядит в моей программе. Я должен был вытащить кусочки из нескольких классов, но суть должна быть очевидной.

session = WinHttpOpen(appName.c_str(), WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);

if (session) connection = WinHttpConnect(session, hostName.c_str(), INTERNET_DEFAULT_HTTP_PORT, 0);

if (connection) request = WinHttpOpenRequest(connection, NULL, requestString.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

bool results = false;

if (request)
{
results = (WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0) != FALSE);
}

if (results)
{
results = (WinHttpReceiveResponse(request, NULL) != FALSE);
}

DWORD bytesCopied = 0;
DWORD size = 0;

if (results)
{
do {
results = (WinHttpQueryDataAvailable(request, &size) != FALSE);

if (results)
{
// More available data?
if (size > 0)
{
// Read the Data.
size = min(bufferSize, size);

ZeroMemory(buffer, size);

results = (WinHttpReadData(request, (LPVOID)buffer, size, &bytesCopied) != FALSE);
}
}

if (bytesCopied > 0 && !SharedShutDown.GetValue())
{
tempFile.write((PCHAR)RequestBuffer, bytesCopied);

if (tempFile.fail())
{
tempFile.close();
return false;
}

fileBytes += bytesCopied;
}
} while (bytesCopied > 0 && !SharedShutDown.GetValue());
}

Все работает нормально, когда я тестирую (тысячи файлов) по локальной сети, используя имя сервера на компьютере с Windows 7 или Windows 10. Он также отлично работает, когда я получаю доступ к службе через Интернет с компьютера с Windows 7. Однако, когда я запускаю клиент на компьютере с Windows 10, доступ к которому осуществляется через Интернет, у меня пропадают символы. Интересно то, что это определенный набор символов, который каждый раз отбрасывается из файлов XML. (Другие, двоичные файлы также затрагиваются, но я еще не определил, какие в них изменения.)

Если файл XML содержит элемент, начинающийся с «<Style«, этот текст исчезает. Итак, это:

<Element1>blah blah</Element1>
<Style_Element>hoopa hoopa</Style_Element>
<Element2>bip bop bam</Element2>

становится так:

<Element1>blah blah</Element1>
_Element>hoopa hoopa</Style_Element>
<Element2>bip bop bam</Element2>

Обратите внимание, что начало элемента стиля обрезано. Это единственный затронутый элемент, и, похоже, он влияет на первый, только если в файле более одного элемента.

Что меня озадачивает, так это то, почему этого не происходит при запуске клиента из Windows 7.

РЕДАКТИРОВАТЬ: Некоторые другие файлы, двоичные и текстовые, не содержат от 1 до 3 символов каждый. Кажется, что падение происходит только один раз в файле. Остальное содержимое файла идентично исходному.

0

Решение

Я не могу понять смысл вышеприведенной процедуры чтения, она также неполная. Просто сделайте это просто, как в примере ниже.

Тот факт, что у вас проблемы с бинарными файлами, говорит о том, что вы не открываете вывод tempFile в двоичном режиме.

std::ofstream tempFile(filename, std::ios::binary);

while(WinHttpQueryDataAvailable(request, &size) && size)
{
std::string buf(size, 0);
WinHttpReadData(request, &buf[0], size, &bytesCopied);
tempFile.write(buf.data(), bytesCopied);
}

Ваш php файл может быть упрощен следующим образом:

<?php
readfile('whatever.bin');
?>
0

Другие решения

Кажется, я решил проблему. Мой php-сервис не включал информацию заголовка (я не думал, что она мне нужна), поэтому я решил попробовать добавить спецификацию заголовка для типа контента application / octet-stream, чтобы посмотреть, что из этого получится. Мой обновленный сервис выглядел так:

if (isset($_GET['file']))
{
$filepath = "C:\\Program Files (Unrestricted)\\Sony Online Entertainment\\Everquest Yarko Client\\" . $_GET['file'];

if (!strpos(pathinfo($filepath, PATHINFO_DIRNAME), "..") && file_exists($filepath) && !is_dir($filepath))
{
header("Content-Type:application/octet-stream");

set_time_limit(0);
$fp = @fopen($filepath, "rb");

while(!feof($fp))
{
print(@fread($fp, 1024*8));
ob_flush();
flush();
}
}
else
{
echo "ERROR at www.lewiefitz.com\r\n";
}

exit;
}

Теперь файлы загружаются без каких-либо повреждений. Зачем мне нужен такой заголовок в этой ситуации мне не подходит. Какая часть системы работает с ответным сообщением, прежде чем оно попадет в мой буфер? Я не знаю.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector