Прервать ловушку: 6 - Libwebsocket Mac - PullRequest
0 голосов
/ 06 февраля 2020

Добрый день, я пытаюсь скомпилировать и выполнить этот код. Оказывается, что он компилируется и выполняется идеально, но когда дело доходит до удара с FRONT (я использую Angular), он ломает меня, когда я ввожу псевдоним, то есть соединение с сервером прерывается, но в любом случае в база данных, он хранит меня с ошибками, например, если в псевдониме я поставил "Juan", он сохраняется в базе данных как "Juantofks =", и я получаю ошибку ABORT.

Кто-нибудь знает, почему это происходит ?

Я использую библиотеку libwebsocket для сервера

#include <stdio.h>
#include <stdlib.h>
#include <libwebsockets.h>
#include <mysql.h>
#define SIZE 100 // Create a stack with capacity of 100 elements long stack[SIZE];

// Initially stack is empty int top = -1;

MYSQL *conn; MYSQL_RES *res; //    MYSQL_RES *res2; MYSQL_ROW row; //  MYSQL_ROW row2;

char *server = "localhost"; char *userdb = "root"; char *password = "111222"; /* set me first */ char *database = "chat";
#define MAX_STRING 128 char query[MAX_STRING] = {0}; char messagefull[MAX_STRING] = {0}; char query2[MAX_STRING] = {0}; char username[MAX_STRING] = {0}; char iscontact[MAX_STRING] = {0}; char message[MAX_STRING] = {0}; char contact[MAX_STRING] = {0};

/* Function declaration to perform push and pop on stack */ void push(long element); int  pop();

int explode(char ***arr_ptr, char *str, char delimiter) {   char *src
= str, *end, *dst;   char **arr;   int size = 1, i;

  // Find number of strings   while ((end = strchr(src, delimiter)) != NULL)
    {
      ++size;
      src = end + 1;
    }

  arr = malloc(size * sizeof(char *) + (strlen(str) + 1) * sizeof(char));

  src = str;   dst = (char *) arr + size * sizeof(char *);   for (i = 0; i < size; ++i)
    {
      if ((end = strchr(src, delimiter)) == NULL)
        end = src + strlen(src);
      arr[i] = dst;
      strncpy(dst, src, end - src);
      dst[end - src] = '\0';
      dst += end - src + 1;
      src = end + 1;
    }   *arr_ptr = arr;

  return size; }

static int callback_http(struct lws *wsi,
                         enum lws_callback_reasons reason, void *user,
                         void *in, size_t len) {    return 0; }

