The lib with which to make LPC1768 a simple HTTP server. This have not yet implemented. fopen() DOESN'T WORK after EthernetInterface::connect() is called as using mbed-os 5.4~. See also https://os.mbed.com/questions/80658/HardFault-occurs-when-fopen-is-called-af/ or https://github.com/ARMmbed/mbed-os/issues/6578 and https://github.com/ARMmbed/mbed-os/issues/6624

Fork of HTTP_SERVER by Akifumi Takahashi

handlers/ResponseMessenger.cpp

Committer:
aktk
Date:
2018-03-23
Revision:
18:ad5c461905bd
Parent:
16:c3920b5b8572

File content as of revision 18:ad5c461905bd:

#include "ResponseMessenger.h"

const char ResponseMessenger::http_ver[9] = "HTTP/1.1";
ResponseMessenger::ResponseMessenger()
{
    //  Status-Line
    status_code         = 0;
    reason_phrase[0]    = '\0';
    header_field_buffer[0]='\0';
    //  Response Header
}
ResponseMessenger::~ResponseMessenger()
{
}
int ResponseMessenger::resetHeader()
{
    //  Status-Line
    status_code         = 0;
    reason_phrase[0]    = '\0';
    //  Response Header
    header_field_buffer[0]='\0';
    return 0;
}
int ResponseMessenger::setStatusLine(
    int arg_status_code,
    const char* arg_reason_phrase
)
{
    status_code = arg_status_code;
    strcpy(reason_phrase, arg_reason_phrase);

    //  To be safe on the sage side
    reason_phrase[REASON_PHRASE_SIZE - 1] = '\0';
    //  Send 0 if arg str size is too big, else -1.
    if (strlen(arg_reason_phrase) < REASON_PHRASE_SIZE)
        return 0;
    else
        return -1;
}

int ResponseMessenger::setHeaderField(
    const char* arg_field_name, const char* arg_field_val)
{
    const int nField = 7;
    char registered_field_name[nField][32]= {
        "Connection",
        "Location",
        "Keep-Alive",
        "Content-Type",
        "Upgrade",
        "Sec-WebSocket-Accept",
        "Access-Control-Allow-Origin"
    };
    bool flag = false;
    char header_field_line_buffer[128];
    int  buffer_size = strlen(header_field_buffer);

    for (int i = 0; i < nField; i++) {
        if(strcmp(arg_field_name, registered_field_name[i]) == 0)
            flag = true;
    }
    if(flag) {
        sprintf(header_field_line_buffer, "%s: %s\r\n", arg_field_name, arg_field_val);
        strcat(header_field_buffer, header_field_line_buffer);
        //printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
    }
    //  To be safe on the sage side
    header_field_buffer[HEADER_FIELDS_SIZE - 1] = '\0';
    //  Send 0 if arg str size is too big, else -1.
    if (buffer_size + strlen(arg_field_name) + strlen(arg_field_val) < HEADER_FIELDS_SIZE + 1)
        return 0;
    else
        return -1;
}

int ResponseMessenger::setHeaderField(
    const char* arg_field_name, int arg_field_val)
{
    const int nField = 1;
    char registered_field_name[nField][32]= {
        "Content-Length"
    };
    bool flag = false;
    char header_field_line_buffer[128];
    int  buffer_size = strlen(header_field_buffer);

    for (int i = 0; i < nField; i++) {
        if(strcmp(arg_field_name, registered_field_name[i]) == 0)
            flag = true;
    }
    if(flag) {
        sprintf(header_field_line_buffer, "%s: %d\r\n", arg_field_name, arg_field_val);
        strcat(header_field_buffer, header_field_line_buffer);
        //printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
    }
    //  To be safe on the sage side
    header_field_buffer[HEADER_FIELDS_SIZE - 1] = '\0';
    //  Send 0 if arg str size is too big, else -1.
    if (buffer_size + strlen(arg_field_name) + 10 < HEADER_FIELDS_SIZE + 1)
        return 0;
    else
        return -1;
}

int ResponseMessenger::rmHeaderField(
    const char* arg_field_name)
{
    char* removedLineHead;
    char* removedLineEnd;
    int  buffer_size;

    //  Look for the head of the line to want to remove
    removedLineHead = strstr(header_field_buffer, arg_field_name);
    if(removedLineHead == NULL) return -1;
    //  Look for the first "\r\n" which is the end of the line
    removedLineEnd = strstr(removedLineHead, "\r\n");
    removedLineEnd += 3; //pointing next line head or '\0' if the line of the last one.
    buffer_size = strlen(removedLineEnd);

    for(int i = 0; i < buffer_size + 1; i++)
        removedLineHead[i] = removedLineEnd[i];

    return 0;
}

int  ResponseMessenger::getStatusCode()
{
    return status_code;
}

char ResponseMessenger::sendHTTPResponse(
    TCPSocket &arg_socket)
{
    int err_log  = 0;
    int err_code = 0;
    enum {
        MAX_BUFFER_SIZE = 1024
    };
    char buffer[MAX_BUFFER_SIZE] = "\0";

    //
    //  Header
    //
    printf("(RM) [send]Header\r\n");
    //  Status Line
    sprintf(buffer, "%s %d %s\r\n", http_ver, status_code, reason_phrase);
    buffer[MAX_BUFFER_SIZE - 1] = '\0';
    err_log = arg_socket.send(buffer, strlen(buffer));
    if(err_log < 0) err_code = ((err_code << 1) | 1);
    //  Response Header
    err_log = arg_socket.send(header_field_buffer, strlen(header_field_buffer));
    if(err_log < 0) err_code = ((err_code << 1) | 1);
    //  Blank line
    err_log = arg_socket.send("\r\n", strlen("\r\n"));
    if(err_log < 0) err_code = ((err_code << 1) | 1);
    printf("(RM) [Header has sent]\r\n");
    //return error code
    return err_code << 2;

}

char ResponseMessenger::sendHTTPResponse(
    TCPSocket &arg_socket,
    FileHandler &arg_file)
{
    int err_log  = 0;
    int err_code = 0;
    enum {
        MAX_BUFFER_SIZE = 1024
    };
    signed char buffer[MAX_BUFFER_SIZE];

    //
    //  Header
    //
    err_code = sendHTTPResponse(arg_socket);
    //
    //  Body
    //
    printf("(RM) file: %d\r\n"
    "(RM) status code: %d\r\n", arg_file.arrival(), status_code);
    if (arg_file.arrival() && status_code == 200) {
        printf("(RM) [send]Body\r\n");
        do {
            int i = 0;
            do {
                buffer[i++] = arg_file.getc();//return a byte from file ponter, or -1 if EOF or ERROR
            } while ((i < MAX_BUFFER_SIZE - 1) && (buffer[i - 1] != EOF));
            if(buffer[i - 1] == EOF)buffer[i - 1] = '\0';
            buffer[i] = '\0';
            if (!arg_file.hasError()) {
                err_log = arg_socket.send((char*)buffer, i);
                //printf("(RM) buffer log: %s",  buffer);
            }
            if (arg_file.hasError()) printf("(RM)---[ERR]---\r\n");
            if (arg_file.atEOF())    printf("(RM)---[EOF]---\r\n");
        } while (!arg_file.atEOF() && !arg_file.hasError());
        printf("(RM) [Body has sent]\r\n");

        if (err_log < 0) err_code = ((err_code) | 2);
        if (!arg_file.hasError())err_code = ((err_code) | 1);
    } else {
        printf("(RM) [No Body]\r\n");
    }
    return (char)err_code;
}