Raised This Month: $32 Target: $400
 8% 

Working with Curl


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
ConorCC
Member
Join Date: Feb 2014
Old 05-31-2021 , 07:43   Working with Curl
Reply With Quote #1

Hy!

A few days ago I started to work with the following libraries: json and curl by Polarhigh

My target is to create an authentication system base on Laravel. For example you can login to your web account by entering email and password. This plugin supposed to send your data via http and waiting for the user id delivered by response. A bit tricky but not overcomplicated.

Lets discuss the results. Pros and cons. This is the first working version. What things would you change for optimalisation or cause my implementation is kinda stupid and why?

PHP Code:
#include <amxmisc>
#include <curl>
#include <json>

new Array: g_requests;

enum _REQUEST_DATA {

    
REQUEST_DATA_ID,
    
REQUEST_DATA_USERID,
    
REQUEST_DATA_BODY[512]
}

public 
plugin_init() {
    
    
register_plugin("HTTPS""1.0.0""JohanCorn");

    
g_requests ArrayCreate(REQUEST_DATA);

    
register_clcmd("login""cmd_login");
}

public 
cmd_login(id) {

    new 
args[64];
    
read_args(argscharsmax(args));
    
remove_quotes(args);

    new 
email[32], password[32];
    
argbreak(argsemailcharsmax(email), passwordcharsmax(password));

    
client_print(idprint_chat"Try to login with %s and %s"emailpassword);

    
// Init curl;
    
new CURLpCurl curl_easy_init();

    
// Create headers;
    
new curl_slistpHeaders;
    
pHeaders curl_slist_append(pHeaders"Content-Type: application/json");
    
pHeaders curl_slist_append(pHeaders"User-Agent: Curl");

    
// Create request data; (Player id, userid and empty body)
    
new request_data[REQUEST_DATA];
    
request_data[REQUEST_DATA_ID] = id;
    
request_data[REQUEST_DATA_USERID] = get_user_userid(id);
    
request_data[REQUEST_DATA_BODY][0] = EOS;

    
// Put it into the global array;
    
new request_id ArrayPushArray(g_requestsrequest_data);

    
// Log;
    
log_to_file("test.log""Start! Request ID: %i | %i %i"request_idrequest_data[REQUEST_DATA_ID], request_data[REQUEST_DATA_USERID]);

    
// Body text;
    
new body[256];
    
format(bodycharsmax(body), "{^"email^": ^"%s^", ^"password^": ^"%s^"}"emailpassword);

    
// Set curl things;
    
curl_easy_setopt(pCurlCURLOPT_URL"http://johancorn.sunwell.hu/api/login");
    
curl_easy_setopt(pCurlCURLOPT_COPYPOSTFIELDSbody);
    
curl_easy_setopt(pCurlCURLOPT_CUSTOMREQUEST"POST");
    
curl_easy_setopt(pCurlCURLOPT_HTTPHEADERpHeaders);
    
curl_easy_setopt(pCurlCURLOPT_WRITEFUNCTION"response_write");
    
curl_easy_setopt(pCurlCURLOPT_WRITEDATArequest_id);
    
curl_easy_setopt(pCurlCURLOPT_CAINFO"/server143/cstrike/cacert.pem");
    
    
// Tmp data;
    
new data[1];
    
data[0] = request_id;

    
// FIRE!
    
curl_easy_perform(pCurl"request_complete"datasizeof(data));
}

public 
response_write(const data[], const size, const nmemb, const request_id) {

    
// Somehow data size is more than the real size so create a new place and copy into it;
    // Thats how we remove garbage from the end of the string;
    
new data_fix[512];
    
add(data_fixcharsmax(data_fix), datanmemb);

    
// Get request data by request_id;
    
new request_data[REQUEST_DATA];
    
ArrayGetArray(g_requestsrequest_idrequest_data);

    
// Add body to stored body; (Empty by default); Required for chunks;
    
add(request_data[REQUEST_DATA_BODY], charsmax(request_data[REQUEST_DATA_BODY]), data_fix);

    
// Overwrite request data in array;
    
ArraySetArray(g_requestsrequest_idrequest_data);

    
// Return size (curl)
    
return size nmemb;
}

