first
This commit is contained in:
5
source/CMakeLists.txt
Normal file
5
source/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
# ADD SOURCES HERE
|
||||
|
||||
|
||||
add_executable(${PROJECT_NAME})
|
||||
target_sources(${PROJECT_NAME} PRIVATE http.c main.c)
|
||||
113
source/http.c
Normal file
113
source/http.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "http.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
HttpRequestHeader* createHttpRequest(char* uri, unsigned char method, char* host, char* accept, char* user_agent) {
|
||||
HttpRequestHeader* request = (HttpRequestHeader*) malloc(sizeof(HttpRequestHeader));
|
||||
|
||||
if(request != NULL) {
|
||||
request->http_version = (char*) malloc(strlen("HTTP/1.1") + 1);
|
||||
strcpy(request->http_version, "HTTP/1.1");
|
||||
request->uri = (char*)malloc(strlen(uri) + 1);
|
||||
strcpy((char*)request->uri, uri);
|
||||
|
||||
request->method = method;
|
||||
|
||||
request->host = (char*)malloc(strlen(host) + 1);
|
||||
strcpy((char*)request->host, host);
|
||||
|
||||
request->accept = (char*)malloc(strlen(accept) + 1);
|
||||
strcpy((char*)request->accept, accept);
|
||||
|
||||
request->user_agent = (char*)malloc(strlen(user_agent) + 1);
|
||||
strcpy((char*)request->user_agent, user_agent);
|
||||
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function to receive an HTTP response
|
||||
HttpResponseHeader* createHttpResponse(int statusCode,const char* contextType,
|
||||
char* data, char* buffer, int bs) {
|
||||
// TO DO: implement the actual receiving logic
|
||||
HttpResponseHeader* response = (HttpResponseHeader*)malloc(sizeof(HttpResponseHeader));
|
||||
response->http_version = (char*) malloc(strlen("HTTP/1.1") + 1);
|
||||
strcpy(response->http_version, "HTTP/1.1");
|
||||
response->content_length = strlen(data);
|
||||
response->content_type = (char*) malloc(strlen(contextType)+1);
|
||||
strcpy(response->content_type, contextType);
|
||||
switch(statusCode) {
|
||||
case 100:
|
||||
response->status_code = 100;
|
||||
response->status_text = (char*) malloc(strlen("Continue") + 1);
|
||||
strcpy(response->status_text, "Continue");
|
||||
break;
|
||||
case 200:
|
||||
response->status_code = 200;
|
||||
response->status_text = (char*) malloc(strlen("OK") + 1);
|
||||
strcpy(response->status_text, "OK");
|
||||
break;
|
||||
case 201:
|
||||
response->status_code = 201;
|
||||
response->status_text = (char*) malloc(strlen("Created") + 1);
|
||||
strcpy(response->status_text, "Created");
|
||||
break;
|
||||
case 301:
|
||||
response->status_code = 301;
|
||||
response->status_text = (char*) malloc(strlen("Moved Permanently") + 1);
|
||||
strcpy(response->status_text, "Moved Permanently");
|
||||
break;
|
||||
case 404:
|
||||
response->status_code = 404;
|
||||
response->status_text = (char*) malloc(strlen("Not Found") + 1);
|
||||
strcpy(response->status_text, "Not Found");
|
||||
break;
|
||||
default:
|
||||
response->status_code = statusCode;
|
||||
response->status_text = (char*) malloc(strlen("Unknown") + 1);
|
||||
strcpy(response->status_text, "Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
HttpResponseHeaderToS(response, data, buffer, bs);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void HttpResponseHeaderToS(HttpResponseHeader* rh,char* d, char* buffer, int bs) {
|
||||
|
||||
|
||||
snprintf(buffer, 512,
|
||||
"%s %u %s\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Server: My Simple Web Server\r\n\r\n%s",
|
||||
rh->http_version, rh->status_code, rh->status_text,
|
||||
rh->content_type, rh->content_length, d);
|
||||
|
||||
}
|
||||
|
||||
// Function to free the memory allocated for an HTTP request header
|
||||
void freeHttpRequest(HttpRequestHeader* request) {
|
||||
if (request == NULL) return;
|
||||
if (request->uri != NULL) free(request->uri);
|
||||
if (request->http_version != NULL) free(request->http_version);
|
||||
if (request->host != NULL) free(request->host);
|
||||
if (request->accept != NULL) free(request->accept);
|
||||
if (request->user_agent != NULL) free(request->user_agent);
|
||||
}
|
||||
|
||||
// Function to free the memory allocated for an HTTP response header
|
||||
void freeHttpResponse(HttpResponseHeader* response) {
|
||||
if (response == NULL) return;
|
||||
if (response->http_version != NULL) free(response->http_version);
|
||||
if (response->status_text != NULL) free(response->status_text);
|
||||
}
|
||||
|
||||
80
source/http.h
Normal file
80
source/http.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* #############################################################################
|
||||
* Http Send and response.
|
||||
*
|
||||
* This file handles all of the http response and requests
|
||||
*
|
||||
* #############################################################################
|
||||
* */
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
|
||||
#define HTTP_GET 1
|
||||
#define HTTP_POST 2
|
||||
#define HTTP_PUT 3
|
||||
#define HTTP_DELETE 4
|
||||
#define HTTP_HEAD 5
|
||||
#define HTTP_OPTIONS 6
|
||||
#define HTTP_PATCH 7
|
||||
#define HTTP_CONNECT 8
|
||||
#define HTTP_TRACE 9
|
||||
|
||||
|
||||
#ifndef HTTP_CONTENT_TYPES_H
|
||||
#define HTTP_CONTENT_TYPES_H
|
||||
|
||||
// Define HTTP Content Types
|
||||
#define HTTP_CONTENT_TYPE_HTML "text/html"
|
||||
#define HTTP_CONTENT_TYPE_CSS "text/css"
|
||||
#define HTTP_CONTENT_TYPE_JS "application/javascript"
|
||||
#define HTTP_CONTENT_TYPE_JSON "application/json"
|
||||
#define HTTP_CONTENT_TYPE_XML "application/xml"
|
||||
#define HTTP_CONTENT_TYPE_TEXT "text/plain"
|
||||
#define HTTP_CONTENT_TYPE_FORM "application/x-www-form-urlencoded"
|
||||
#define HTTP_CONTENT_TYPE_IMAGE_GIF "image/gif"
|
||||
#define HTTP_CONTENT_TYPE_IMAGE_JPG "image/jpeg"
|
||||
#define HTTP_CONTENT_TYPE_IMAGE_PNG "image/png"
|
||||
#define HTTP_CONTENT_TYPE_IMAGE_BMP "image/bmp"
|
||||
|
||||
#endif // HTTP_CONTENT_TYPES_H
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
char* http_version; // HTTP version and status code (e.g., "HTTP/1.1 200 OK")
|
||||
char* content_type; // Content type (e.g., "text/html; charset=UTF-8")
|
||||
int content_length; // Size of the response body in bytes
|
||||
char* last_modified; // Date and time when the resource was last modified
|
||||
char* etag; // Unique identifier for the resource (e.g., "abcdefg")
|
||||
char* server; // Information about the web server software (e.g., "Apache/2.4.41 (Ubuntu)")
|
||||
unsigned int status_code;
|
||||
char* status_text;
|
||||
} HttpResponseHeader;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char method; // e.g., "GET", "POST", etc.
|
||||
char* uri; // The requested URI
|
||||
char* http_version; // The HTTP version (e.g., "HTTP/1.1")
|
||||
char* host; // The host name or IP address of the server
|
||||
char* accept; // The accepted content type(s)
|
||||
char* user_agent; // The user agent string
|
||||
} HttpRequestHeader;
|
||||
|
||||
HttpRequestHeader* createHttpRequest(char* uri, unsigned char method,
|
||||
char* host, char* accept, char* user_agent);
|
||||
HttpResponseHeader* createHttpResponse(int statusCode,const char* contentType,
|
||||
char* data, char* buffer, int bs);
|
||||
|
||||
|
||||
void HttpResponseHeaderToS(HttpResponseHeader* rh, char* d, char* buffer, int bs);
|
||||
void HttpRequestHeaderToS(HttpRequestHeader* rh, char* buffer);
|
||||
|
||||
// Freeing Objects
|
||||
void freeHttpRequest(HttpRequestHeader* request);
|
||||
void freeHttpResponse(HttpResponseHeader* response);
|
||||
|
||||
|
||||
#endif // HTTP_H
|
||||
64
source/main.c
Normal file
64
source/main.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* #############################################################################
|
||||
* # DesingedWorlds
|
||||
*
|
||||
*
|
||||
* AUTHER: PreacherDHM
|
||||
* DATE: MM/DD/YY
|
||||
* #############################################################################
|
||||
*/
|
||||
|
||||
#include "http.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
int main() {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(9090);
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||
|
||||
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
perror("bind");
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen(sock, 3);
|
||||
printf("Server started. Listening on port 9090.\n");
|
||||
|
||||
while (1) {
|
||||
int client_sock = accept(sock, NULL, NULL);
|
||||
if (client_sock < 0) {
|
||||
perror("accept");
|
||||
continue;
|
||||
}
|
||||
|
||||
char* response = (char*)malloc(512); // Assuming a maximum length of 512 bytes
|
||||
|
||||
HttpResponseHeader* header = createHttpResponse(200, HTTP_CONTENT_TYPE_HTML,
|
||||
"<h1>This is a test to see what happends</h1>", response, 512);
|
||||
|
||||
|
||||
printf("%s\n", response);
|
||||
|
||||
|
||||
printf("Sent 'Hello, World!' to the client.\n");
|
||||
|
||||
send(client_sock, response, strlen(response)+1, 0);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user