#include #include #include #include "klog.h" #include "x_builtins.h" int x_builtin_parse(const char *s, enum x_builtin_upstream *out) { if (s == NULL || out == NULL) { return -EINVAL; } if (strcmp(s, "client_addr") == 0) { *out = X_BUILTIN_CLIENT_ADDR; return 0; } if (strcmp(s, "discard") == 0) { *out = X_BUILTIN_DISCARD; return 0; } if (strcmp(s, "hang") == 0) { *out = X_BUILTIN_HANG; return 0; } if (strcmp(s, "http_ok") == 0) { *out = X_BUILTIN_HTTP_OK; return 0; } if (strcmp(s, "log_conn") == 0) { *out = X_BUILTIN_LOG_CONN; return 0; } if (strcmp(s, "close") == 0) { *out = X_BUILTIN_CLOSE; return 0; } if (strcmp(s, "close") == 0) { *out = X_BUILTIN_CLOSE; return 0; } return -EINVAL; } const char *x_builtin_name(enum x_builtin_upstream builtin) { switch (builtin) { case X_BUILTIN_CLIENT_ADDR: return "client_addr"; case X_BUILTIN_DISCARD: return "discard"; case X_BUILTIN_HANG: return "hang"; case X_BUILTIN_HTTP_OK: return "http_ok"; case X_BUILTIN_LOG_CONN: return "log_conn"; case X_BUILTIN_CLOSE: return "close"; case X_BUILTIN_NONE: default: return "none"; } } int x_builtin_handle( const struct x_builtin_request *req, struct x_builtin_response *res ) { int n; if (req == NULL || res == NULL) { return -EINVAL; } memset(res, 0, sizeof(*res)); switch (req->builtin) { case X_BUILTIN_CLIENT_ADDR: if (req->client_addr == NULL) { return -EINVAL; } n = snprintf(res->data, sizeof(res->data), "%s\n", req->client_addr); if (n < 0 || (size_t)n >= sizeof(res->data)) { return -ENOSPC; } res->data_len = (size_t)n; res->action = X_BUILTIN_ACTION_CLOSE; return 0; case X_BUILTIN_HTTP_OK: { static const char http_ok[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 2\r\n" "Connection: close\r\n" "\r\n" "OK"; memcpy(res->data, http_ok, sizeof(http_ok) - 1); res->data_len = sizeof(http_ok) - 1; res->action = X_BUILTIN_ACTION_CLOSE; return 0; } case X_BUILTIN_DISCARD: res->action = X_BUILTIN_ACTION_DISCARD; return 0; case X_BUILTIN_LOG_CONN: LOG_INFO("log_conn", "client_addr", _LOGV(req->client_addr)); res->data_len = 0; res->action = X_BUILTIN_ACTION_CLOSE; return 0; case X_BUILTIN_CLOSE: res->data_len = 0; res->action = X_BUILTIN_ACTION_CLOSE; return 0; case X_BUILTIN_HANG: res->action = X_BUILTIN_ACTION_HANG; return 0; case X_BUILTIN_NONE: default: return -EINVAL; } }