mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-14 04:57:21 +01:00
Implemented chunked file downloads. For some reason if a file is too big and has to be sent in more that 43 chunks it crashes, it might be a bug in brynet (it always crashes at the 43th chunk, with every file and chunk size setting.), will figure out the problem later.
This commit is contained in:
parent
8e429cee7d
commit
4b64bf5864
@ -59,6 +59,28 @@ void Request::send() {
|
||||
RequestPool::return_request(this);
|
||||
}
|
||||
|
||||
void Request::send_file(const std::string &p_file_path) {
|
||||
file_path = p_file_path;
|
||||
|
||||
FILE *f = fopen(file_path.c_str(), "rb");
|
||||
|
||||
if (!f) {
|
||||
printf("send_file: Error: Download: file doesn't exists! %s\n", file_path.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
file_size = ftell(f);
|
||||
fclose(f);
|
||||
|
||||
response->addHeadValue("Connection", "Close");
|
||||
std::string result = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n";
|
||||
const HttpSession::Ptr lsession = (*session);
|
||||
|
||||
(*session)->send(result.c_str(), result.size(), [this]() { this->_progress_send_file(); });
|
||||
}
|
||||
|
||||
void Request::reset() {
|
||||
http_parser = nullptr;
|
||||
session = nullptr;
|
||||
@ -66,6 +88,8 @@ void Request::reset() {
|
||||
middleware_stack = nullptr;
|
||||
_path_stack.clear();
|
||||
_path_stack_pointer = 0;
|
||||
file_size = 0;
|
||||
current_file_progress = 0;
|
||||
|
||||
head.clear();
|
||||
body.clear();
|
||||
@ -151,6 +175,8 @@ void Request::push_path() {
|
||||
|
||||
Request::Request() {
|
||||
response = nullptr;
|
||||
//file_chunk_size = 1 << 20; //1MB
|
||||
file_chunk_size = 1 << 23;
|
||||
|
||||
reset();
|
||||
}
|
||||
@ -159,6 +185,48 @@ Request::~Request() {
|
||||
delete response;
|
||||
}
|
||||
|
||||
void Request::_progress_send_file() {
|
||||
const HttpSession::Ptr lsession = (*session);
|
||||
|
||||
if (current_file_progress >= file_size) {
|
||||
lsession->postShutdown();
|
||||
|
||||
RequestPool::return_request(this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *f = fopen(file_path.c_str(), "rb");
|
||||
|
||||
if (!f) {
|
||||
printf("Error: Download: In progress file doesn't exists anymore! %s\n", file_path.c_str());
|
||||
|
||||
lsession->postShutdown();
|
||||
|
||||
RequestPool::return_request(this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(f, current_file_progress, SEEK_SET);
|
||||
|
||||
long nfp = current_file_progress + file_chunk_size;
|
||||
|
||||
long csize = file_chunk_size;
|
||||
if (nfp >= file_size) {
|
||||
csize = (file_size - current_file_progress);
|
||||
}
|
||||
|
||||
body.resize(csize);
|
||||
|
||||
fread(&body[0], 1, csize, f);
|
||||
fclose(f);
|
||||
|
||||
current_file_progress = nfp;
|
||||
|
||||
(*session)->send(body.c_str(), body.size(), [this]() { this->_progress_send_file(); });
|
||||
}
|
||||
|
||||
Request *RequestPool::get_request() {
|
||||
_mutex.lock();
|
||||
|
||||
|
@ -28,10 +28,17 @@ public:
|
||||
std::string footer;
|
||||
std::string compiled_body;
|
||||
|
||||
std::string file_path;
|
||||
long file_size;
|
||||
long current_file_progress;
|
||||
long file_chunk_size;
|
||||
bool file_next;
|
||||
|
||||
void compile_body();
|
||||
void compile_and_send_body();
|
||||
void next_stage();
|
||||
void send();
|
||||
void send_file(const std::string &p_file_path);
|
||||
void reset();
|
||||
|
||||
void setup_url_stack();
|
||||
@ -49,6 +56,8 @@ public:
|
||||
~Request();
|
||||
|
||||
protected:
|
||||
void _progress_send_file();
|
||||
|
||||
std::vector<std::string> _path_stack;
|
||||
uint32_t _path_stack_pointer;
|
||||
};
|
||||
|
@ -30,29 +30,7 @@ void PagedArticle::index(Request *request) {
|
||||
if (s->file_cache->wwwroot_has_file(file_name)) {
|
||||
std::string fp = s->file_cache->wwwroot + file_name;
|
||||
|
||||
FILE *f = fopen(fp.c_str(), "rb");
|
||||
|
||||
if (!f) {
|
||||
printf("Error: Registered file doesn't exists anymore! %s\n", fp.c_str());
|
||||
|
||||
Application::get_instance()->send_error(404, request);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET); /* same as rewind(f); */
|
||||
|
||||
std::string body;
|
||||
body.resize(fsize);
|
||||
|
||||
fread(&body[0], 1, fsize, f);
|
||||
fclose(f);
|
||||
|
||||
//TODO set mimetype?
|
||||
|
||||
request->response->setBody(body);
|
||||
request->send();
|
||||
request->send_file(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user