#include <sys/socket.h> /* socket definitions */ #include <sys/types.h> /* socket types */ #include <arpa/inet.h> /* inet (3) funtions */ #include <unistd.h> /* misc. UNIX functions */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <libgen.h> /* #define DEBUG */ /* Global constants */ #define ECHO_PORT (2002) #define MAX_LINE (65535) #define LISTENQ (1024) /* Backlog for listen() */ ssize_t Readline(int fd, void *vptr, size_t maxlen); ssize_t Writeline(int fc, const void *vptr, size_t maxlen); /* Read a line from a socket */ ssize_t Readline(int sockd, void *vptr, size_t maxlen) { ssize_t n, rc; char c, *buffer; buffer = vptr; for (n = 1; n < maxlen; n++) { if ((rc = read(sockd, &c, 1)) == 1) { *buffer++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return 0; else break; } else { if (errno == EINTR) continue; return -1; } } *buffer = 0; return n; } /* Write a line to a socket */ ssize_t Writeline(int sockd, const void *vptr, size_t n) { size_t nleft; ssize_t nwritten; const char *buffer; buffer = vptr; nleft = n; while (nleft > 0) { if ((nwritten = write(sockd, buffer, nleft)) <= 0) { if (errno == EINTR) nwritten = 0; else return -1; } nleft -= nwritten; buffer += nwritten; printf("LOOP"); fflush(stdout); } return n; } void show_buffer(unsigned char *buf, int len) { int i, j; char str[17]; str[16] = 0; printf("\n"); for (i = 0; i < len; i += 16) { fprintf(stdout, " "); for (j = 0; j < 16 && i + j < len; j++) { fprintf(stdout, "%02x ", buf[i + j]); if (buf[i + j] > 32 && buf[i + j] < 127) str[j] = buf[i + j]; else str[j] = '.'; } for (; j < 16; j++) { fprintf(stdout, " "); str[j] = ' '; } printf(" | %s |\n", str); } fflush(stdout); } int main(int argc, char *argv[]) { int list_s; /* listening socket */ int conn_s; /* connection socket */ short int port; /* port number */ struct sockaddr_in servaddr; /* socket address structure */ char buffer[MAX_LINE]; /* character buffer */ char *endptr; /* for strtol() */ int len; int i; /* Get port number from the command line, and set to default port if no arguments were supplied */ if (argc == 2) { port = strtol(argv[1], &endptr, 0); if (*endptr) { fprintf(stderr, "ECHOSERV: Invalid port number.\n"); exit(EXIT_FAILURE); } } else if (argc < 2) { port = ECHO_PORT; } else { fprintf(stderr, "ECHOSERV: Invalid arguments.\n"); exit(EXIT_FAILURE); } /* Create the listening socket */ if ((list_s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "ECHOSERV: Error creating listening socket.\n"); exit(EXIT_FAILURE); } /* Set all bytes in socket address structure to zero, and fill in the relevant data members */ memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); /* Bind our socket addresss to the listening socket, and call listen() */ if (bind(list_s, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { fprintf(stderr, "ECHOSERV: Error calling bind()\n"); exit(EXIT_FAILURE); } if (listen(list_s, LISTENQ) < 0) { fprintf(stderr, "ECHOSERV: Error calling listen()\n"); exit(EXIT_FAILURE); } /* Enter an infinite loop to respond to client requests and echo input */ while (1) { /* Wait for a connection, then accept() it */ if ((conn_s = accept(list_s, NULL, NULL)) < 0) { fprintf(stderr, "ECHOSERV: Error calling accept()\n"); exit(EXIT_FAILURE); } /* Retrieve an input line from the connected socket then simply write it back to the same socket. */ len = Readline(conn_s, buffer, MAX_LINE - 1); /* Writeline(conn_s, buffer, strlen(buffer)); */ if (len > 0 && len < MAX_LINE) buffer[len] = 0; else buffer[0] = 0; /* Check HTTP method */ if (strncmp(buffer, "GET ", 4) && strncmp(buffer, "get ", 4)) continue; /* buffer shuold look like 'GET URL HTTP/1.0' */ /* remove everything after URL */ for (i = 4; i < MAX_LINE; i++) { if (buffer[i] == ' ') { buffer[i] = 0; break; } } printf("%s\n", &buffer[5]); fflush(stdout); sprintf(buffer, "HTTP/1.1 404 Not Found\r\n" "Server: nginx\r\n" "Content-Type: text/html\r\n\r\n" "<html>\n" "<head><title>404 Not Found</title></head>\n" "<body bgcolor=\"white\">\n" "<center><h1>404 Not Found</h1></center>\n" "<hr><center>nginx</center>\n" "</body>\n" "</html>\n\r\n"); len = send(conn_s, buffer, strlen(buffer), 0); #ifdef DEBUG printf("sent len: %d\n", len); #endif /* Close the connected socket */ if (close(conn_s) < 0) { fprintf(stderr, "ECHOSERV: Error calling close()\n"); exit(EXIT_FAILURE); } } }