static int callback_dumb_increment(struct lws *wsi,
                                   enum lws_callback_reasons reason,
                                   void *user, void *in, size_t len) {

    long wsi_adress = wsi;
    conn = mysql_init(NULL);

    /* Connect to database */
    if (!mysql_real_connect(conn, server, userdb, password,
                                      database, 8889, NULL, 0)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
    switch (reason) {
        case LWS_CALLBACK_ESTABLISHED: // just log message that someone is connecting
            printf("connection established\n");

            break;
        case LWS_CALLBACK_CLOSED: {
            snprintf(query, MAX_STRING, "DELETE FROM users WHERE token=%lu", wsi_adress);
            if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
            }



                //RESET CONTACT
                char contact[MAX_STRING] = {0};
                char reset[MAX_STRING] = {0};
                char *out = NULL;
                snprintf(query, MAX_STRING, "SELECT * FROM users");

                if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    exit(1);
                }
                res = mysql_store_result(conn); //                res = res2;
                char value[10];
                char *eptr;
                long long wsi_long;
                while ((row = mysql_fetch_row(res)) != NULL) {
                    strcpy(value, row[1]);
                    /* Convert the provided value to a decimal long long */
                    wsi_long = strtoll(value, &eptr, 10);
                    free(out);
                    push(wsi_long);
                }
                mysql_free_result(res);

                snprintf(query, MAX_STRING, "SELECT * FROM users");

                if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    exit(1);
                }
                int i = 0;
                for(i = 0; i < top + 1;i++){
                    snprintf(reset, MAX_STRING, "reset");
                    len = strlen(reset);
                    out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
                        //* setup the buffer*/
                    memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, reset, len );
                        //* write out*/
                    lws_write(stack[i],  out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
                    free(out);
                }
                res = mysql_store_result(conn);
                int j = 0;
                while ((row = mysql_fetch_row(res)) != NULL) {
                    for(j = 0; j < top + 1;j++){
                        snprintf(contact, MAX_STRING, "contact:%s", row[2]);
                        len = strlen(contact);

                        out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
                        //* setup the buffer*/
                        memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, contact, len );
                        //* write out*/
                        lws_write(stack[j],  out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
                        free(out);
                    }
                }
                pop();

                mysql_free_result(res);
            break;
        }

        case LWS_CALLBACK_RECEIVE: { // the funny part
            // create a buffer to hold our response
            // it has to have some pre and post padding. You don't need to care
            // what comes there, lwss will do everything for you. For more info see
            // http://git.warmcat.com/cgi-bin/cgit/lwss/tree/lib/lwss.h#n597   


            unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
                                                         LWS_SEND_BUFFER_POST_PADDING);
            //memset(&buf,'\0', sizeof(buf));
            int i;

            // pointer to `void *in` holds the incoming request
            // we're just going to put it in reverse order and put it in `buf` with
            // correct offset. `len` holds length of the request.
            for (i=0; i < len; i++) {
                buf[LWS_SEND_BUFFER_PRE_PADDING + (len - 1) - i ] = ((char *) in)[i];
            }
             //GUARDAR USUARIO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            int n;
            int len;
            char *out = NULL;
            char listContact[MAX_STRING] = {0};
            /* send SQL query */
            char **arr;
            char **arr2;
            char isUserNameString[MAX_STRING] = {0};
            char contact[MAX_STRING] = {0};
            strncpy(isUserNameString, (char *) in, 11);
            isUserNameString[11] = '\0'; //
            if(strcmp("firstnamews", isUserNameString) == 0) {
                explode(&arr, (char *) in, ':');
                snprintf(username, MAX_STRING, "%s",  arr[1]);
                free(arr);
                snprintf(query, MAX_STRING, "INSERT INTO users (name, token) VALUES ('%s', '%lu')",  username, wsi_adress);

                if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    len = strlen(mysql_error(conn));
                    out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
                    //* setup the buffer*/
                    memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, mysql_error(conn), len );
                    //* write out*/
                    lws_write(wsi,  out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
                    free(out);
                    break;
                }


                //RESET CONTACT
                char contact[MAX_STRING] = {0};
                char reset[MAX_STRING] = {0};
                char *out = NULL;
                snprintf(query, MAX_STRING, "SELECT * FROM users");

                if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    exit(1);
                }
                res = mysql_store_result(conn); //                res = res2;
                char value[10];
                char *eptr;
                long long wsi_long;
                while ((row = mysql_fetch_row(res)) != NULL) {
                    strcpy(value, row[1]);
                    /* Convert the provided value to a decimal long long */
                    wsi_long = strtoll(value, &eptr, 10);
                    free(out);
                    push(wsi_long);
                }
                mysql_free_result(res);

                snprintf(query, MAX_STRING, "SELECT * FROM users");

                if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
                    exit(1);
                }

                res = mysql_store_result(conn);
                int i = 0;
                for(i = 0; i < top + 1;i++){
                    snprintf(reset, MAX_STRING, "reset");
                    len = strlen(reset);
                    out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
                        //* setup the buffer*/
                    memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, reset, len );
                        //* write out*/
                    lws_write(stack[i],  out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
                    free(out);
                }
                int j = 0;
                while ((row = mysql_fetch_row(res)) != NULL) {
                    for(j = 0; j < top + 1;j++){
                        snprintf(contact, MAX_STRING, "contact:%s", row[2]);
                        len = strlen(contact);

                        out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
                        //* setup the buffer*/
                        memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, contact, len );
                        //* write out*/
                        lws_write(stack[j],  out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
                        free(out);
                    }
                }
                pop();

                mysql_free_result(res);
                break;
            }

            //ENVIAR MENSAJE !!!!!!!!!!!!!!!!!!!!!!!!!!
            explode(&arr2, (char *) in, ':');
            snprintf(iscontact, MAX_STRING, "%s",  arr2[0]);
            snprintf(message, MAX_STRING, "%s",  arr2[2]);
            snprintf(contact, MAX_STRING, "%s",  arr2[1]);
            free(arr2);
            snprintf(query, MAX_STRING, "SELECT * FROM users WHERE name='%s'",  contact);
            if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
            }
            res = mysql_store_result(conn);
            char value[10];
            char *eptr;
            long long wsi_long;
            while ((row = mysql_fetch_row(res)) != NULL) {
                strcpy(value, row[1]);
                /* Convert the provided value to a decimal long long */
                wsi_long = strtoll(value, &eptr, 10);
            }
            mysql_free_result(res);
            snprintf(query, MAX_STRING, "SELECT * FROM users WHERE token='%lu'",  wsi);
            if (mysql_query(conn, query)) {
                    fprintf(stderr, "%s\n", mysql_error(conn));
            }
            res = mysql_store_result(conn);
            while ((row = mysql_fetch_row(res)) != NULL) {
                snprintf(messagefull, MAX_STRING, "from:%s:%s", row[2],message);
                len = strlen(messagefull);
                out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
                //* setup the buffer*/
                memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, messagefull, len );
                //* write out*/
                lws_write(wsi_long,  out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
                free(out);
            }
            free(buf);
            break;
        }
        default:
        break;
    }
    mysql_close(conn);
    return 0; }

