void cb_downloadStart(AuthServer_Private& client) { START_REPLY(e_AuthToCli_FileDownloadChunk); // Trans ID uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); // Download filename DS::String filename = DS::CryptRecvString(client.m_sock, client.m_crypt); // Ensure filename is jailed to our data path if (filename.find("..") != -1) { client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Chunk offset client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } filename.replace("\\", "/"); filename = DS::Settings::AuthRoot() + filename; DS::FileStream* stream = new DS::FileStream(); try { stream->open(filename.c_str(), "rb"); } catch (const DS::FileIOException& ex) { fprintf(stderr, "[Auth] Could not open file %s: %s\n[Auth] Requested by %s\n", filename.c_str(), ex.what(), DS::SockIpAddress(client.m_sock).c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Chunk offset client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); delete stream; return; } client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(stream->size()); client.m_buffer.write<uint32_t>(stream->tell()); uint8_t data[CHUNK_SIZE]; if (stream->size() > CHUNK_SIZE) { client.m_buffer.write<uint32_t>(CHUNK_SIZE); stream->readBytes(data, CHUNK_SIZE); client.m_buffer.writeBytes(data, CHUNK_SIZE); client.m_downloads[transId] = stream; } else { client.m_buffer.write<uint32_t>(stream->size()); stream->readBytes(data, stream->size()); client.m_buffer.writeBytes(data, stream->size()); delete stream; } SEND_REPLY(); }
void cb_downloadStart(FileServer_Private& client) { START_REPLY(e_FileToCli_FileDownloadReply); // Trans ID client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock)); // Download filename chr16_t buffer[260]; DS::RecvBuffer(client.m_sock, buffer, 260 * sizeof(chr16_t)); buffer[259] = 0; DS::String filename = DS::String::FromUtf16(buffer); // Build ID uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock); if (buildId && buildId != CLIENT_BUILD_ID) { fprintf(stderr, "[File] Wrong Build ID from %s: %d\n", DS::SockIpAddress(client.m_sock).c_str(), buildId); DS::CloseSock(client.m_sock); return; } // Ensure filename is jailed to our data path if (filename.find("..") != -1) { client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } filename.replace("\\", "/"); filename = DS::Settings::FileRoot() + filename; DS::FileStream* stream = new DS::FileStream(); try { stream->open(filename.c_str(), "rb"); } catch (DS::FileIOException ex) { fprintf(stderr, "[File] Could not open file %s: %s\n[File] Requested by %s\n", filename.c_str(), ex.what(), DS::SockIpAddress(client.m_sock).c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); delete stream; return; } client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(++client.m_readerId); client.m_buffer.write<uint32_t>(stream->size()); uint8_t data[CHUNK_SIZE]; if (stream->size() > CHUNK_SIZE) { client.m_buffer.write<uint32_t>(CHUNK_SIZE); stream->readBytes(data, CHUNK_SIZE); client.m_buffer.writeBytes(data, CHUNK_SIZE); client.m_downloads[client.m_readerId] = stream; } else { client.m_buffer.write<uint32_t>(stream->size()); stream->readBytes(data, stream->size()); client.m_buffer.writeBytes(data, stream->size()); delete stream; } SEND_REPLY(); }