Bu yazıda, C dilini kullanarak basit bir FastCGI web uygulaması yapacağız. Uygulamamız FastCGI kütüphanesini kullanarak, açtığımız socket üzerinden nginx web sunucusu ile haberleşerek çalışacak.

FastCGI, CGI protokolündeki bazı eksikliklerden yola çıkılarak geliştirilmiş, açık standartlı bir CGI alternatifidir. Bu protokol, web sunucuları ile bilgisayar programları arasında bağlantı kurulabilmesi için tasarlanmıştır. Web sunucuları, bu protokol üzerinden programlara; istek methodu, istek adresi, sorgu parametreleri ve kullanıcı IP’si başta olmak üzere pek çok veriyi aktarabilirken, programlar da web sunucularına dönülecek yanıtları aktarmaktadır. Böylece, bu protokolün implement edildiği bütün programlama dilleriyle web uygulamaları geliştirmek mümkün hale gelir.

İşe önce FastCGI’nin Github’daki kütüphanesini kendimize klonlayarak başlayalım.

git clone git@github.com:FastCGI-Archives/fcgi2.git

make komutunu kullanarak kütüphaneyi, işletim sistemimizin varsayılan olarak kullandığı “shared libraries” yoluna kuralım.

Not: Kurulumdan önce gcc, gnu make, m4, aclocal, autoconf, automake ve libtool paketlerinin sistemde yüklü olduğundan emin olunuz.

cd fcgi2/
./autogen.sh
./configure
sudo make
sudo make install

Kütüphane kurulumunun kontrolünü buradan kontrol edebiliriz:

ls /usr/local/lib

Şimdi, bir text editörü açalım ve dosya adı “hello.c” olan şu dosyayı oluşturalım:

#include "fcgi_stdio.h"
#include <stdlib.h>

int main()
{
    // FastCGI'nin başlatılabilmesi için mutlaka belirtmemiz gerekli.
    FCGX_Init();

    // ":9000" değeri vererek istediğimiz port numarası ile socket oluşturuyoruz.
    // fakat bir dosya ismi belirterek, yerine UNIX socket de oluşturabiliriz.
    int fcgi_sock = FCGX_OpenSocket(":9000", 10);

    FCGX_Request req;
    FCGX_InitRequest(&req, fcgi_sock, 0);

    char *request_method;
    char *request_path;
    char *query_string;

    while (FCGX_Accept_r(&req) == 0) {

        request_method = FCGX_GetParam("REQUEST_METHOD", req.envp);
        request_path   = FCGX_GetParam("REQUEST_URI", req.envp);
        query_string   = FCGX_GetParam("QUERY_STRING", req.envp);
        
        FCGX_FPrintF(req.out, 
            "Content-Type: text/html\r\n"
            "Server: EkinServer 1.0\r\n"
            "\r\n");

        FCGX_FPrintF(req.out, "<html><head><meta charset='utf-8'></head><body>");
        FCGX_FPrintF(req.out, "<h1>Örnek FastCGI uygulamasına hoşgeldiniz!</h1>");
        FCGX_FPrintF(req.out, "İstek methodu: %s <br>", request_method);
        FCGX_FPrintF(req.out, "İstek adresi: %s <br>", request_path);
        FCGX_FPrintF(req.out, "İstek sorgusu: %s <br>", query_string);
        FCGX_FPrintF(req.out, "</body></html>");

        FCGX_Finish_r(&req);
    }

    return 0;
}

Daha sonra programı derletelim ve çalıştıralım:

gcc hello.c -Wl,-rpath /usr/local/lib -lfcgi -o hello-fastcgi
./hello-fastcgi

Çalıştığı sırada programın exit olmaması gerekir. Programı çalıştırdığımızda terminalde bloklanıyorsa programda tanımladığımız socket üzerinden dinleme yapılıyor anlamına gelir. Şimdi nginx web sunucusunu ayarlayalım. nginx’i kurduğumuzu farzediyorum ve bir config dosyası oluşturuyoruz.

/etc/nginx/conf.d/hello-fastcgi.conf

server {
    listen 8080;
    server_name localhost;

    location / {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;

        # UNIX socket oluşturduysak ayar aşağıdaki gibi olmalıdır:
        # fastcgi_pass unix:/var/run/hello-fastcgi.sock;
    }
}

nginx config dosyasını kaydettikten ve sonra nginx’i yeniden başlattıktan sonra bir web tarayısından http://localhost:8080/deneme?foo=bar adresine girdiğimizde aşağıdaki çıktıyı elde edebilmemiz gerekir:

hello-fastcgi