http.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include <stdlib.h>
  2. #include <time.h>
  3. #include <uv.h>
  4. #include "player.h"
  5. #include "server.h"
  6. uv_tcp_t* http_server = NULL;
  7. #define HTTP_HEADER \
  8. "HTTP/1.1 200 OK\r\n" \
  9. "Content-Type: text/plain; charset=utf-8\r\n" \
  10. "X-Content-Type-Options: nosniff\r\n" \
  11. "Content-Length: %d\r\n\r\n"
  12. void free_tcp_connection(uv_handle_t* handle) {
  13. free(handle->data);
  14. free(handle);
  15. }
  16. void free_http_response(uv_write_t* res, int status) {
  17. (void)status;
  18. uv_close((uv_handle_t*)res->data, free_tcp_connection);
  19. free(res);
  20. }
  21. void new_http_connection(uv_stream_t* server, int status) {
  22. if (status < 0) {
  23. fprintf(stderr, "Connection error: %s\n", uv_strerror(status));
  24. return;
  25. }
  26. uv_loop_t* loop = uv_default_loop();
  27. uv_tcp_t* tcp_connection = malloc(sizeof(uv_tcp_t));
  28. uv_tcp_init(loop, tcp_connection);
  29. if (uv_accept(server, (uv_stream_t*)tcp_connection) != 0) {
  30. uv_close((uv_handle_t*)tcp_connection, free_tcp_connection);
  31. return;
  32. }
  33. // Get uptime
  34. int uptime = time(NULL) - start_tms;
  35. int seconds = uptime % 60;
  36. int minutes = uptime / 60 % 60;
  37. int hours = uptime / 3600;
  38. // Calculate HTTP response length
  39. int body_length = snprintf(NULL, 0,
  40. "Server uptime: %02d:%02d:%02d\r\n\r\n"
  41. "Players online:\r\n",
  42. hours, minutes, seconds);
  43. for (int i = 0; i < MAX_PLAYERS; i++) {
  44. if (players[i].username[0] == '\0') continue;
  45. body_length += snprintf(NULL, 0,
  46. "\r\n* %s\r\n"
  47. "Scene: %s\r\n",
  48. players[i].username, players[i].scene);
  49. }
  50. int header_length = snprintf(NULL, 0, HTTP_HEADER, body_length);
  51. // Generate the HTTP response
  52. tcp_connection->data = malloc(header_length + body_length + 1);
  53. int pos = sprintf(tcp_connection->data, HTTP_HEADER, body_length);
  54. pos += sprintf(tcp_connection->data + pos,
  55. "Server uptime: %02d:%02d:%02d\r\n\r\n"
  56. "Players online:\r\n",
  57. hours, minutes, seconds);
  58. for (int i = 0; i < MAX_PLAYERS; i++) {
  59. if (players[i].username[0] == '\0') continue;
  60. pos += sprintf(tcp_connection->data + pos,
  61. "\r\n* %s\r\n"
  62. "Scene: %s\r\n",
  63. players[i].username, players[i].scene);
  64. }
  65. uv_write_t* res = malloc(sizeof(uv_write_t));
  66. res->data = tcp_connection;
  67. uv_buf_t buf = uv_buf_init(tcp_connection->data, header_length + body_length);
  68. uv_write(res, (uv_stream_t*)tcp_connection, &buf, 1, free_http_response);
  69. }