diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-03-20 03:32:00 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-03-20 10:57:20 +0100 |
| commit | d9bb874591c63f2efbfc1c4c953934251c700e9f (patch) | |
| tree | 88254b346628a22ece5a4ede5f411458969720c0 /page.c | |
| parent | d51b191ab7005de6679a00dd200ad5502ecff5ac (diff) | |
| download | slcl-d9bb874591c63f2efbfc1c4c953934251c700e9f.tar.gz | |
Send response on quota exceeded
So far, slcl would just close the connection with a client when the
Content-Length of an incoming request exceeded the user quota, without
any meaningful information given back to the user.
Now, slcl responds with a HTML file with meaningful information about
the error.
Limitations:
- While this commits has been successfully tested on ungoogled-chromium,
LibreWolf (and I assume Firefox and any other derivates too) does not
seem to receive the response from the server.
- However, this issue only occurred during local testing, but not
on remote instances.
Diffstat (limited to 'page.c')
| -rw-r--r-- | page.c | 90 |
1 files changed, 90 insertions, 0 deletions
@@ -1311,3 +1311,93 @@ end: return ret; } + +int page_quota_exceeded(struct http_response *const r, + const unsigned long long len, const unsigned long long quota) +{ + int ret = -1; + struct dynstr msg, out; + char q[sizeof MAXSIZEFMT], l[sizeof q]; + struct html_node *const html = html_node_alloc("html"), + *head, *body; + + dynstr_init(&msg); + dynstr_init(&out); + + if (!html) + { + fprintf(stderr, "%s: html_node_alloc failed\n", __func__); + goto end; + } + else if (!(head = html_node_add_child(html, "head"))) + { + fprintf(stderr, "%s: html_node_add_child head failed\n", __func__); + goto end; + } + else if (!(body = html_node_add_child(html, "body"))) + { + fprintf(stderr, "%s: html_node_add_child body failed\n", __func__); + goto end; + } + else if (common_head(head, NULL)) + { + fprintf(stderr, "%s: common_head failed\n", __func__); + goto end; + } + else if (size_units(quota, q, sizeof q)) + { + fprintf(stderr, "%s: size_units quota failed\n", __func__); + goto end; + } + else if (size_units(len, l, sizeof l)) + { + fprintf(stderr, "%s: size_units len failed\n", __func__); + goto end; + } + else if (dynstr_append(&msg, "Maximum quota exceeded: %s " + "(requested size: %s)", q, l)) + { + fprintf(stderr, "%s: dynstr_append msg failed\n", __func__); + goto end; + } + else if (html_node_set_value(body, msg.str)) + { + fprintf(stderr, "%s: html_node_set_value msg failed\n", __func__); + goto end; + } + else if (dynstr_append(&out, DOCTYPE_TAG)) + { + fprintf(stderr, "%s: dynstr_prepend failed\n", __func__); + goto end; + } + else if (html_serialize(html, &out)) + { + fprintf(stderr, "%s: html_serialize failed\n", __func__); + goto end; + } + + *r = (const struct http_response) + { + .status = HTTP_STATUS_PAYLOAD_TOO_LARGE, + .buf.rw = out.str, + .n = out.len, + .free = free + }; + + if (http_response_add_header(r, "Content-Type", "text/html")) + { + fprintf(stderr, "%s: http_response_add_header failed\n", __func__); + goto end; + } + + ret = 0; + +end: + html_node_free(html); + dynstr_free(&msg); + + if (ret) + dynstr_free(&out); + + return ret; +} |
