Skip to content

Commit 9f5d808

Browse files
committed
UPD | more slices
1 parent 972e341 commit 9f5d808

File tree

7 files changed

+107
-54
lines changed

7 files changed

+107
-54
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ HTTP server written on C++ which supports HTTP/1.1, HTTP/2 and HTTP/3 (over QUIC
55

66
> [!CAUTION]
77
> This project is in development!!!
8+
> (last stable commit - [b2836e13a967f734c57868eb1daa62801d123ee8](https://github.com/xiadnoring/manapi-http/commit/b2836e13a967f734c57868eb1daa62801d123ee8))
89
910
## About
1011
This HTTP server should simplify development of `web applications`, `API-interfaces` and other things.
1112

12-
So many important utils will be supported out of the box, for example, `JSON`, `MySQL-client`, `PostgreSQL-client`, `JSON-masks`, `Big Int`, `modules`, `plugins`.
13+
Many important utils will be supported out of the box, for example, `JSON`, `MySQL-client`, `PostgreSQL-client`, `JSON-masks`, `Big Int`, `modules`, `plugins`.
1314

1415
## Installation
1516
For compile this project, you need to install below projects:

include/worker/TCP.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ namespace manapi::net::worker {
7373

7474

7575
protected:
76-
virtual void flush_write_ (const shared_conn &connection, bool flush = false);
76+
virtual int flush_write_ (const shared_conn &connection, bool flush = false);
7777

7878
void flush_read_ (const shared_conn &conn, connection_interface *data);
7979

include/worker/TLS.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ namespace manapi::net::worker {
7979

8080
void onrecv(std::shared_ptr<ev::tcp> &watcher, const shared_conn &conn, ibuffpool_t buffer) override;
8181

82-
void flush_write_(const shared_conn &connection, bool flush) override;
83-
8482
void *ctx = nullptr;
8583
int ssl_session_ctx_id{1};
8684
private:

main.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,22 @@ int main () {
286286
co_return resp.file("/home/Timur/Downloads/VideoDownloader/ufa.mp4");
287287
});
288288

289+
router.GET("/noise", [] (manapi::net::http::request &req, manapi::net::http::response &resp)
290+
-> manapi::future<> {
291+
ssize_t len = 10737418240;
292+
293+
resp.header(manapi::net::http::HEADER.CONTENT_LENGTH, std::to_string(len));
294+
co_return resp.callback_sync([current = (ssize_t)0, len] (char *buffer, ssize_t size, bool &flg) mutable
295+
-> ssize_t {
296+
size = std::min(size, len - current);
297+
memset(buffer, '\0', size);
298+
len -= size;
299+
if (!len)
300+
flg = true;
301+
return size;
302+
});
303+
});
304+
289305
router.GET("/mem", "/home/Timur/Downloads/VideoDownloader");
290306

291307
router.GET("/timeout", [] (manapi::net::http::request &req, manapi::net::http::response &resp)

src/http/base_http.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -511,34 +511,47 @@ void manapi::net::http::internal::send_response_sync_cb(uq_handle_data_t cdata,
511511
auto cb_sync = std::make_unique<http::response::resp_callback_sync>(std::move(res->callback_sync()));
512512
manapi::async::run ([res = std::move(res), cb_sync = std::move(cb_sync), cdata = std::move(cdata)] () mutable
513513
-> manapi::future<> {
514-
auto buffer = manapi::async::current()->memory_fabric().buffer (
515-
std::max(res->config()->buffer_size, 64L));
516514

517515
bool finish = false;
518516
std::size_t cursor = 0;
519517

520-
521518
if (http_v1_1_is_chunked_data(cdata, res.get())) {
519+
auto buffer = manapi::async::current()->memory_fabric().buffer (
520+
std::max(res->config()->buffer_size, 64L));
522521
while (!finish) {
523522
auto rhs = cb_sync->operator()(buffer.data(), buffer.size(), finish);
524523
co_await send_http_v1_1_chunked_data(cdata, rhs, buffer.data(), buffer.size(), finish);
525524
}
526525
}
527526
else {
527+
auto slices = cdata->worker->bufferpool().slice(4096 * 16);
528528
while (!finish) {
529-
auto rhs = cb_sync->operator()(buffer.data() + cursor, buffer.size() - cursor, finish);
530-
if (rhs < 0) {
531-
THROW_MANAPIHTTP_EXCEPTION2(ERR_INVALID_ARGUMENT, "The callback returned an invalid length");
532-
}
533-
rhs = co_await cdata->worker->write(cdata->conn, buffer.data() + cursor, rhs, finish);
529+
ssize_t total = 0;
530+
for (auto it = slices.begin(); it != slices.end() && !finish; ) {
531+
auto rhs = cb_sync->operator()(static_cast<char *>(it.buffer()) + cursor,
532+
it.size() - cursor, finish);
534533

535-
if (rhs <= 0)
536-
co_return;
534+
if (rhs < 0)
535+
THROW_MANAPIHTTP_EXCEPTION2(ERR_INVALID_ARGUMENT, "The callback returned an invalid length");
537536

538-
cursor += rhs;
537+
cursor += rhs;
539538

540-
if (buffer.size() == cursor)
539+
if (cursor == it.size()) {
540+
total += cursor;
541+
cursor = 0;
542+
it++;
543+
}
544+
}
545+
if (cursor) {
546+
total += cursor;
541547
cursor = 0;
548+
}
549+
550+
auto const rhs = co_await cdata->worker->fwrite(
551+
cdata->conn, slices.subslice(0, total).value(), finish);
552+
553+
if (rhs <= 0)
554+
co_return;
542555
}
543556
}
544557
});

src/worker/TCP.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,8 @@ ssize_t manapi::net::worker::TCP::sync_write_ex(const worker::shared_conn &conn,
487487
connection->transfered += rhs;
488488
}
489489

490-
this->flush_write_(conn, finish);
490+
if (this->flush_write_(conn, finish))
491+
return -1;
491492
}
492493

493494
return rhs;
@@ -550,11 +551,11 @@ int manapi::net::worker::TCP::event_flags(const shared_conn & conn) {
550551
return (conn->as<connection_interface>()->status) & CONN_MASK_GETTING;
551552
}
552553

553-
void manapi::net::worker::TCP::flush_write_(const worker::shared_conn &connection, bool flush) {
554+
int manapi::net::worker::TCP::flush_write_(const worker::shared_conn &connection, bool flush) {
554555
auto conn = connection->as<connection_interface>();
555556

556-
if ((conn->top->cur_send_size >= this->config_->max_merge_buffer_stack
557-
&& ((conn->top->send.last_deque->buffer.size() == conn->top->send.deque_cursor)))
557+
if ((conn->top->cur_send_size > this->config_->max_merge_buffer_stack)
558+
|| ((conn->top->cur_send_size == this->config_->max_merge_buffer_stack) && (conn->top->send.last_deque->buffer.size() == conn->top->send.deque_cursor))
558559
|| (flush && conn->top->cur_send_size)) {
559560
std::unique_ptr<ev::buff_t, ev::buffer_deleter> s;
560561
s.reset(new ev::buff_t[conn->top->cur_send_size]);
@@ -596,6 +597,10 @@ void manapi::net::worker::TCP::flush_write_(const worker::shared_conn &connectio
596597
conn->top->cur_send_size = 0;
597598
}
598599
else {
600+
if (rhs < 0)
601+
return CONN_IO_ERROR;
602+
603+
599604
uint32_t cursor = 0;
600605
while (cursor != conn->top->cur_send_size
601606
&& rhs >= buffptr[cursor].len) {
@@ -652,6 +657,8 @@ void manapi::net::worker::TCP::flush_write_(const worker::shared_conn &connectio
652657
}
653658
}
654659
}
660+
661+
return CONN_IO_OK;
655662
}
656663

657664
void manapi::net::worker::TCP::flush_read_(const shared_conn &conn, connection_interface *data) {

src/worker/TLS.cpp

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,9 @@ ssize_t manapi::net::worker::TLS::sync_write_ex(const shared_conn &conn, ev::buf
110110

111111
bool const cfinish = finish && total == size;
112112

113-
int err;
114-
if (rhs <= 0) {
115-
err = this->ssl_get_error_(connection->ssl, rhs);
113+
int err = this->ssl_get_error_(connection->ssl, rhs);
116114

115+
if (err) {
117116
if (err == this->ssl_error_none_) {
118117

119118
}
@@ -128,14 +127,16 @@ ssize_t manapi::net::worker::TLS::sync_write_ex(const shared_conn &conn, ev::buf
128127

129128
if (err) {
130129
if (err == CONN_IO_WANT_WRITE) {
131-
this->flush_write_(conn, cfinish);
130+
if (this->flush_write_(conn, cfinish))
131+
return CONN_IO_ERROR;
132132
return total;
133133
}
134134

135135
return CONN_IO_ERROR;
136136
}
137137

138-
this->flush_write_(conn, true);
138+
if (this->flush_write_(conn, true))
139+
return CONN_IO_ERROR;
139140

140141
continue;
141142
}
@@ -149,14 +150,16 @@ ssize_t manapi::net::worker::TLS::sync_write_ex(const shared_conn &conn, ev::buf
149150

150151
if (err) {
151152
if (err == CONN_IO_WANT_WRITE) {
152-
this->flush_write_(conn, cfinish);
153+
if (this->flush_write_(conn, cfinish))
154+
return CONN_IO_ERROR;
153155
return total;
154156
}
155157

156158
return CONN_IO_ERROR;
157159
}
158160

159-
this->flush_write_(conn, cfinish);
161+
if (this->flush_write_(conn, cfinish))
162+
return CONN_IO_ERROR;
160163
}
161164
}
162165

@@ -306,7 +309,8 @@ void manapi::net::worker::TLS::onrecv(std::shared_ptr<ev::tcp> &watcher, const s
306309
goto err;
307310
}
308311

309-
this->flush_write_(conn, true);
312+
if (this->flush_write_(conn, true))
313+
goto err;
310314
}
311315
else if (status) {
312316
goto err;
@@ -354,31 +358,6 @@ void manapi::net::worker::TLS::onrecv(std::shared_ptr<ev::tcp> &watcher, const s
354358
// conn->as<TLS::connection_interface>()->watcher->read_start();
355359
// }
356360

357-
void manapi::net::worker::TLS::flush_write_(const shared_conn &connection, bool flush) {
358-
// auto const data = connection->as<TLS::connection_interface>();
359-
// if (flush && data->top->send_size == 1) {
360-
// assert(data->top->send.last_deque);
361-
// /* in the stack */
362-
// auto &buffer = data->top->send.deque->buffer;
363-
// auto copy = static_cast<int>(data->top->send.deque_cursor - data->top->send.deque_current);
364-
// auto const rhs = data->watcher->try_write(buffer.data() + data->top->send.deque_current, copy);
365-
// if (rhs >= 0) {
366-
// if (rhs == copy) {
367-
// data->top->send.deque = nullptr;
368-
// data->top->send.last_deque = nullptr;
369-
// data->top->send.deque_current = 0;
370-
// data->top->send.deque_cursor = 0;
371-
// data->top->send_size--;
372-
// data->top->cur_send_size--;
373-
// return;
374-
// }
375-
//
376-
// data->top->send.deque_current += static_cast<int>(rhs);
377-
// }
378-
// }
379-
380-
TCP::flush_write_(connection, flush);
381-
}
382361

383362
int manapi::net::worker::TLS::check_read_stack_full_(connection_interface *data) {
384363
if (data->top->recv_size >= this->config_->max_buffer_stack) {
@@ -395,11 +374,50 @@ int manapi::net::worker::TLS::ssl_bio_flush_write_(const shared_conn &conn, void
395374
int flags = 0;
396375
buffer_deque *parent = nullptr;
397376
auto top = &m->send;
377+
//
378+
// char fastfast[16356];
379+
// ssize_t nfastfast = 0;
380+
//
381+
// try {
382+
// while (true) {
383+
// if (max_cnt < m->send_size)
384+
// break;
385+
//
386+
// if (max_cnt < 10000)
387+
// nfastfast = std::min<ssize_t>((max_cnt - m->send_size + 1) * this->config_->buffer_size,
388+
// (sizeof (fastfast)));
389+
// else
390+
// nfastfast = sizeof (fastfast);
391+
//
392+
// rhs = this->ssl_bio_read_(wbio, fastfast,
393+
// static_cast<int>(nfastfast));
394+
//
395+
// if (rhs > 0) {
396+
// auto const prev = m->send_size;
397+
// TLS::connection_io_send(top, fastfast, rhs, &this->bufferpool(), this->config_->buffer_size, &m->send_size, 1e5);
398+
// m->cur_send_size += m->send_size - prev;
399+
//
400+
// this->flush_write_(conn, false);
401+
// }
402+
// else {
403+
// if (!this->ssl_bio_should_retry_(wbio)) {
404+
// return CONN_IO_ERROR;
405+
// }
406+
// break;
407+
// }
408+
// }
409+
// return CONN_IO_OK;
410+
// }
411+
// catch (std::exception const &e) {
412+
// manapi::async::current()->logger()->error(manapi::logger::default_service,
413+
// manapi::ERR_INTERNAL, "TLS::ssl_bio_flush_write_(...): {}", e.what());
414+
// }
398415

399416
try {
400417
do {
401418
if (!top->last_deque || top->last_deque->buffer.size() == top->deque_cursor) {
402-
this->flush_write_(conn, false);
419+
if (this->flush_write_(conn, false))
420+
return CONN_IO_ERROR;
403421

404422
if (m->send_size > max_cnt)
405423
return CONN_IO_WANT_WRITE;

0 commit comments

Comments
 (0)