Add read from file
This commit is contained in:
parent
29bbb28f41
commit
0b924ca966
6
include/arrayHelper.h
Normal file
6
include/arrayHelper.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ARRAYHELPER_H
|
||||||
|
#define ARRAYHELPER_H
|
||||||
|
|
||||||
|
char *mergeArray(char *arr1, char *arr2);
|
||||||
|
|
||||||
|
#endif
|
@ -1,16 +0,0 @@
|
|||||||
#ifndef IPADDRESS_H
|
|
||||||
#define IPADDRESS_H
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define MAX_LINE_LENGTH (1024)
|
|
||||||
|
|
||||||
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
|
|
||||||
|
|
||||||
int extract_ip_address_from_header(char *line, char *address);
|
|
||||||
char *get_ip_address(FILE *f);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,13 +1,26 @@
|
|||||||
#ifndef SERVER_H
|
#ifndef SERVER_H
|
||||||
#define SERVER_H
|
#define SERVER_H
|
||||||
|
|
||||||
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
void send_response(FILE *f, char *html);
|
#define BUFFER_SIZE 1024
|
||||||
int open_connection(int port);
|
|
||||||
void accept_client(int sock, char *key);
|
// This code has been borrowed from this github repo https://bruinsslot.jp/post/simple-http-webserver-in-c/ and modified by me.
|
||||||
void send_only(int port, char *key);
|
|
||||||
|
struct setup {
|
||||||
|
struct sockaddr_in host_addr;
|
||||||
|
struct sockaddr_in client_addr;
|
||||||
|
int sockfd;
|
||||||
|
int host_addrlen;
|
||||||
|
int client_addrlen;
|
||||||
|
char *response;
|
||||||
|
};
|
||||||
|
|
||||||
|
void serve(struct setup s);
|
||||||
|
|
||||||
#endif
|
#endif
|
15
src/arrayHelper.c
Normal file
15
src/arrayHelper.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../include/arrayHelper.h"
|
||||||
|
|
||||||
|
char *mergeArray(char *arr1, char *arr2){
|
||||||
|
int arrSize1 = sizeof(arr1);
|
||||||
|
int arrSize2 = sizeof(arr2);
|
||||||
|
int totalSize = arrSize1 + arrSize2;
|
||||||
|
char *total = malloc(totalSize * sizeof(char));
|
||||||
|
|
||||||
|
memcpy(total, arr1, arrSize1 * sizeof(char));
|
||||||
|
memcpy(total + arrSize2, arr2, arrSize2 * sizeof(char));
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "../include/ipaddress.h"
|
|
||||||
|
|
||||||
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
|
|
||||||
|
|
||||||
int extract_ip_address_from_header(char *line, char *address) {
|
|
||||||
int found = 0;
|
|
||||||
char *ptr;
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
|
|
||||||
name = strndup(line, MAX_LINE_LENGTH);
|
|
||||||
ptr = index(name, (int)':');
|
|
||||||
if (ptr == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// end the string at the colon
|
|
||||||
*ptr = '\0';
|
|
||||||
|
|
||||||
// get the value part of the header field
|
|
||||||
ptr = index(line, (int) ':');
|
|
||||||
value = strndup(ptr + 2, MAX_LINE_LENGTH);
|
|
||||||
|
|
||||||
// most ugly way to remove \r\n from the end of the string
|
|
||||||
value[strlen(value)-2] = '\0';
|
|
||||||
|
|
||||||
if (strncmp(name, "X-Forwarded-For", MAX_LINE_LENGTH) == 0) {
|
|
||||||
found = 1;
|
|
||||||
strncpy(address, value, MAX_LINE_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
free(value);
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *get_ip_address(FILE *f) {
|
|
||||||
int address_found = 0;
|
|
||||||
char *res;
|
|
||||||
char *ip_address = malloc (sizeof (char) * MAX_LINE_LENGTH);
|
|
||||||
char header_line[MAX_LINE_LENGTH];
|
|
||||||
|
|
||||||
do {
|
|
||||||
res = fgets(header_line, MAX_LINE_LENGTH, f);
|
|
||||||
|
|
||||||
if (res != NULL) {
|
|
||||||
printf("%s", res);
|
|
||||||
|
|
||||||
if (!address_found) {
|
|
||||||
address_found = extract_ip_address_from_header(res, ip_address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (res != NULL && strcmp(header_line, "\r\n") != 0);
|
|
||||||
|
|
||||||
return ip_address;
|
|
||||||
}
|
|
78
src/main.c
78
src/main.c
@ -1,27 +1,79 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "../include/arrayHelper.h"
|
||||||
#include "../include/fileReader.h"
|
#include "../include/fileReader.h"
|
||||||
#include "../include/server.h"
|
#include "../include/server.h"
|
||||||
#include "../include/ipaddress.h"
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define PORT 3090
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if(argc <= 1) {
|
|
||||||
printf("Please provide options. \n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *file = NULL;
|
char *file = NULL;
|
||||||
|
file = ReadHTML("/home/skingging/Documents/Projects/C/C-Webserver/HTML/index.html");
|
||||||
|
|
||||||
if(strcasecmp(argv[0], "cache")) {
|
char buffer[BUFFER_SIZE];
|
||||||
file = ReadHTML("/home/skingging/Documents/Projects/C/C-Webserver/HTML/index.html");
|
char resp[] = "HTTP/1.0 200 OK\r\n"
|
||||||
|
"Server: webserver-c\r\n"
|
||||||
|
"Content-type: text/html\r\n\r\n"
|
||||||
|
"<html>hello, world</html>\r\n";
|
||||||
|
|
||||||
|
char *temp = mergeArray(resp, file);
|
||||||
|
|
||||||
|
// Create a socket
|
||||||
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (sockfd == -1) {
|
||||||
|
perror("webserver (socket)");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int port = 3090;
|
printf("socket created successfully\n");
|
||||||
send_only(port, "address");
|
|
||||||
exit(EXIT_SUCCESS);
|
// Create the address to bind the socket to
|
||||||
|
struct sockaddr_in host_addr;
|
||||||
|
int host_addrlen = sizeof(host_addr);
|
||||||
|
|
||||||
|
host_addr.sin_family = AF_INET;
|
||||||
|
host_addr.sin_port = htons(PORT);
|
||||||
|
host_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
|
// Create client address
|
||||||
|
struct sockaddr_in client_addr;
|
||||||
|
int client_addrlen = sizeof(client_addr);
|
||||||
|
|
||||||
|
// Bind the socket to the address
|
||||||
|
if (bind(sockfd, (struct sockaddr *)&host_addr, host_addrlen) != 0) {
|
||||||
|
perror("webserver (bind)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("socket successfully bound to address\n");
|
||||||
|
|
||||||
|
// Listen for incoming connections
|
||||||
|
if (listen(sockfd, SOMAXCONN) != 0) {
|
||||||
|
perror("webserver (listen)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("server listening for connections\n");
|
||||||
|
|
||||||
|
struct setup s;
|
||||||
|
|
||||||
|
s.client_addr = client_addr;
|
||||||
|
s.client_addrlen = client_addrlen;
|
||||||
|
s.host_addr = host_addr;
|
||||||
|
s.host_addrlen = host_addrlen;
|
||||||
|
s.response = resp;
|
||||||
|
s.sockfd = sockfd;
|
||||||
|
|
||||||
|
serve(s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
143
src/server.c
143
src/server.c
@ -1,103 +1,60 @@
|
|||||||
|
#include <arpa/inet.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "../include/ipaddress.h"
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "../include/server.h"
|
#include "../include/server.h"
|
||||||
|
|
||||||
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
|
// This code has been borrowed from this github repo https://bruinsslot.jp/post/simple-http-webserver-in-c/ and modified by me.
|
||||||
|
|
||||||
void send_response(FILE *f, char *html)
|
#define PORT 3090
|
||||||
{
|
#define BUFFER_SIZE 1024
|
||||||
fprintf(f, "HTTP/1.1 200 OK\r\n");
|
|
||||||
fprintf(f, "Content-Type: application/html\r\n");
|
|
||||||
fprintf(f, "\r\n");
|
|
||||||
fprintf(f, "%s", html);
|
|
||||||
}
|
|
||||||
|
|
||||||
int open_connection(int port)
|
void serve(struct setup s) {
|
||||||
{
|
char buffer[BUFFER_SIZE];
|
||||||
int sock;
|
|
||||||
struct sockaddr_in addr_in;
|
|
||||||
|
|
||||||
printf("simpleserver::Creating socket: (%d, %d, 0)\n", AF_INET, SOCK_STREAM);
|
for (;;) {
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
// Accept incoming connections
|
||||||
printf("simpleserver::Socket created (%d)\n", sock);
|
int newsockfd = accept(s.sockfd, (struct sockaddr *)&s.host_addr, (socklen_t *)&s.host_addrlen);
|
||||||
|
|
||||||
if (sock == -1)
|
if (newsockfd < 0) {
|
||||||
{
|
perror("webserver (accept)");
|
||||||
printf("Failed to create socket (%d)\n", errno);
|
continue;
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
printf("connection accepted\n");
|
||||||
addr_in.sin_family = AF_INET;
|
|
||||||
addr_in.sin_port = htons(port);
|
|
||||||
addr_in.sin_addr.s_addr = INADDR_ANY;
|
|
||||||
|
|
||||||
printf("simpleserver::bind (%d, (%d, %d, %d), %lu)\n", sock, addr_in.sin_family, addr_in.sin_port, addr_in.sin_addr.s_addr, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
int lol = bind(sock, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
printf("simpleserver::listen(%d, 8)\n", sock);
|
|
||||||
|
|
||||||
if (listen(sock, 8) == -1)
|
|
||||||
{
|
|
||||||
printf("Failed to get socket to listen (%d)\n", errno);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void accept_client(int sock, char *key)
|
// Get client address
|
||||||
{
|
int sockn = getsockname(newsockfd, (struct sockaddr *)&s.client_addr, (socklen_t *)&s.client_addrlen);
|
||||||
struct sockaddr_in client_addr;
|
|
||||||
socklen_t clientaddr_len;
|
if (sockn < 0) {
|
||||||
FILE *f;
|
perror("webserver (getsockname)");
|
||||||
|
continue;
|
||||||
printf("simpleserver::accept(%d)\n", sock);
|
}
|
||||||
|
|
||||||
int client_sock = accept(sock, (struct sockaddr *)&client_addr, &clientaddr_len);
|
|
||||||
printf("simpleserver::accepted (%d)\n", client_sock);
|
|
||||||
|
|
||||||
if (client_sock == -1)
|
|
||||||
{
|
|
||||||
printf("Failed to accept connection (%d)\n", errno);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("simpleserver::fdopen(%d)\n", client_sock);
|
|
||||||
|
|
||||||
f = fdopen(client_sock, "w+");
|
|
||||||
|
|
||||||
if (f == NULL){
|
|
||||||
printf("simpleserver::Error during fdopen\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("simpleserver::send_response(%s)\n", key);
|
|
||||||
send_response(f, "<h1>Hello</h1>");
|
|
||||||
|
|
||||||
printf("simpleserver::fclose()\n");
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
printf("simpleserver::fflush\n");
|
|
||||||
// stdout needs to be flushed in order for heroku to read the logs
|
|
||||||
fflush(stdout);
|
|
||||||
printf("simpleserver::endfflush\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_only(int port, char *key)
|
// Read from the socket
|
||||||
{
|
int valread = read(newsockfd, buffer, BUFFER_SIZE);
|
||||||
int sock = open_connection(port);
|
|
||||||
|
if (valread < 0) {
|
||||||
while (1)
|
perror("webserver (read)");
|
||||||
{
|
continue;
|
||||||
accept_client(sock, key);
|
}
|
||||||
|
|
||||||
|
// Read the request
|
||||||
|
char method[BUFFER_SIZE], uri[BUFFER_SIZE], version[BUFFER_SIZE];
|
||||||
|
|
||||||
|
sscanf(buffer, "%s %s %s", method, uri, version);
|
||||||
|
|
||||||
|
printf("[%s:%u] %s %s %s\n", inet_ntoa(s.client_addr.sin_addr), ntohs(s.client_addr.sin_port), method, version, uri);
|
||||||
|
|
||||||
|
// Write to the socket
|
||||||
|
int valwrite = write(newsockfd, s.response, strlen(s.response));
|
||||||
|
|
||||||
|
if (valwrite < 0) {
|
||||||
|
perror("webserver (write)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(newsockfd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
close(sock);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user