#include #include #include #include #define BUFFER_SIZE (1024 * 1024) void simple_http_ok(char *response, size_t *response_len); int main() { printf("hello world!~\n"); int result = 0; WSADATA wsaData = {0}; struct sockaddr_in service; const char* address = "127.0.0.1"; int port = 8080; result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { printf("WSAStartup failed: %d\n", result); return 1; } SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { printf("failed to create socket! (%d)\n", WSAGetLastError()); WSACleanup(); return 1; } printf("socket created successfully!\n"); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr(address); service.sin_port = htons(port); if (bind(sock, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) { closesocket(sock); printf("failed to bind to %s:%d: %ld\n", address, port, WSAGetLastError()); WSACleanup(); return 1; } /* result = connect(sock, (SOCKADDR*) &service, sizeof(client_service)); if (result == SOCKET_ERROR) { closesocket(sock); printf("unable to connect to the server: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } */ if (listen(sock, 1) == SOCKET_ERROR) { closesocket(sock); printf("failed to bind to %s:%d: %ld\n", address, port, WSAGetLastError()); WSACleanup(); return 1; } /* char address[INET_ADDRSTRLEN]; InetNtop(AF_INET, &(service.sin_addr.s_addr), address, INET_ADDRSTRLEN); ntohs(service.sin_port) */ printf("now listening on %s:%d!\n", address, port); char running = 1; do { SOCKET accept_sock = accept(sock, NULL, NULL); if (accept_sock == INVALID_SOCKET) { closesocket(sock); printf("failed to accept socket connection: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } else { printf("client connected!\n"); } char recvbuf[512]; int received = 0; do { received = recv(accept_sock, recvbuf, 512, 0); char end[] = "\r\n\r\n"; char lastfour[4]; if (received > 0) { printf("bytes received: %d\n", received); printf("< "); for (int i = 0; i < received; i++) { printf("%c", recvbuf[i]); if (recvbuf[i] == '\n') { printf("< "); } for (int i = 0; i < 3; i++) { lastfour[i] = lastfour[i + 1]; } lastfour[3] = recvbuf[i]; } char matches = 1; for (int i = 0; i < 4; i++) { if (lastfour[i] != end[i]) { matches = 0; break; } } if (matches) break; } else if (received == 0) { printf("connection closed.\n"); } else { printf("recv failed: %d\n", WSAGetLastError()); } } while (received > 0); char *response = (char *)malloc(BUFFER_SIZE * 2 * sizeof(char)); size_t response_len; simple_http_ok(response, &response_len); send(accept_sock, response, response_len, 0); free(response); result = closesocket(accept_sock); if (result == SOCKET_ERROR) { printf("failed to close socket properly: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return 1; } } while (running); // close responsibly! <3 result = closesocket(sock); if (result == SOCKET_ERROR) { printf("failed to close socket properly: %d\n", WSAGetLastError()); WSACleanup(); return 1; } return 0; } void simple_http_ok(char *response, size_t *response_len) { // build header char *header = (char *)malloc(BUFFER_SIZE * sizeof(char)); snprintf(header, BUFFER_SIZE, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "Content-Length: 9\r\n" "\r\n" "meow 😺"); *response_len = 0; memcpy(response, header, strlen(header)); *response_len += strlen(header); free(header); }