Advertisement
CSenshi

httplib

Apr 13th, 2019
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.33 KB | None | 0 0
  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9.  
  10. #include "libhttp.h"
  11.  
  12. #define LIBHTTP_REQUEST_MAX_SIZE 8192
  13.  
  14. void http_fatal_error(char *message) {
  15.   fprintf(stderr, "%s\n", message);
  16.   exit(ENOBUFS);
  17. }
  18.  
  19. struct http_request *http_request_parse(int fd) {
  20.   struct http_request *request = malloc(sizeof(struct http_request));
  21.   if (!request) http_fatal_error("Malloc failed");
  22.  
  23.   char *read_buffer = malloc(LIBHTTP_REQUEST_MAX_SIZE + 1);
  24.   if (!read_buffer) http_fatal_error("Malloc failed");
  25.  
  26.   int bytes_read = read(fd, read_buffer, LIBHTTP_REQUEST_MAX_SIZE);
  27.   read_buffer[bytes_read] = '\0'; /* Always null-terminate. */
  28.  
  29.   char *read_start, *read_end;
  30.   size_t read_size;
  31.  
  32.   do {
  33.     /* Read in the HTTP method: "[A-Z]*" */
  34.     read_start = read_end = read_buffer;
  35.     while (*read_end >= 'A' && *read_end <= 'Z') read_end++;
  36.     read_size = read_end - read_start;
  37.     if (read_size == 0) break;
  38.     request->method = malloc(read_size + 1);
  39.     memcpy(request->method, read_start, read_size);
  40.     request->method[read_size] = '\0';
  41.  
  42.     /* Read in a space character. */
  43.     read_start = read_end;
  44.     if (*read_end != ' ') break;
  45.     read_end++;
  46.  
  47.     /* Read in the path: "[^ \n]*" */
  48.     read_start = read_end;
  49.     while (*read_end != '\0' && *read_end != ' ' && *read_end != '\n') read_end++;
  50.     read_size = read_end - read_start;
  51.     if (read_size == 0) break;
  52.     request->path = malloc(read_size + 1);
  53.     memcpy(request->path, read_start, read_size);
  54.     request->path[read_size] = '\0';
  55.  
  56.     /* Read in HTTP version and rest of request line: ".*" */
  57.     read_start = read_end;
  58.     while (*read_end != '\0' && *read_end != '\n') read_end++;
  59.     if (*read_end != '\n') break;
  60.     read_end++;
  61.  
  62.     free(read_buffer);
  63.     return request;
  64.   } while (0);
  65.  
  66.   /* An error occurred. */
  67.   free(request);
  68.   free(read_buffer);
  69.   return NULL;
  70.  
  71. }
  72.  
  73. char* http_get_response_message(int status_code) {
  74.   switch (status_code) {
  75.     case 100:
  76.       return "Continue";
  77.     case 200:
  78.       return "OK";
  79.     case 301:
  80.       return "Moved Permanently";
  81.     case 302:
  82.       return "Found";
  83.     case 304:
  84.       return "Not Modified";
  85.     case 400:
  86.       return "Bad Request";
  87.     case 401:
  88.       return "Unauthorized";
  89.     case 403:
  90.       return "Forbidden";
  91.     case 404:
  92.       return "Not Found";
  93.     case 405:
  94.       return "Method Not Allowed";
  95.     default:
  96.       return "Internal Server Error";
  97.   }
  98. }
  99.  
  100. void http_start_response(int fd, int status_code) {
  101.   dprintf(fd, "HTTP/1.0 %d %s\r\n", status_code,
  102.       http_get_response_message(status_code));
  103. }
  104.  
  105. void http_send_header(int fd, char *key, char *value) {
  106.   dprintf(fd, "%s: %s\r\n", key, value);
  107. }
  108.  
  109. void http_end_headers(int fd) {
  110.   dprintf(fd, "\r\n");
  111. }
  112.  
  113. void http_send_string(int fd, char *data) {
  114.   http_send_data(fd, data, strlen(data));
  115. }
  116.  
  117. void http_send_data(int fd, char *data, size_t size) {
  118.   ssize_t bytes_sent;
  119.   while (size > 0) {
  120.     bytes_sent = write(fd, data, size);
  121.     if (bytes_sent < 0)
  122.       return;
  123.     size -= bytes_sent;
  124.     data += bytes_sent;
  125.   }
  126. }
  127.  
  128. void http_send_data_from_file(int fd, char *path){
  129.     int file_fd = open(path, O_RDONLY, 0644);
  130.     if (file_fd == -1) {
  131.         perror("");
  132.     } else {
  133.         int BUF_SIZE = 1024;
  134.         char buff[BUF_SIZE];
  135.         int bytes_read = 0;
  136.         while (bytes_read = read(file_fd, buff, BUF_SIZE), bytes_read > 0) {
  137.             http_send_data(fd, buff, bytes_read);
  138.         }
  139.     }
  140. }
  141.  
  142. char *http_get_mime_type(char *file_name) {
  143.   char *file_extension = strrchr(file_name, '.');
  144.   if (file_extension == NULL) {
  145.     return "text/plain";
  146.   }
  147.  
  148.   if (strcmp(file_extension, ".html") == 0 || strcmp(file_extension, ".htm") == 0) {
  149.     return "text/html";
  150.   } else if (strcmp(file_extension, ".jpg") == 0 || strcmp(file_extension, ".jpeg") == 0) {
  151.     return "image/jpeg";
  152.   } else if (strcmp(file_extension, ".png") == 0) {
  153.     return "image/png";
  154.   } else if (strcmp(file_extension, ".css") == 0) {
  155.     return "text/css";
  156.   } else if (strcmp(file_extension, ".js") == 0) {
  157.     return "application/javascript";
  158.   } else if (strcmp(file_extension, ".pdf") == 0) {
  159.     return "application/pdf";
  160.   } else {
  161.     return "text/plain";
  162.   }
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement