mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-06 17:51:36 +02: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);
|
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() {
|
void Request::reset() {
|
||||||
http_parser = nullptr;
|
http_parser = nullptr;
|
||||||
session = nullptr;
|
session = nullptr;
|
||||||
@ -66,6 +88,8 @@ void Request::reset() {
|
|||||||
middleware_stack = nullptr;
|
middleware_stack = nullptr;
|
||||||
_path_stack.clear();
|
_path_stack.clear();
|
||||||
_path_stack_pointer = 0;
|
_path_stack_pointer = 0;
|
||||||
|
file_size = 0;
|
||||||
|
current_file_progress = 0;
|
||||||
|
|
||||||
head.clear();
|
head.clear();
|
||||||
body.clear();
|
body.clear();
|
||||||
@ -151,6 +175,8 @@ void Request::push_path() {
|
|||||||
|
|
||||||
Request::Request() {
|
Request::Request() {
|
||||||
response = nullptr;
|
response = nullptr;
|
||||||
|
//file_chunk_size = 1 << 20; //1MB
|
||||||
|
file_chunk_size = 1 << 23;
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@ -159,6 +185,48 @@ Request::~Request() {
|
|||||||
delete response;
|
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() {
|
Request *RequestPool::get_request() {
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
|
|
||||||
|
@ -28,10 +28,17 @@ public:
|
|||||||
std::string footer;
|
std::string footer;
|
||||||
std::string compiled_body;
|
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_body();
|
||||||
void compile_and_send_body();
|
void compile_and_send_body();
|
||||||
void next_stage();
|
void next_stage();
|
||||||
void send();
|
void send();
|
||||||
|
void send_file(const std::string &p_file_path);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void setup_url_stack();
|
void setup_url_stack();
|
||||||
@ -49,6 +56,8 @@ public:
|
|||||||
~Request();
|
~Request();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _progress_send_file();
|
||||||
|
|
||||||
std::vector<std::string> _path_stack;
|
std::vector<std::string> _path_stack;
|
||||||
uint32_t _path_stack_pointer;
|
uint32_t _path_stack_pointer;
|
||||||
};
|
};
|
||||||
|
@ -30,29 +30,7 @@ void PagedArticle::index(Request *request) {
|
|||||||
if (s->file_cache->wwwroot_has_file(file_name)) {
|
if (s->file_cache->wwwroot_has_file(file_name)) {
|
||||||
std::string fp = s->file_cache->wwwroot + file_name;
|
std::string fp = s->file_cache->wwwroot + file_name;
|
||||||
|
|
||||||
FILE *f = fopen(fp.c_str(), "rb");
|
request->send_file(fp);
|
||||||
|
|
||||||
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();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user