|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "http_total.h"
|
|
|
|
#include "panic.h"
|
|
|
|
|
|
|
|
#define HTTP_MAX_HEADER_COUNT 16
|
|
|
|
#define HTTP_MAX_HEADER_LENGTH 32
|
|
|
|
#define HTTP_MAX_HEADER_VALUE_LENGTH 64
|
|
|
|
|
|
|
|
#define HTTP_RESPONSE_400_BAD_REQUEST \
|
|
|
|
"HTTP/1.1 400 Bad Request\r\n" \
|
|
|
|
"Server: SLEdge\r\n" \
|
|
|
|
"Connection: close\r\n" \
|
|
|
|
"\r\n"
|
|
|
|
|
|
|
|
|
|
|
|
#define HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE \
|
|
|
|
"HTTP/1.1 413 Payload Too Large\r\n" \
|
|
|
|
"Server: SLEdge\r\n" \
|
|
|
|
"Connection: close\r\n" \
|
|
|
|
"\r\n"
|
|
|
|
|
|
|
|
#define HTTP_RESPONSE_503_SERVICE_UNAVAILABLE \
|
|
|
|
"HTTP/1.1 503 Service Unavailable\r\n" \
|
|
|
|
"Server: SLEdge\r\n" \
|
|
|
|
"Connection: close\r\n" \
|
|
|
|
"\r\n"
|
|
|
|
|
|
|
|
#define HTTP_RESPONSE_200_TEMPLATE \
|
|
|
|
"HTTP/1.1 200 OK\r\n" \
|
|
|
|
"Server: SLEdge\r\n" \
|
|
|
|
"Connection: close\r\n" \
|
|
|
|
"Content-Type: %s\r\n" \
|
|
|
|
"Content-Length: %lu\r\n" \
|
|
|
|
"\r\n"
|
|
|
|
|
|
|
|
/* The sum of format specifier characters in the template above */
|
|
|
|
#define HTTP_RESPONSE_200_TEMPLATE_FORMAT_SPECIFIER_LENGTH 5
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the number of bytes of the HTTP response containing the passed header values
|
|
|
|
* @return total size in bytes
|
|
|
|
*/
|
|
|
|
static inline size_t
|
|
|
|
http_response_200_size(const char *content_type, ssize_t content_length)
|
|
|
|
{
|
|
|
|
size_t size = 0;
|
|
|
|
size += strlen(HTTP_RESPONSE_200_TEMPLATE) - HTTP_RESPONSE_200_TEMPLATE_FORMAT_SPECIFIER_LENGTH;
|
|
|
|
size += strlen(content_type);
|
|
|
|
|
|
|
|
while (content_length > 0) {
|
|
|
|
content_length /= 10;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
http_header_200_build(char *buffer, const char *content_type, ssize_t content_length)
|
|
|
|
{
|
|
|
|
return sprintf(buffer, HTTP_RESPONSE_200_TEMPLATE, content_type, content_length);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline const char *
|
|
|
|
http_header_build(int status_code)
|
|
|
|
{
|
|
|
|
const char *response;
|
|
|
|
int rc;
|
|
|
|
switch (status_code) {
|
|
|
|
case 503:
|
|
|
|
response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE;
|
|
|
|
http_total_increment_5XX();
|
|
|
|
break;
|
|
|
|
case 413:
|
|
|
|
response = HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE;
|
|
|
|
http_total_increment_4XX();
|
|
|
|
break;
|
|
|
|
case 400:
|
|
|
|
response = HTTP_RESPONSE_400_BAD_REQUEST;
|
|
|
|
http_total_increment_4XX();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
panic("%d is not a valid status code\n", status_code);
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
http_header_len(int status_code)
|
|
|
|
{
|
|
|
|
switch (status_code) {
|
|
|
|
case 503:
|
|
|
|
return strlen(HTTP_RESPONSE_503_SERVICE_UNAVAILABLE);
|
|
|
|
case 413:
|
|
|
|
return strlen(HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE);
|
|
|
|
case 400:
|
|
|
|
return strlen(HTTP_RESPONSE_400_BAD_REQUEST);
|
|
|
|
default:
|
|
|
|
panic("%d is not a valid status code\n", status_code);
|
|
|
|
}
|
|
|
|
}
|