From d93bacb8f272c5ce3f4709db83633769c15dfc53 Mon Sep 17 00:00:00 2001 From: tototomate123 Date: Sun, 19 Oct 2025 20:08:56 +0200 Subject: [PATCH] add json returns --- server.c | 131 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 27 deletions(-) diff --git a/server.c b/server.c index 8af86a0..809eb6e 100644 --- a/server.c +++ b/server.c @@ -1,18 +1,18 @@ #include #include +#include +#include +#include +#include #include #include -#include -#include -/* #include -#include -#include */ #define PORT 6008 #define BACKLOG 16 #define RECV_BUF 256 -int main() { +int main() +{ int server_fd = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); @@ -31,38 +31,115 @@ int main() { const char *hdr = "X-Forwarded-For:"; const size_t hdrlen = strlen(hdr); - while(1) { + while (1) + { int client = accept(server_fd, NULL, NULL); - if (client < 0) continue; - ssize_t r = recv(client, buf, sizeof(buf) -1, 0); - if (r <= 0) { close(client); continue; } + if (client < 0) + continue; + ssize_t r = recv(client, buf, sizeof(buf) - 1, 0); + if (r <= 0) + { + close(client); + continue; + } buf[r] = 0; - //find header + // detect optional JSON response request on the first line + bool wants_json = false; + const char *line_end = strstr(buf, "\r\n"); + size_t line_len = line_end ? (size_t)(line_end - buf) : (size_t)r; + const char *space1 = memchr(buf, ' ', line_len); + if (space1 && space1 < buf + line_len) + { + const char *path = space1 + 1; + const char *space2 = memchr(path, ' ', line_len - (size_t)(path - buf)); + if (space2 && space2 > path) + { + const char *query = memchr(path, '?', (size_t)(space2 - path)); + if (query && ++query < space2) + { + size_t remaining = (size_t)(space2 - query); + const char *token = query; + while (remaining > 0) + { + size_t token_len = 0; + while (token_len < remaining && token[token_len] != '&') + token_len++; + if (token_len == 11 && strncasecmp(token, "format=json", 11) == 0) + { + wants_json = true; + break; + } + if (token_len >= 7 && strncasecmp(token, "format=", 7) == 0) + { + size_t value_len = token_len - 7; + if (value_len == 4 && strncasecmp(token + 7, "json", 4) == 0) + { + wants_json = true; + break; + } + } + if (token_len == remaining) + break; + token += token_len + 1; + remaining -= token_len + 1; + } + } + } + } + + // find header char *ip = NULL; - for (ssize_t i = 0; i < r - (ssize_t)hdrlen; ++i) { - if (strncasecmp(buf + i, hdr, hdrlen) == 0) { + for (ssize_t i = 0; i < r - (ssize_t)hdrlen; ++i) + { + if (strncasecmp(buf + i, hdr, hdrlen) == 0) + { ip = buf + i + hdrlen; - while (*ip == ' ' || *ip == '\t') ip++; + while (*ip == ' ' || *ip == '\t') + ip++; break; } } - //find end + // find end char *end = ip; - if (ip) { - while (*end && *end != '\r' && *end != '\n') end++; + if (ip) + { + while (*end && *end != '\r' && *end != '\n' && *end != ',') + end++; + while (end > ip && (end[-1] == ' ' || end[-1] == '\t')) + end--; *end = 0; } - - //response - const char *head = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: "; - char lenbuf[32]; - int iplen = ip ? strlen(ip) : 0; - int len = snprintf(lenbuf, sizeof(lenbuf), "%d\r\n\r\n", iplen); - send(client, head, strlen(head), 0); - send(client, lenbuf, len, 0); - if (iplen > 0) send(client, ip, iplen, 0); + // response + char head[128]; + char jsonbuf[RECV_BUF]; + const char *body = ip ? ip : ""; + const char *content_type = "text/plain"; + int body_len = ip ? (int)strlen(ip) : 0; + + if (wants_json) + { + content_type = "application/json"; + if (ip && *ip) + { + body_len = snprintf(jsonbuf, sizeof(jsonbuf), "{\"ip\":\"%s\"}", ip); + if (body_len < 0 || body_len >= (int)sizeof(jsonbuf)) + body_len = snprintf(jsonbuf, sizeof(jsonbuf), "{\"ip\":\"%s\"}", ""); + } + else + { + body_len = snprintf(jsonbuf, sizeof(jsonbuf), "{\"ip\":null}"); + } + body = jsonbuf; + } + + int head_len = snprintf(head, sizeof(head), + "HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n", + content_type, body_len); + if (head_len > 0) + send(client, head, (size_t)head_len, 0); + if (body_len > 0) + send(client, body, (size_t)body_len, 0); close(client); - } } \ No newline at end of file