Direct connect to php fpm. Linux C

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ckpunmkug, 23 Dec 2024.

  1. ckpunmkug

    ckpunmkug Member

    Joined:
    20 Mar 2017
    Messages:
    73
    Likes Received:
    72
    Reputations:
    10
    годная дока
    specification
    template

    Code:
    #include <error.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <fastcgi.h>
    
    int fpm_client(char *fpm_socket_file_path, char *result)
    {
            int ret, len;
    
            int unix_stream_socket;
            unix_stream_socket = socket(AF_UNIX, SOCK_STREAM, 0);
            if(unix_stream_socket < 0) {
                    error(0, errno, "Can't create unix socket stream");
                    return(-1);
            }
            
            struct sockaddr_un addr;
            memset(&addr, 0, sizeof(addr));
            addr.sun_family = AF_UNIX;
            len = strlen(fpm_socket_file_path);
            strncpy(addr.sun_path, fpm_socket_file_path, len);
    
            ret = connect(unix_stream_socket, (const struct sockaddr *) &addr, sizeof(addr));
            if(ret < 0){
                    error(0, errno, "Can't connect to unix socket stream");
                    return(-1);
            }
            
            
            FCGI_Header header;
            header.version = FCGI_VERSION_1;
            header.requestIdB1 = 0;
            header.requestIdB0 = 1;
            header.paddingLength = 0;
            
            // FCGI_BEGIN_REQUEST
            
            header.type = FCGI_BEGIN_REQUEST;
            
            FCGI_BeginRequestBody begin_request_body;
            begin_request_body.roleB1 = 0;
            begin_request_body.roleB0 = FCGI_RESPONDER;
            begin_request_body.flags = 0;
            
            len = sizeof(begin_request_body);
            header.contentLengthB1 = 0;
            header.contentLengthB0 = len;
            
            ret = write(unix_stream_socket, &header, sizeof(header));
            if(ret < 0) {
                    error(0, errno, "Can't write `begin request header`");
                    return(-1);
            }
            
            ret = write(unix_stream_socket, &begin_request_body, len);
            if(ret < 0) {
                    error(0, errno, "Can't write `begin request body`");
                    return(-1);
            }
            
            // FCGI_PARAMS
            
            header.type = FCGI_PARAMS;
            
            len = 0;
            char *params[] = {
                    "SCRIPT_FILENAME", "/var/www/index.php",
                    "REQUEST_METHOD", "GET",
                    "VAR", "value"
            };
            
            int i, c, nl, vl;
            char buffer[65536];
            c = sizeof(params)/sizeof(params[0]);
            for(i = 0; i < c; i += 2) {
                    nl = strlen(params[i]);
                    vl = strlen(params[i+1]);
                    
                    memcpy(buffer+len, &nl, 1);
                    len += 1;
                    
                    memcpy(buffer+len, &vl, 1);
                    len += 1;
                    
                    memcpy(buffer+len, params[i], nl);
                    len += nl;
                    
                    memcpy(buffer+len, params[i+1], vl);
                    len += vl;
            }
            
            header.contentLengthB1 = (len >>8) & 0xff;
            header.contentLengthB0 = len & 0xff;
            
            ret = write(unix_stream_socket, &header, sizeof(header));
            if(ret < 0) {
                    error(0, errno, "Can't write `params request header`");
                    return(-1);
            }
            
            ret = write(unix_stream_socket, buffer, len);
            if(ret < 0) {
                    error(0, errno, "Can't write `params request body`");
                    return(-1);
            }
            
            header.contentLengthB1 = 0;
            header.contentLengthB0 = 0;
            
            ret = write(unix_stream_socket, &header, sizeof(header));
            if(ret < 0) {
                    error(0, errno, "Can't write `empty params request header`");
                    return(-1);
            }
            
            // FCGI_STDOUT
            
            ret = read(unix_stream_socket, &header, 8);
            if(ret < 0) {
                    error(0, errno, "Can't read stdout response header");
                    return(-1);
            }
            
            len = 0;
            len = header.contentLengthB1 << 8;
            len = len | header.contentLengthB0;
            
            memset(buffer, 0, 65536);
            
            ret = read(unix_stream_socket, buffer, len);
            if(ret < 0) {
                    error(0, errno, "Can't read stdout response body");
                    return(-1);
            }
            
            //write(1, buffer, len);
            
            char *offset;
            offset = strstr(buffer, "\r\n\r\n");
            offset += 4;
            
            //printf("\n%s\n", offset);
            
            len = len-(offset-buffer);
            strncpy(result, offset, len);
            
            ret = close(unix_stream_socket);
            if(ret < 0) {
                    error(0, errno, "Can't close unix socket stream");
                    return(-1);
            }
            
            return(0);
    }