• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

llnl / dftracer-utils / 23529483807

25 Mar 2026 07:17AM UTC coverage: 48.515% (-1.6%) from 50.098%
23529483807

Pull #57

github

web-flow
Merge 5b1e117ad into 38f9f3616
Pull Request #57: feat(comparator): add pairwise traces comparator

18829 of 49412 branches covered (38.11%)

Branch coverage included in aggregate %.

1584 of 1933 new or added lines in 14 files covered. (81.95%)

3552 existing lines in 135 files now uncovered.

18474 of 27477 relevant lines covered (67.23%)

241072.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.72
/src/dftracer/utils/server/http_connection.cpp
1
#include <dftracer/utils/core/common/logging.h>
2
#include <dftracer/utils/core/io/ops.h>
3
#include <dftracer/utils/server/http_connection.h>
4
#include <dftracer/utils/server/http_request.h>
5
#include <dftracer/utils/server/http_response.h>
6
#include <dftracer/utils/server/router.h>
7

8
#include <cstring>
9

10
#ifdef __linux__
11
#include <malloc.h>  // malloc_trim
12
#endif
13

14
namespace dftracer::utils::server {
15

16
coro::CoroTask<void> handle_connection(int client_fd,
154!
17
                                       struct sockaddr_in /*addr*/,
18
                                       Router& router) {
18!
19
    // 8 KiB receive buffer. For HTTP/1.1 GET requests this is plenty.
20
    // Requests larger than this are rejected as "too large".
21
    constexpr std::size_t BUF_SIZE = 8192;
18✔
22
    char buf[BUF_SIZE];
18✔
23
    std::size_t buf_used = 0;
18✔
24

25
    while (true) {
18✔
26
        // Read data from socket.
27
        ssize_t n = co_await io::recv(client_fd, buf + buf_used,
72!
28
                                      BUF_SIZE - buf_used, 0);
18✔
29
        if (n <= 0) break;  // Connection closed or error
50✔
30
        buf_used += static_cast<std::size_t>(n);
48✔
31

32
        // Try to parse a complete request.
33
        HttpRequest req;
48✔
34
        int parsed = req.parse(buf, buf_used);
48!
35
        if (parsed == -2) {
48!
36
            // Incomplete — need more data.
NEW
37
            if (buf_used >= BUF_SIZE) {
×
38
                // Buffer full but still no complete request.
UNCOV
39
                auto resp = HttpResponse::bad_request("Request too large");
×
UNCOV
40
                auto out = resp.serialize();
×
UNCOV
41
                co_await io::send(client_fd, out.data(), out.size(), 0);
×
UNCOV
42
                break;
×
UNCOV
43
            }
×
UNCOV
44
            continue;
×
45
        }
46
        if (parsed < 0) {
48!
UNCOV
47
            auto resp = HttpResponse::bad_request("Malformed HTTP request");
×
UNCOV
48
            auto out = resp.serialize();
×
UNCOV
49
            co_await io::send(client_fd, out.data(), out.size(), 0);
×
UNCOV
50
            break;
×
UNCOV
51
        }
×
52

53
        // Route and handle.
54
        HttpResponse resp;
48!
55
        try {
56
            resp = co_await router.handle(req);
64!
57
        } catch (const std::exception& e) {
16!
UNCOV
58
            DFTRACER_UTILS_LOG_ERROR("Handler exception: %s", e.what());
×
UNCOV
59
            resp = HttpResponse::internal_error(e.what());
×
UNCOV
60
        } catch (...) {
×
UNCOV
61
            DFTRACER_UTILS_LOG_ERROR("Handler threw unknown exception");
×
UNCOV
62
            resp = HttpResponse::internal_error("Internal server error");
×
UNCOV
63
        }
×
64
        auto out = resp.serialize();
16!
65
        co_await io::send(client_fd, out.data(), out.size(), 0);
32!
66

67
        // Consume parsed bytes; shift any remaining data.
68
        auto consumed = static_cast<std::size_t>(parsed);
16✔
69
        if (consumed < buf_used) {
16!
UNCOV
70
            std::memmove(buf, buf + consumed, buf_used - consumed);
×
UNCOV
71
            buf_used -= consumed;
×
UNCOV
72
        } else {
×
73
            buf_used = 0;
16✔
74
        }
75

76
        // Check Connection: close or HTTP/1.0 (no keep-alive).
77
        if (req.minor_version == 0 || req.has_header("connection", "close")) {
16!
78
            break;
16✔
79
        }
80
    }
50!
81

82
    // Note: the caller (tcp_listener) is responsible for closing
83
    // client_fd via io::close() after this coroutine returns.
84

85
#ifdef __linux__
86
    // Return freed heap pages to the OS.  Each request may decompress
87
    // large gzip buffers and build sizeable JSON responses; without
88
    // this call glibc's ptmalloc2 keeps those arenas mapped, causing
89
    // RSS to grow monotonically.
90
    ::malloc_trim(0);
91
#endif
92
}
82✔
93

94
}  // namespace dftracer::utils::server
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc