CGI هو معيار الواجهة المستخدم لتوصيل برنامج خارجي للتواصل مع الخادم. يُطلق على البرنامج الذي يعمل وفقًا لمثل هذه الواجهة مع خادم الويب عادةً بوابة ، على الرغم من أن العديد من الأسماء تفضل "برنامج البرنامج النصي" أو "برنامج CGI". في الواقع ، فإنه يسمح باستخدام وحدة التحكم في الإدخال والإخراج بالتفاعل مع العميل.
تم تصميم الواجهة نفسها بطريقة يمكن استخدام أي لغة برمجة يمكنها العمل مع أجهزة الإدخال والمخرجات القياسية. تتمتع البرامج النصية للمترجمين الفوريين في أنظمة التشغيل المدمجة في مثل هذه الفرص ، لذلك في الحالات البسيطة ، يمكن استخدام البرامج النصية الأوامر.
CGI هي واحدة من أكثر الوسائل شيوعًا لإنشاء مواقع ديناميكية. يتم استخدام هذا المعيار من قبل خوادم الويب الشهيرة مثل Nginx أو Apache.
يعرف الخادم كيفية إصلاحه على مضيف معين: المنفذ والاستماع إلى الاتصالات الواردة. في عنوان معين ، يتم إصدار صفحة HTML إذا كان الطلب صحيحًا ، أو صفحة بها خطأ قدره 404 ، إذا لم تكن الصفحة المطلوبة موجودة. يتم أيضًا تنفيذ برنامج نصي CGI الذي يوضح الوقت عند الضغط على الأزرار الموجودة على الصفحة الرئيسية.
#!
htdocs/
cgi-bin/
install.c
utility.c
utility.h
main.c
Makefile
نقوم بتثبيته باستخدام Make. سيتم تجميع البرنامج النصي للتثبيت ونقل الملف القابل للتنفيذ إلى مجلد/usr/local/bin ، ثم إنشاء ملف .service ووضعه في/etc/systemd/::
cd cgi/
make install
يمكن الآن إطلاق الخادم بنفس طريقة خدمات النظام (يعمل فقط على Ubuntu ، لأنه يضع ملف وحدة في/etc/systemd/system/folder ، والذي لم يتم تثبيته على أنظمة أخرى). وفقًا للافتراضي ، سيبدأ الخادم في 127.0.0.1:1235. لتعيين الإعدادات الخاصة بك ، تحتاج إلى تغيير ملف التكوين:
service cgi start
service cgi stop
عند البدء ، يقوم البرنامج بإنشاء ملف PID يسجل فيه معرف العملية الحالية بحيث يمكنك إرسال إشارة إليه في المستقبل لإكمال العمل. إذا حدث خطأ أثناء بداية الخادم ، فلا يتم إنشاء الملف.
#!c
//creating PID file
FILE * file = fopen(path_to_pidfile, "a+");
fprintf(file, "%d", getpid());
fclose(file);
//killing running server
FILE * file = fopen(path_to_pidfile, "r+");
fscanf(file, "%d", &pid);
kill(pid, SIGTERM);
fclose(file);
remove(path_to_pidfile);
بعد ذلك ، باستخدام مجموعة من الوظائف للعمل مع Sockets ، قمنا بإعداد الخادم الخاص بنا. إذا كان كل شيء قد مرت بدون أخطاء ، فإننا نبدأ في قبول الاتصالات الواردة. لكل اتصال تم تبنيه ، نقوم بإنشاء عملية منفصلة ، تستمر عملية الوالدين في الاستماع.
#!c
pid_t pid = fork();
if (0 == pid) { //if it is child process - interact connection
handle_request(client_socket, &client_address, htdocs);
exit(0);
} else { //otherwise close socket and continue listening
close(client_socket);
}
تقرأ الشركة الفرعية الطلب ، وتعالجه ويعطي الجواب: إذا تم العثور على الملف ، فسيتم إصدار الصفحة المقابلة ، وإلا فإن المستخدم سيتلقى صفحة مع 404. يتم تخزين جميع الإحصائيات في مجلد خادم HTDOCS.
#!c
read(client_socket, recv_buffer, sizeof(recv_buffer));
char *query_str = parse_request(recv_buffer);
...
GET(client_socket, query_str, maindir);
عند النقر على الصفحة الرئيسية على زر "Get Current Time" ، يتم تنفيذ البرنامج النصي الذي يقوم بإرجاع التاريخ/الوقت الحالي:
#!c
if (strcmp(query_str + strlen(query_str) - 4, "cgi?") == 0) {
...
execve(main_dir, arg, empty2); //execute cgi-script
close(client_socket);
}
في الوقت الحالي ، يتم تنفيذها:
قريباً: