progress
This commit is contained in:
parent
9e1a9c7c23
commit
9fbe993f1c
@ -1,7 +1,7 @@
|
||||
TARGET=http
|
||||
CC=gcc
|
||||
|
||||
OBJ = main.o tcp.o
|
||||
OBJ = main.o tcp.o http.o
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
mkdir -p ../build
|
||||
@ -9,7 +9,8 @@ $(TARGET): $(OBJ)
|
||||
mv $(TARGET) ../build/
|
||||
|
||||
main.o: include/tcp.h
|
||||
tcp.o: include/tcp.h
|
||||
tcp.o: include/tcp.h include/http.h
|
||||
http.o: include/http.h
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
112
src/http.c
Normal file
112
src/http.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "include/http.h"
|
||||
|
||||
// what we want to do here is start parsing the http message
|
||||
|
||||
// GET / HTTP/1.1
|
||||
// Host: localhost:8080
|
||||
// User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0
|
||||
// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
// Accept-Language: en-US,en;q=0.5
|
||||
// Accept-Encoding: gzip, deflate, br, zstd
|
||||
// Connection: keep-alive
|
||||
// Upgrade-Insecure-Requests: 1
|
||||
// Sec-Fetch-Dest: document
|
||||
// Sec-Fetch-Mode: navigate
|
||||
// Sec-Fetch-Site: none
|
||||
// Sec-Fetch-User: ?1
|
||||
// Priority: u=0, i
|
||||
|
||||
http_method_t str_to_http_method(char* input)
|
||||
{
|
||||
if (strncmp(input, "GET", 3) == 0) {
|
||||
return GET;
|
||||
} else if (strncmp(input, "HEAD", 4) == 0) {
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
const char* http_method_to_str(http_method_t input)
|
||||
{
|
||||
switch (input) {
|
||||
case GET:
|
||||
return "GET";
|
||||
case HEAD:
|
||||
return "HEAD";
|
||||
case UNKNOWN:
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void parse_request_line(char** line, http_request* request)
|
||||
{
|
||||
char *tok, *ver;
|
||||
|
||||
|
||||
tok = strtok(*line, " "); // this is the method
|
||||
if (tok == NULL) {
|
||||
perror("strtok");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
request->method = str_to_http_method(tok);
|
||||
|
||||
tok = strtok(NULL, " "); // this is the request URI
|
||||
if (tok == NULL) {
|
||||
perror("strtok");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
request->request_uri = (char*) malloc(strlen(tok) + 1);
|
||||
strncpy(request->request_uri, tok, strlen(tok) + 1);
|
||||
|
||||
tok = strtok(NULL, " "); // this is the version
|
||||
if (tok == NULL) {
|
||||
perror("strtok");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ver = strtok(tok, "/");
|
||||
if (tok == NULL) {
|
||||
perror("strtok");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ver = strtok(NULL, "/");
|
||||
if (tok == NULL) {
|
||||
perror("strtok");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
request->version = atof(ver);
|
||||
}
|
||||
|
||||
void parse_http_request(char** buffer, http_request* request)
|
||||
{
|
||||
// going to be using strtok here to split up the request
|
||||
|
||||
// first lets split each line
|
||||
char* line;
|
||||
|
||||
// parse the first line
|
||||
line = strtok(*buffer, "\n");
|
||||
if (line == NULL) {
|
||||
perror("strtok");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
parse_request_line(&line, request);
|
||||
|
||||
|
||||
/**
|
||||
// parse the remaining lines
|
||||
while (line != NULL) {
|
||||
// get the rest of them
|
||||
line = strtok(NULL, "\n");
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
25
src/include/http.h
Normal file
25
src/include/http.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
typedef enum {
|
||||
GET,
|
||||
HEAD,
|
||||
UNKNOWN,
|
||||
} http_method_t;
|
||||
|
||||
typedef struct {
|
||||
http_method_t method;
|
||||
char* request_uri;
|
||||
double version;
|
||||
|
||||
} http_request;
|
||||
|
||||
|
||||
http_method_t str_to_http_method(char* input);
|
||||
const char* http_method_to_str(http_method_t input);
|
||||
|
||||
void parse_request_line(char** line, http_request* request);
|
||||
|
||||
void parse_http_request(char** buffer, http_request* request);
|
||||
|
||||
#endif
|
@ -14,9 +14,6 @@ int main(void)
|
||||
setup_socket(&server);
|
||||
puts("Server setup succesfully!");
|
||||
|
||||
// start accepting connections here
|
||||
|
||||
|
||||
puts("Accepting new connections...");
|
||||
while (true) {
|
||||
client_sock = accept(server.socket, (struct sockaddr*) &(server.server_info),
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <poll.h>
|
||||
|
||||
#include "include/tcp.h"
|
||||
#include "include/http.h"
|
||||
|
||||
void setup_socket(server_conn_t* conn)
|
||||
{
|
||||
@ -78,7 +79,7 @@ void recv_message(char** buffer, int socket)
|
||||
}
|
||||
|
||||
bytes_recv += status;
|
||||
} while (status == BUFFER_INC_LEN); // break when we stop receiving, status == 0 means no more data
|
||||
} while (status == BUFFER_INC_LEN); // break when we stop receiving, status < BUFFER_INC_LEN means no more data after this last call
|
||||
|
||||
(*buffer)[bytes_recv] = '\0';
|
||||
}
|
||||
@ -86,12 +87,17 @@ void recv_message(char** buffer, int socket)
|
||||
void* connection_handler(void* arg)
|
||||
{
|
||||
int client_socket = *(int*) arg;
|
||||
http_request request;
|
||||
char* buffer = NULL;
|
||||
|
||||
recv_message(&buffer, client_socket);
|
||||
|
||||
puts(buffer);
|
||||
|
||||
parse_http_request(&buffer, &request);
|
||||
|
||||
printf("%s %s %1.1f\n", http_method_to_str(request.method), request.request_uri, request.version);
|
||||
|
||||
/**
|
||||
* Handle HTTP request here :)
|
||||
*/
|
||||
@ -104,6 +110,7 @@ void* connection_handler(void* arg)
|
||||
//
|
||||
// send payload
|
||||
|
||||
free(buffer);
|
||||
close(client_socket);
|
||||
|
||||
return NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user