static struct lws_protocols protocols[] = {
    /* first protocol must always be HTTP handler */
    {
        "http-only",   // name
        callback_http, // callback
        0              // per_session_data_size
    },
    {
        "dumb-increment-protocol", // protocol name - very important!
        callback_dumb_increment,   // callback
        0                          // we don't use any per session data
    },
    {
        NULL, NULL, 0   /* End of list */
    } };

int main(void) {
    // server url will be http://localhost:9000

    conn = mysql_init(NULL);

    /* Connect to database */
    if (!mysql_real_connect(conn, server, userdb, password,
                                      database, 8889, NULL, 0)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
    snprintf(query, MAX_STRING, "TRUNCATE TABLE users");

    if (mysql_query(conn, query)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
    mysql_close(conn);
    int port = 9000;
    struct lws_context *context;
    struct lws_context_creation_info context_info =
    {
        .port = port, .iface = NULL, .protocols = protocols, .extensions = NULL,
        .ssl_cert_filepath = NULL, .ssl_private_key_filepath = NULL, .ssl_ca_filepath = NULL,
        .gid = -1, .uid = -1, .options = 0, NULL, .ka_time = 0, .ka_probes = 0, .ka_interval = 0
    };
    // create lws context representing this server
    context = lws_create_context(&context_info);

    if (context == NULL) {
        fprintf(stderr, "lws init failed\n");
        return -1;
    }

    printf("starting server...\n");

    // infinite loop, to end this server send SIGTERM. (CTRL+C)
    while (1) {
        lws_service(context, 50);
        // lws_service will process all waiting events with their
        // callback functions and then wait 50 ms.
        // (this is a single threaded webserver and this will keep our server
        // from generating load while there are not requests to process)
    }

    lws_context_destroy(context);

    return 0; }

/**  * Functiont to push a new element in stack.  */ void push(long element) {
    // Check stack overflow
    if (top >= SIZE)
    {
        printf("Stack Overflow, can't add more element element to stack.\n");
        return;
    }

    // Increase element count in stack
    top++;

    // Push element in stack
    stack[top] = element;

    printf("Data pushed to stack.\n"); }


/**  * Function to pop element from top of stack.  */ int pop() {
    // Check stack underflow
    if (top < 0)
    {
        printf("Stack is empty.\n");

        // Throw empty stack error/exception
        // Since C does not have concept of exception
        // Hence return minimum integer value as error value
        // Later in code check if return value is INT_MIN, then
        // stack is empty
        return INT_MIN;
    }
    return stack[top--]; }
...