Some more refactores, added articles functionality to web server

This commit is contained in:
Dmitriy Shishkov 2020-07-04 16:41:24 +05:00
parent 4c61d24352
commit cd874d6e28
11 changed files with 238 additions and 80 deletions

View File

@ -26,4 +26,7 @@ typedef struct
#endif
int list_articles(article_info **articles);
long get_article_contents(article_info *article);
#endif

View File

@ -0,0 +1,23 @@
#ifndef _HTML_H
#define _HTML_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifndef _ARTICLE_INFO
#define _ARTICLE_INFO
typedef struct
{
char *title;
long time;
char *content;
unsigned long length;
} article_info;
#endif
int gen_html_article(article_info article, char **out);
int gen_html_article_list(article_info *articles, int n, char **out);
#endif

View File

@ -11,8 +11,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#define FILE_SIZE 1024
struct header_s {
char * str;
size_t size;

View File

@ -2,8 +2,7 @@
int list_articles(article_info **articles)
{
// FILE *file = fopen("./static/articles_list.db", "r");
FILE *file = fopen("./test_.db", "r");
FILE *file = fopen("./static/articles_list.db", "r");
if (file == NULL)
{
perror("Couldn't open db file");
@ -70,8 +69,7 @@ long get_article_contents(article_info *article)
snprintf(name, line_length, "%ld", article->time);
}
// snprintf(NULL, 0, "./static/articles/%s/%s.md", article->title, article->title);
int line_length = snprintf(NULL, 0, "./test_articles/%s/%s.md", name, name) + 1;
int line_length = snprintf(NULL, 0, "./static/articles/%s/%s.md", name, name) + 1;
char *path = malloc(line_length);
if (path == NULL)
{
@ -79,8 +77,7 @@ long get_article_contents(article_info *article)
return -1;
}
// snprintf(path, line_length, "./static/articles/%s/%s.md", article->title, article->title);
snprintf(path, line_length, "./test_articles/%s/%s.md", name, name);
snprintf(path, line_length, "./static/articles/%s/%s.md", name, name);
FILE *file = fopen(path, "r");
if (file == NULL)
@ -102,62 +99,24 @@ long get_article_contents(article_info *article)
return article->length;
}
int gen_html_article(article_info article, char **out)
{
// FILE *template = fopen("./static/article.html", "r");
FILE *template = fopen("./test_article.html", "r");
if (template == NULL)
{
perror("Couldn't open article template");
*out = "500";
return -1;
}
// /* Only for testing purposes */
// int main()
// {
// article_info *articles = malloc(0);
size_t template_size = get_file_size(template);
// int n = list_articles(&articles);
char *template_str = malloc(template_size + 1);
// printf("Read %d lines\n", n);
// printf("Last article's creation date is %ld and title is %s\n", articles[n - 1].time, articles[n - 1].title);
for (int i = 0; i < template_size; i++)
template_str[i] = fgetc(template);
template_str[template_size] = '\0';
// for (int i = 0; i < n; i++)
// get_article_contents(&(articles[i]));
*out = malloc(template_size + article.length + 1);
// printf("Got content of %d files\n", n);
char *content;
// char **html = malloc(sizeof(char *) * n);
// for (int i = 0; i < n; i++)
// gen_html_article(articles[i], &(html[i]));
process_md(article, &content);
int line_length = snprintf(NULL, 0, template_str, article.title, content) + 1;
*out = malloc(line_length);
if (*out == NULL)
{
*out = "500";
return -1;
}
snprintf(*out, line_length, template_str, article.title, content);
return line_length;
}
/* Only for testing purposes */
int main()
{
article_info *articles = malloc(0);
int n = list_articles(&articles);
printf("Read %d lines\n", n);
printf("Last article's creation date is %ld and title is %s\n", articles[n - 1].time, articles[n - 1].title);
for (int i = 0; i < n; i++)
get_article_contents(&(articles[i]));
printf("Got content of %d files\n", n);
char **html = malloc(sizeof(char *) * n);
for (int i = 0; i < n; i++)
gen_html_article(articles[i], &(html[i]));
return 0;
}
// return 0;
// }

100
src/articles_op/html.c Normal file
View File

@ -0,0 +1,100 @@
#include "../../include/articles_op/html.h"
#include "../../include/articles_op/article.h"
int gen_html_article(article_info article, char **out)
{
FILE *template = fopen("./static/articles/index.html", "r");
if (template == NULL)
{
perror("Couldn't open article template");
*out = "500";
return -1;
}
size_t template_size = get_file_size(template);
char *template_str = malloc(template_size + 1);
for (int i = 0; i < template_size; i++)
template_str[i] = fgetc(template);
template_str[template_size] = '\0';
*out = malloc(template_size + article.length + 1);
char *content;
process_md(article, &content);
int line_length = snprintf(NULL, 0, template_str, article.title, content) + 1;
*out = malloc(line_length);
if (*out == NULL)
{
*out = "500";
return -1;
}
snprintf(*out, line_length, template_str, article.title, content);
free(template_str);
return line_length;
}
int gen_html_article_list(article_info *articles, int n, char **out)
{
if (n == 0)
{
*out = "No articles found";
return 0;
}
*out = strdup("<ul>\n");
char *insert;
for (int i = 0; i < n; i++)
{
int line_length = snprintf(NULL, 0, "<li><a href=\"/article/%d\" >%s</a></li>\n", i, articles[i].title) + 1;
insert = malloc(line_length);
*out = realloc(*out, strlen(*out) + line_length);
if (insert == NULL || *out == NULL)
{
*out = "500 Memory error";
return -1;
}
snprintf(insert, line_length, "<li><a href=\"/article/%d\" >%s</a></li>\n", i, articles[i].title);
strcat(*out, insert);
}
*out = realloc(*out, strlen(*out) + strlen("</ul>") + 1);
strcat(*out, "</ul>");
free(insert);
return 0;
}
// /* Only for testing purposes */
// int main ()
// {
// article_info *articles = malloc(0);
// int n = list_articles(&articles);
// printf("Read %d lines\n", n);
// printf("Last article's creation date is %ld and title is %s\n", articles[n - 1].time, articles[n - 1].title);
// for (int i = 0; i < n; i++)
// get_article_contents(&(articles[i]));
// printf("Got content of %d files\n", n);
// char *html;
// gen_html_article_list(articles, n, &html);
// printf("-%s-\n", html);
// return 0;
// }

View File

@ -202,7 +202,7 @@ int process_md(article_info article, char **out)
snprintf(append, append_line_length, "<img src=\"%s\" alt=\"%s\"> ", src, internal_text);
strcat(*out, append);
i += i + 2 + n + 2 + k + 1;
i += 2 + n + 2 + k + 1;
free(append);
free(src);
@ -223,7 +223,7 @@ int process_md(article_info article, char **out)
int k = 0;
while (buff[i + 1 + n + 2 + k] != ')')
k++;
char *internal_text = malloc(n + 1);
memcpy(internal_text, buff + i + 1, n);
internal_text[n] = '\0';
@ -245,12 +245,14 @@ int process_md(article_info article, char **out)
snprintf(append, append_line_length, "<a href=\"%s\">%s</a> ", href, internal_text);
strcat(*out, append);
i += i + 1 + n + 2 + k + 1;
i += 1 + n + 2 + k + 1;
free(append);
free(href);
free(internal_text);
printf("++%d-%c++\n", i, buff[i]);
continue;
}
@ -264,6 +266,8 @@ int process_md(article_info article, char **out)
*out = tmp_out;
(*out)[len] = buff[i];
(*out)[len + 1] = '\0';
printf("**%d-%c**\n", i, buff[i]);
}
tmp_out = realloc(*out, strlen(*out) + strlen("</p>") + 1);
@ -290,8 +294,7 @@ int process_md(article_info article, char **out)
(*out)[len + 1] = '\0';
}
}
printf("%s\n\n***\n", *out);
(*out)[strlen(*out) - 1] = '\0';
return strlen(*out);
}

View File

@ -2,7 +2,8 @@
#include "../../include/utils_op/utils.h"
#include "../../include/file_op/file.h"
#include "../../include/file_op/mime.h"
#include "../../include/db_op/db_cli.h"
#include "../../include/articles_op/html.h"
#include "../../include/articles_op/article.h"
/**
* @brief Send 404 response
@ -34,10 +35,10 @@ void res_500(int fd)
{
char *msg = "Server error";
struct header_s *header = gen_header(500, sizeof(msg), "text/plain");
struct header_s *header = gen_header(500, strlen(msg), "text/plain");
send(fd, header->str, header->size - 1, 0);
send(fd, msg, sizeof(msg), 0);
send(fd, msg, strlen(msg), 0);
close(fd);
printf("500 ERROR\n");
@ -158,17 +159,41 @@ void handle_get_request(int fd, char *request)
char *path = get_path(request);
printf("Client accessed path: %s\n", path);
if (strcmp(path, "/") == 0)
if (strcmp(path, "/") == 0 || strcmp(path, "/index.html") == 0)
{
FILE *fp = fopen("static/index.html", "r");
char buff[FILE_SIZE], msg[FILE_SIZE * 2], articles_list_str[FILE_SIZE / 2] = {0}, blogposts_list_str[FILE_SIZE / 2] = {0};
if (fp == NULL)
{
res_404(fd, "/index.html");
return;
}
fread(buff, FILE_SIZE, 1, fp);
size_t file_size = get_file_size(fp) + 1;
char *template = malloc(file_size);
fread(template, file_size, 1, fp);
fclose(fp);
article_info *articles = malloc(0);
int amount = list_articles(&articles);
if (amount < 0)
{
res_500(fd);
return;
}
sprintf(msg, buff, articles_list_str);
char *articles_list_str;
gen_html_article_list(articles, amount, &articles_list_str);
int line_length = snprintf(NULL, 0, template, articles_list_str) + 1;
char *msg = malloc(line_length);
if (msg == NULL)
{
res_500(fd);
return;
}
snprintf(msg, line_length, template, articles_list_str);
struct header_s *header = gen_header(200, strlen(msg), "text/html");
send(fd, header->str, header->size - 1, 0);
@ -181,12 +206,49 @@ void handle_get_request(int fd, char *request)
return;
}
if (strncmp(path, "/blog/", strlen("/blog/")) == 0)
if (strncmp(path, "/article/", strlen("/article/")) == 0)
{
char *id = (char *)malloc(strlen(path) - strlen("/blog/") + 1);
memmove(id, path + strlen("/blog/"), strlen(path) - strlen("/blog/") + 1);
char *id_str = (char *)malloc(strlen(path) - strlen("/article/") + 1);
memmove(id_str, path + strlen("/article/"), strlen(path) - strlen("/article/") + 1);
printf("Blog post id = %s\n", id);
int id = strtol(id_str, NULL, 10);
if (id < 0)
{
res_404(fd, path);
return;
}
article_info *articles = malloc(0);
int amount = list_articles(&articles);
if (amount < 0)
{
res_500(fd);
return;
}
if (id > amount-1)
{
res_404(fd, path);
return;
}
get_article_contents(&(articles[id]));
char *html;
gen_html_article(articles[id], &html);
struct header_s *header = gen_header(200, strlen(html), "text/html");
send(fd, header->str, header->size - 1, 0);
send(fd, html, strlen(html), 0);
close(fd);
printf("Sent article with id=%d\n", id);
free(articles);
free(html);
return;
}
if (send_response(fd, path) < 0)

View File

@ -1,12 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>%s</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
%s
<header>
<a href="/" id="logo"><img src="/logo.png" alt="logo" /></a>
</header>
<main>
%s
</main>
</body>
</html>

View File

0
static/articles_list.db Normal file
View File

View File

@ -11,7 +11,7 @@
<body>
<header>
<a href="/" id="logo"><img src="./logo.png" alt="logo" /></a>
<a href="/" id="logo"><img src="/logo.png" alt="logo" /></a>
</header>
<main>
<h1>Home</h1>
@ -21,6 +21,7 @@
<li><a href="/projects">Projects</a></li>
<li><a href="/philosophy">Philosophy</a></li>
</ul>
<h1>Articles</h1>
%s
</main>
</body>