Browse Source

setting response headers using function instead of struct fields

pull/2/head
Ivan Polyakov 2 years ago
parent
commit
ec7fd1d728
  1. 1
      c/keyval.c
  2. 74
      c/response.c
  3. 8
      cxx/Response.cxx
  4. 8
      examples/c/example.c
  5. 13
      examples/c/minimal.c
  6. 2
      examples/cxx/example.cxx
  7. 3
      examples/cxx/minimal.cxx
  8. 39
      include/Response.hxx
  9. 2
      include/keyval.h
  10. 4
      include/response.h
  11. 1
      servers/tcp.c

1
c/keyval.c

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
#include "keyval.h"
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

74
c/response.c

@ -6,22 +6,24 @@ @@ -6,22 +6,24 @@
#include <stdlib.h>
#include <string.h>
static size_t calc_res_headers_sz(const rpd_res *res);
static size_t calc_res_status_sz(const rpd_res *res);
static size_t calc_res_headers_sz(const rpd_keyval *res);
void rpd_res_init(rpd_res *dest)
{
dest->status = rpd_res_st_ok;
dest->location = dest->content_type = NULL;
dest->body = NULL;
rpd_keyval_init(&dest->cookie, 0);
rpd_keyval_init(&dest->headers, 5);
}
int rpd_res_headers_str(char **dest, const rpd_res *src)
{
size_t size = calc_res_headers_sz(src);
size_t size, i = 0;
char *ptr;
size = calc_res_headers_sz(&src->headers);
*dest = (char *) malloc(sizeof(char) * size);
if (!*dest) {
perror("malloc");
@ -29,12 +31,13 @@ int rpd_res_headers_str(char **dest, const rpd_res *src) @@ -29,12 +31,13 @@ int rpd_res_headers_str(char **dest, const rpd_res *src)
}
ptr = *dest;
if (src->content_type) {
ptr += sprintf(ptr, "Content-Type: %s\r\n", src->content_type);
}
if (src->location) {
ptr += sprintf(ptr, "Location: %s\r\n", src->location);
while (i < src->headers.size) {
ptr += sprintf(
ptr,
"%s: %s\r\n",
src->headers.items[i].key,
src->headers.items[i].val);
i++;
}
return 0;
@ -44,7 +47,9 @@ int rpd_res_str(char **dest, const rpd_res *res) @@ -44,7 +47,9 @@ int rpd_res_str(char **dest, const rpd_res *res)
{
size_t headers_size, size;
char *ptr, *headers;
size = headers_size = calc_res_headers_sz(res);
size = headers_size = calc_res_headers_sz(&res->headers);
size += calc_res_status_sz(res);
if (res->body)
size += 2 + strlen(res->body);
@ -78,25 +83,24 @@ int rpd_res_str(char **dest, const rpd_res *res) @@ -78,25 +83,24 @@ int rpd_res_str(char **dest, const rpd_res *res)
return 0;
}
static size_t calc_res_headers_sz(const rpd_res *res)
static size_t calc_res_status_sz(const rpd_res *res)
{
size_t size = 0;
size += strlen("Status: \r\n");
size += 3; /* plus status code */
return size;
}
size += strlen("Status: \r\n") + 3;
if (res->location) {
size += strlen("Location: \r\n") + strlen(res->location);
}
if (res->content_type) {
size += strlen("Content-Type: \r\n") + strlen(res->content_type);
}
if (res->cookie.size) {
size += strlen("Set-Cookie: \r\n") * res->cookie.size;
for (int i = 0; i < res->cookie.size; i++) {
rpd_keyval_item *item = res->cookie.items + i;
size += strlen(item->key) + strlen(item->val);
}
static size_t calc_res_headers_sz(const rpd_keyval *headers)
{
size_t size = 0, i = 0;
while (i < headers->size) {
size += strlen(headers->items[i].key);
size++; /* plus space */
size += strlen(headers->items[i].val);
size += 2; /* plus CRLF */
i++;
}
return size;
@ -106,22 +110,12 @@ void rpd_res_cleanup(rpd_res *res) @@ -106,22 +110,12 @@ void rpd_res_cleanup(rpd_res *res)
{
res->status = rpd_res_st_ok;
if (res->location) {
free(res->location);
res->location = NULL;
}
if (res->content_type) {
free(res->content_type);
res->content_type = NULL;
}
if (res->body) {
free(res->body);
res->body = NULL;
}
if (res->cookie.capacity) {
rpd_keyval_cleanup(&res->cookie);
if (res->headers.capacity) {
rpd_keyval_cleanup(&res->headers);
}
}

8
cxx/Response.cxx

@ -9,6 +9,14 @@ @@ -9,6 +9,14 @@
using namespace rpd;
int Response::header(const char *key, const char *value)
{
return rpd_keyval_insert(
&this->res->headers,
key,
value);
}
#ifdef EXTENSIONS_INJA
void Response::render(const char *path, nlohmann::json data)
{

8
examples/c/example.c

@ -28,6 +28,7 @@ static void products_handler(rpd_req *req, rpd_res *res, void *userdata) @@ -28,6 +28,7 @@ static void products_handler(rpd_req *req, rpd_res *res, void *userdata)
int bufflen = strlen(body) + strlen(cat->val) + strlen(id->val);
res->body = (char *) malloc(sizeof(char) * (bufflen + 1));
if (!res->body) {
perror("malloc");
res->status = rpd_res_st_internal_server_error;
return;
}
@ -37,12 +38,7 @@ static void products_handler(rpd_req *req, rpd_res *res, void *userdata) @@ -37,12 +38,7 @@ static void products_handler(rpd_req *req, rpd_res *res, void *userdata)
res->status = rpd_res_st_ok;
/*
* place all values in heap, please,
* because after call handler
* `req` and `res` will be freed
*/
res->content_type = strdup("text/html");
rpd_keyval_insert(&res->headers, "Content-Type", "text/html");
}
int main()

13
examples/c/minimal.c

@ -15,15 +15,18 @@ static void home_page_handler(rpd_req *req, rpd_res *res, void *userdata) @@ -15,15 +15,18 @@ static void home_page_handler(rpd_req *req, rpd_res *res, void *userdata)
/* Check request method */
switch (req->method) {
case HEAD:
/* Process GET request */
res->status = rpd_res_st_ok;
rpd_keyval_insert(&res->headers, "Content-Type", "text/plain");
break;
case GET:
res->status = rpd_res_st_ok;
rpd_keyval_insert(&res->headers, "Content-Type", "text/plain");
rpd_keyval_insert(&res->headers, "JavaScript", "Sucks");
/* Please allocate data on the heap,
/* Please allocate body on the heap,
* because after calling this handler
* Rapida will free it all.
* Rapida will free it.
*/
res->content_type = strdup("text/plain");
case GET:
res->body = strdup("Hello World!");
break;
default:

2
examples/cxx/example.cxx

@ -35,7 +35,7 @@ protected: @@ -35,7 +35,7 @@ protected:
virtual void handle_head(const rpd::Request &req, rpd::Response &res) override
{
res.status(rpd_res_st_ok);
res.content_type("text/html");
res.header("Content-Type", "text/html");
}
};

3
examples/cxx/minimal.cxx

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
#include "../../include/rapida.hxx"
#include "../../include/servers/tcp.h"
/*
* \brief Home page route handler.
*/
@ -29,7 +28,7 @@ protected: @@ -29,7 +28,7 @@ protected:
virtual void handle_head(const rpd::Request &req, rpd::Response &res) override
{
res.status(rpd_res_st_ok);
res.content_type("text/plain");
res.header("Content-Type", "text/plain");
}
};

39
include/Response.hxx

@ -59,43 +59,14 @@ public: @@ -59,43 +59,14 @@ public:
}
/*!
* \brief Sets _location_ response field.
* \brief Sets response header.
*
* \param location Location URL.
*/
void location(const char *location)
{
if (res->location)
free(res->location);
res->location = strdup(location);
}
/*!
* \brief Sets _Content-Type_ response field.
*
* \param content_type Response content type.
*/
void content_type(const char *content_type)
{
if (res->content_type)
free(res->content_type);
res->content_type = strdup(content_type);
}
/*!
* \brief Sets cookie field.
* \param key Header key.
* \param value Header value
*
* Adds new cookie field to key-value storage.
* If you need to set cookie parameters such as lifetime,
* place it to val.
*
* \param key Cookie field key.
* \param val Cookie field value.
* \return Status code. 0 is success.
*/
void cookie(const char *key, const char *val)
{
rpd_keyval_insert(&res->cookie, key, val);
}
int header(const char *key, const char *value);
/*!
* \brief Sets response body.

2
include/keyval.h

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
#ifndef RAPIDA_KEYVAL_H_ENTRY
#define RAPIDA_KEYVAL_H_ENTRY
#include "unistd.h"
#include <unistd.h>
#ifdef __cplusplus
extern "C" {

4
include/response.h

@ -86,10 +86,8 @@ enum rpd_res_statuses { @@ -86,10 +86,8 @@ enum rpd_res_statuses {
*/
typedef struct {
enum rpd_res_statuses status; /**< Response status code. */
char *location; /**< Location field. */
char *content_type; /**< Content type. */
char *body; /**< Response body. */
rpd_keyval cookie; /**< Set-Cookie fields. */
rpd_keyval headers; /**< Response headers. */
} rpd_res;
/*!

1
servers/tcp.c

@ -64,6 +64,7 @@ static void handle_request(struct mg_connection *conn, int ev, void *ev_data, vo @@ -64,6 +64,7 @@ static void handle_request(struct mg_connection *conn, int ev, void *ev_data, vo
rpd_app_handle_request((rpd_app *) app, req, res);
rpd_res_headers_str(&headers_buff, res);
puts(headers_buff);
mg_http_reply(conn, res->status, headers_buff, res->body ? res->body : "");
free(headers_buff);

Loading…
Cancel
Save