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

HTTP_SERVER.cpp

Committer:
aktk
Date:
2018-03-04
Revision:
12:c926d680f339
Parent:
10:4a48594c2f44
Child:
13:483b2b1a6471

File content as of revision 12:c926d680f339:

#include "HTTP_SERVER.h"
#include "string"
#ifndef HTTP_SERVER_DEBUG
//#define DEBUG
#endif

namespace HTTP_SERVER
{
void DEBUG_PRINT_LINE(const char* arg_line)
{
#ifdef HTTP_SERVER_DEBUG
    printf("(HTTP_SERVER) ")
    printf(arg_line);
    printf("\r\n");
#endif
}
template<typename T>
void DEBUG_PRINT_LINE(const char* arg_line, T arg_t)
{
#ifdef HTTP_SERVER_DEBUG
    printf("(HTTP_SERVER) ");
    printf(arg_line, arg_t);
    printf("\r\n");
#endif
}
template<typename T1, typename T2>
void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2)
{
#ifdef HTTP_SERVER_DEBUG
    printf("(HTTP_SERVER) ");
    printf(arg_line, arg_t1, arg_t2);
    printf("\r\n");
#endif
}
}
using namespace HTTP_SERVER;

HttpServer::HttpServer()
{
    keep_alive = (false);
    listening_flag = (false);
    req_buf[0] = '\0';
}

HttpServer::~HttpServer()
{
}

bool HttpServer::init()
{

//  Ethernet Initialization
    if(net.init()) {
        printf("(HTTP_SERVER) Error!@EthernetInterface::init()\r\n");
        return false;
    }
    //  Ethernet Connecting setup
    if(net.connect()) {
        printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n");
        return false;
    } else {
        printf("(HTTP_SERVER) IP Address is %s\r\n", net.getIPAddress());
    }
    //  TCP Socket setup
    //  To open Server-side PORT
    if(server.bind(TCP_PORT)< 0) {
        printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n");
        return false;
    } else {
        printf("(HTTP_SERVER) TCP Server has bounden!\r\n");
    }
    //  Server start listening Request from a web browser.
    if(server.listen(1) < 0) {
        printf("(HTTP_SERVER) tcp server listen failed.\r\n");
        return false;
    } else {
        listening_flag = true;
        printf("(HTTP_SERVER) tcp server is listening...\r\n");
    }

    return true;
}

bool HttpServer::run()
{
    DigitalOut led1(LED1);
    DigitalOut led2(LED1);

    while (listening_flag) {
        led1 = true;
        //  blocking mode (never timeout)
        //  waiting client connection
        printf("(HTTP_SERVER) waiting connection\r\n");
        if(server.accept(tcpcon) < 0) {
            printf("(HTTP_SERVER) failed to accept connection.\r\n");
            return -1;
        } else {
            printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",client.get_address());
            led2 = true;
        }
        //  When conected
        while(client.is_connected()) {
            printf("(HTTP_SERVER) connected\r\n");

            char buffer[1024]   = {0};
            char* httpmethod    = NULL;
            char* filepath      = NULL;
            char* http_ver      = NULL;
            char* header_field_name = NULL;
            char* header_field_val  = NULL;

            //
            //  Request Analysis
            //
            DEBUG_PRINT_LINE("DEBUG MODE");
            switch(client.receive(buffer, 1023)) {
                case 0:
                    DEBUG_PRINT_LINE("recieved buffer is empty.");
                    msger.setStatusLine(400, "No Request");
                    if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                    httpmethod    = NULL;
                    filepath      = NULL;
                    http_ver      = NULL;
                    break;
                case -1:
                    DEBUG_PRINT_LINE("failed to read data from client.");
                    msger.setStatusLine(500, "Internal Server Error");
                    if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                    httpmethod    = NULL;
                    filepath      = NULL;
                    http_ver      = NULL;
                    break;
                default:
                    DEBUG_PRINT_LINE("Recieved Data: %d",strlen(buffer));
                    DEBUG_PRINT_LINE("-->\r\n");
                    DEBUG_PRINT_LINE("%.*s[End of Request]",strlen(buffer),buffer);
                    //  get HTTP method, File path, HTTP version
                    httpmethod = strtok(buffer," ");
                    filepath = strtok(NULL, " ");
                    http_ver = strtok(NULL, "\r\n");
                    DEBUG_PRINT_LINE("httpmethod: %s", httpmethod);
                    DEBUG_PRINT_LINE("file path:  %s", filepath);
                    DEBUG_PRINT_LINE("http ver :  %s", http_ver);
                    break;
            }

            //
            //  Response
            //
            if (strcmp(httpmethod,"GET") == 0 ) {
                DEBUG_PRINT_LINE("GET request incomming.");

                //  file calibration
                DEBUG_PRINT_LINE("file opening");
                fhandl.open(filepath,"rb");
                if(fhandl.arrival()) {
                    msger.setStatusLine(200, "OK");
                    if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))    DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                    if(msger.setHeaderField("Connection", "keep-alive"))                DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                } else {
                    if(msger.setStatusLine(404, "NOT FOUND"))                           DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                    if(msger.setHeaderField("Connection", "Close"))                     DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                    DEBUG_PRINT_LINE("NOT FOUND");
                }
                if(         !strcmp(fhandl.getSuffix(), "htm" ) ||
                            !strcmp(fhandl.getSuffix(), "HTM" ) ||
                            !strcmp(fhandl.getSuffix(), "html") ||
                            !strcmp(fhandl.getSuffix(), "HTML")){
                    if(msger.setHeaderField("Content-Type", "text/html"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                } else if(  !strcmp(fhandl.getSuffix(), "js"  )){
                    if(msger.setHeaderField("Content-Type", "text/javascript"))         DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                } else if ( !strcmp(fhandl.getSuffix(), "ico" )){
                    if(msger.setHeaderField("Content-Type", "image/png"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                } else if ( !strcmp(fhandl.getSuffix(), "png" ) ||
                            !strcmp(fhandl.getSuffix(), "PNG" )){
                    if(msger.setHeaderField("Content-Type", "image/png"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                } else if ( !strcmp(fhandl.getSuffix(), "jpg" ) ||
                            !strcmp(fhandl.getSuffix(), "JPG" )){
                    if(msger.setHeaderField("Content-Type", "image/jpg"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                } else {
                    msger.setStatusLine(406, "not acceptable");
                }

                //  Connection timeout field
                if(msger.setHeaderField("Keep-Alive", "timeouit=15"))                   DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");

                //  send response
                msger.sendHTTPResponse(tcpcon, fhandl);

                //file close
                if( fhandl.close()== 0)
                    DEBUG_PRINT_LINE("file has closed");
                else if(EOF)
                    DEBUG_PRINT_LINE("failed to close the file");
                    
                msger.resetHeader();
                DEBUG_PRINT_LINE("echo back done.");
            }
            if (httpmethod == NULL) {
                msger.sendHTTPResponse(tcpcon);
                msger.resetHeader();
                DEBUG_PRINT_LINE("echo back done.");
            }
            printf("(HTTP_SERVER) Response to Request has done\r\n");
            //
            //
            //
        }
        printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n");
        client.close();
        led2 = false;
    }
    server.close();
    listening_flag = false;
    led1 = false;
    return 0;
}