public 
request_complete(CURLcurlCURLcodecode, const data[1]) {

    
// Get stored request_id;
    
new request_id data[0];

    
// Get request data by request_id;
    
new request_data[REQUEST_DATA];
    
ArrayGetArray(g_requestsrequest_idrequest_data);

    
// Get player id by request data;
    
new id request_data[REQUEST_DATA_ID];

    
// Is stored player userid equals current player's userid;
    
if ( get_user_userid(id) == request_data[REQUEST_DATA_USERID] ) {

        
// Is Curl status OK;
        
if ( code == CURLE_OK ) {

            
// Get status code; (200, 401, etc.)
            
new status_codecurl_easy_getinfo(curlCURLINFO_RESPONSE_CODEstatus_code);

            
// Log;
            
log_to_file("test.log""Completed! Request ID: %i | %i %i | Body: %s | Status: %i"request_idrequest_data[REQUEST_DATA_ID], request_data[REQUEST_DATA_USERID], request_data[REQUEST_DATA_BODY], status_code);
        
            
// All good;
            
if ( status_code == 200 ) {

                
// Do login display;
                
login_authorized(idrequest_data[REQUEST_DATA_BODY]);
            }
            
// Something is wrong;
            
else {

                switch ( 
status_code ) {

                    case 
401login_failed(id"Invalid login details.");
                    case 
402..499: {

                        
// Error text;
                        
new error[64]; format(errorcharsmax(error), "Client Error: %i"code);

                        
login_failed(iderror);
                    }
                    case 
500..599: {

                        
// Error text;
                        
new error[64]; format(errorcharsmax(error), "Server Error: %i"code);

                        
login_failed(iderror);
                    }
                    default: {

                        
// Error text;
                        
new error[64]; format(errorcharsmax(error), "Other Error: %i"code);

                        
login_failed(iderror);
                    }
                }
            }
        }
        
// Some weird error;
        
else {

            
// Log;
            
log_to_file("test.log""Failed! Request ID: %i | %i %i"request_idrequest_data[REQUEST_DATA_ID], request_data[REQUEST_DATA_USERID]);

            
// Error text;
            
new error[64]; format(errorcharsmax(error), "Weird Code: %i"code);

            
// Do error display;
            
login_failed(iderror);
        }
    }
    else {

        
// Response received too late. (Player disconnected.)
        // Do nothing.
    
}

    
curl_easy_cleanup(curl);
}

public 
login_authorized(idbody[]) {

    new 
JSONjsonjson json_parse(body);

    
client_print(idprint_console"You are logged in as #%i!"json_object_get_number(json"id"));
}

public 
login_failed(iderror[]) {

    
client_print(idprint_console"Login failed! Error: %s"error);

If you want to check the code in runtime I can give you a test account and a game server installed with this plugin.

At least I already have a question about curl.

You can pass array of data to request_complete function by setting the 3-4th params. But you only can send an integer value to response_write function. It doesnt make sense to me. Since the source is expecting a pointer of data it should work with an array too. Isnt it?

Edit: I know the address is not secured. Cause its only for tests.

Last edited by ConorCC; 05-31-2021 at 07:46.
ConorCC is offline
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
Old 05-31-2021 , 11:10   Re: Working with Curl
Reply With Quote #2

Ideally, all callbacks should support passing an array of data, my guess is this was just missed by the creator of the module.
__________________
Bugsy is offline
ConorCC
Member
Join Date: Feb 2014
Old 05-31-2021 , 18:44   Re: Working with Curl
Reply With Quote #3

v1.0 is Available! Please take a look at this.

GitHub: https://github.com/JohanCorn/amxx_auth

Test or just view the source and tell me your experience.
ConorCC is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 23:38.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode