init
This commit is contained in:
commit
0a3dc4a56a
3 changed files with 156 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/serv
|
||||||
|
/vgcore.*
|
2
Makefile
Normal file
2
Makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
make:
|
||||||
|
gcc ./src/*.c -O3 -o ./serv
|
152
src/http.c
Normal file
152
src/http.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define MAX_MSG 1024*1024*16
|
||||||
|
#define LISTEN_BACKLOG 50
|
||||||
|
#define THREADS 8
|
||||||
|
#define MAX_HEADERS 1024
|
||||||
|
|
||||||
|
struct header {
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header_list {
|
||||||
|
size_t header_count;
|
||||||
|
struct header *header_data;
|
||||||
|
size_t storage_count;
|
||||||
|
char *storage_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void handle_error(char *msg) {
|
||||||
|
perror(msg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct header_list push_header(struct header_list headers, char *key, char *value) {
|
||||||
|
if (headers.header_count >= MAX_HEADERS - 1) return headers;
|
||||||
|
|
||||||
|
int len = headers.storage_count + 1;
|
||||||
|
snprintf(&headers.storage_data[len],MAX_MSG - len,"%s",key);
|
||||||
|
len += strlen(key) + 1;
|
||||||
|
snprintf(&headers.storage_data[len],MAX_MSG - len,"%s",value);
|
||||||
|
len += strlen(value) + 1;
|
||||||
|
headers.storage_count = len;
|
||||||
|
|
||||||
|
struct header new_header;
|
||||||
|
new_header.value = &headers.storage_data[len - strlen(value) - 1];
|
||||||
|
new_header.key = &headers.storage_data[len - strlen(value) - strlen(key) - 2];
|
||||||
|
headers.header_data[headers.header_count] = new_header;
|
||||||
|
headers.header_count++;
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *parse_header(char *tmp, char *msg, struct header_list headers) {
|
||||||
|
for (int i = 0; i < headers.header_count; i++) {
|
||||||
|
struct header dat = headers.header_data[i];
|
||||||
|
snprintf(tmp,MAX_MSG,"%s\n%s: %s",msg,dat.key,dat.value);
|
||||||
|
memcpy(msg,tmp,MAX_MSG);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* use_sock(void* cfd2) {
|
||||||
|
printf("%s\n","Request is being sent");
|
||||||
|
int cfd = (int) cfd2;
|
||||||
|
|
||||||
|
char *msg = malloc(MAX_MSG);
|
||||||
|
char *tmp = malloc(MAX_MSG);
|
||||||
|
char *num = malloc(MAX_MSG);
|
||||||
|
char *html = "Balls man is cool";
|
||||||
|
|
||||||
|
struct header_list headers;
|
||||||
|
headers.header_count = 0;
|
||||||
|
headers.storage_count = 0;
|
||||||
|
|
||||||
|
headers.header_data = calloc(MAX_HEADERS, sizeof(struct header));
|
||||||
|
headers.storage_data = malloc(MAX_MSG);
|
||||||
|
|
||||||
|
memset(headers.storage_data,0,MAX_MSG);
|
||||||
|
|
||||||
|
tmp[0] = '\0';
|
||||||
|
|
||||||
|
headers = push_header(headers,"Content-Type","text/html");
|
||||||
|
snprintf(num,MAX_MSG,"%d",strlen(html));
|
||||||
|
headers = push_header(headers,"Content-Length",num);
|
||||||
|
|
||||||
|
parse_header(tmp, msg, headers);
|
||||||
|
|
||||||
|
snprintf(msg, MAX_MSG, "HTTP/1.1 200 OK%s\n\n%s", tmp, html);
|
||||||
|
|
||||||
|
printf("%s\n",msg);
|
||||||
|
|
||||||
|
send(cfd,msg,strlen(msg),0);
|
||||||
|
close(cfd);
|
||||||
|
|
||||||
|
free(msg);
|
||||||
|
free(tmp);
|
||||||
|
free(num);
|
||||||
|
|
||||||
|
return (void*) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// credit to the man docs
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int sfd, cfd, thread_num;
|
||||||
|
struct sockaddr_in my_addr, peer_addr;
|
||||||
|
socklen_t peer_addr_size;
|
||||||
|
pthread_t* thread_list;
|
||||||
|
|
||||||
|
sfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sfd == -1)
|
||||||
|
handle_error("socket");
|
||||||
|
|
||||||
|
memset(&my_addr, 0, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
|
my_addr.sin_family = AF_INET;
|
||||||
|
my_addr.sin_port = htons(8000);
|
||||||
|
my_addr.sin_addr.s_addr = htonl(0x7F000001);
|
||||||
|
|
||||||
|
if (bind(sfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in)) == -1)
|
||||||
|
handle_error("bind");
|
||||||
|
|
||||||
|
if (listen(sfd, LISTEN_BACKLOG) == -1)
|
||||||
|
handle_error("listen");
|
||||||
|
|
||||||
|
peer_addr_size = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
thread_list = calloc(THREADS,sizeof(pthread_t));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < THREADS; i++) {
|
||||||
|
thread_list[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_num = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_size);
|
||||||
|
|
||||||
|
if (cfd == -1)
|
||||||
|
handle_error("accept");
|
||||||
|
|
||||||
|
if (thread_list[thread_num] != -1) {
|
||||||
|
pthread_join(thread_list[thread_num],NULL);
|
||||||
|
|
||||||
|
thread_list[thread_num] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_create(&thread_list[thread_num],NULL,use_sock,(void*)cfd);
|
||||||
|
|
||||||
|
thread_num = (thread_num + 1) % THREADS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free(thread_list);
|
||||||
|
}
|
Loading…
Reference in a new issue