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:
2016-11-26
Revision:
2:33714d7c0f45
Parent:
1:3a1fe94c6e42
Child:
3:59884bc0a238

File content as of revision 2:33714d7c0f45:

#include "HTTP_SERVER.h"
#include "string"
#define DEBUG

void DEBUG_PRINT_LINE(const char* arg_line)
{
#ifdef DEBUG
    printf("%s",arg_line);
#endif
}

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

HttpServer::~HttpServer()
{
}

bool HttpServer::init()
{

//  Ethernet Initialization
    if(eth.init()) {
        printf("(HTTP_SERVER) Error!@EthernetInterface::init()\r\n");
        return false;
    }
    //  Ethernet Connecting setup
    if(eth.connect()) {
        printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n");
        return false;
    } else {
        printf("(HTTP_SERVER) IP Address is %s\r\n", eth.getIPAddress());
    }
    //  TCP Socket setup
    //  To open Server-side PORT
    if(tcpsvr.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(tcpsvr.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(tcpsvr.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",tcpcon.get_address());
            led2 = true;
        }
        //  When conected
        while(tcpcon.is_connected()) {
            DEBUG_PRINT_LINE("(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("(HTTP_SERVER) DEBUG MODE\r\n");
            switch(tcpcon.receive(buffer, 1023)) {
                case 0:
                    printf("(HTTP_SERVER) recieved buffer is empty.\r\n");
                    msger.setStatusLine(400, "No Request");
                    httpmethod    = NULL;
                    filepath      = NULL;
                    http_ver      = NULL;
                    break;
                case -1:
                    printf("(HTTP_SERVER) failed to read data from client.\r\n");
                    msger.setStatusLine(500, "Internal Server Error");
                    httpmethod    = NULL;
                    filepath      = NULL;
                    http_ver      = NULL;
                    break;
                default:
                    printf("(HTTP_SERVER) Recieved Data: %d\r\n-->\r\n%.*s[End of Request]\r\n",strlen(buffer),strlen(buffer),buffer);
                    //  get HTTP method
                    httpmethod = strtok(buffer," ");
                    //  get File path
                    filepath = strtok(NULL, " ");
                    //  get HTTP version
                    http_ver = strtok(NULL, "\r\n");
#ifdef DEBUG
                    printf("(HTTP_SERVER) httpmethod: %s\r\n", httpmethod);
                    printf("(HTTP_SERVER) file path:  %s\r\n", filepath);
                    printf("(HTTP_SERVER) http ver :  %s\r\n", http_ver);
#endif
                    break;
            }
            DEBUG_PRINT_LINE("\r\n"
                             "(HTTP_SERVER) debug before response\r\n");

            //
            //  Response
            //
            if (strcmp(httpmethod,"GET") == 0 ) {
                printf("(HTTP_SERVER) GET request incomming.\r\n");

                //  file calibration
                DEBUG_PRINT_LINE("(HTTP_SERVER) file opening\r\n");
                fhandl.open(filepath,"rb");
                if(fhandl.arrival()) {
                    msger.setStatusLine(200, "OK");
                    if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))printf("buffer over flow");
                    if(msger.setHeaderField("Connection", "keep-alive"))printf("buffer over flow");
                } else {
                    if(msger.setStatusLine(404, "NOT FOUND"))printf("buffer over flow");
                    if(msger.setHeaderField("Connection", "close"))printf("buffer over flow");
                    DEBUG_PRINT_LINE("(HTTP_SERVER) NOT FOUND\r\n");
                }
                if(     strcmp(fhandl.getSuffix(), "htm" )  ||
                        strcmp(fhandl.getSuffix(), "HTM" )  ||
                        strcmp(fhandl.getSuffix(), "html")  ||
                        strcmp(fhandl.getSuffix(), "HTML")) {
                    if(msger.setHeaderField("Content-Type", "text/html"))printf("buffer over flow");
                } else if (strcmp(fhandl.getSuffix(), "ico" )  ) {
                    if(msger.setHeaderField("Content-Type", "image/png"))printf("buffer over flow");
                } else {
                    msger.setStatusLine(406, "not acceptable");
                }

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

                //  Define behaviour of server according to Request Header lines
                //  Apply request header field to response header field
                char* field_Connection = NULL,
                      field_Upgrade = NULL,
                      field_Sec_WebSocket_Key = NULL,
                      field_Sec-WebSocket_Version = NULL,
                                field_Origin = NULL;
                do {
                    //Analyze the header feilds
                    header_field_name = strtok(NULL, ":");
                    header_field_name++;
                    header_field_val  = strtok(NULL, "\r\n");
                    header_field_val++;

                    if(header_field_name != NULL) {
                        switch(header_field_name) {
                            case "Connection":
                                filed_Connection = header_field_val;
                                break;
                            case "Upgrade":
                                field_Upgrade = header_field_val;
                                break;
                            case "Sec-WebSocket-Key":
                                field_Sec_WebSocket_Key = header_field_val;
                                break;
                            case "Sec-WebSocket-Version":
                                field_Sec_WebSocket_Version = header_field_val;
                                break;
                            case "Origin":
                                field_Origin = header_field_val;
                                break;
                            default:
                                break;
                        }
                    } else {
                        break;
                    }
#ifdef DEBUG
                    printf("(HTTP_SERVER) *header_field_name adr: %d %s\r\n", header_field_name - 1, header_field_name);
                    printf("(HTTP_SERVER)  header_field_val  adr: %d %s\r\n", header_field_val  - 1, header_field_val);
#endif
                } while(1);

                //  if the request is to switching to the WebSocket Server
                if(     !strcmp(filed_Connection, "Upgrade")        &&
                        !strcmp(field_Upgrade, "websocket")         &&
                        field_Sec_WebSocket_Key != NULL             &&
                        !strcmp(field_Sec_WebSocket_Version, "13")  &&
                        field_Origin != NULL) {
                    DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol will be Upgraded to Websocket! \r\n");
                    /*
                    if(ws.isValid()){
                        msger.resetHeader();
                        msger.setStatusLine(101, "Switching Protocols");
                        if(msger.msger.setHeaderField("Connection", "Upgrade"))             printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
                        if(msger.msger.setHeaderField("Upgrade", "websocket"))              printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
                        if(msger.msger.setHeaderField("Sec-WebSocket-Accept", ...))         printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
                        if(msger.msger.setHeaderField("Access-Control-Allow-Origin", "*"))  printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
                        ...
                    }
                    */
                } else {
                    DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol won't be Upgraded.\r\n");
                    msger.setStatusLine(426, "Upgrade Required");
                    if(msger.setHeaderField("Connection", "Close"))printf("buffer over flow");
                }


#ifdef DEBUG
                //printf("status code :  %d\r\n", status_code);
                //printf("content type:  %s\r\n", content_type);
#endif

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

                //file close
#ifdef DEBUG
                if(
#endif
                    fhandl.close()
#ifndef DEBUG
                    ;
#endif
#ifdef DEBUG
                    == 0)
                    printf("(HTTP_SERVER) file has closed\r\n");
                else if(EOF)
                    printf("(HTTP_SERVER) failed to close the file\r\n");
#endif
                msger.resetHeader();
                printf("(HTTP_SERVER) echo back done.\r\n");
            }
            printf("(HTTP_SERVER) Response to Request has done\r\n");
        }
        printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n");
        tcpcon.close();
        //tcpsvr.close();
        led2 = false;
    }
    led1 = false;
    return 0;
}