Perl ile CGI Programlama

 

 

BÖLÜM 3: CGI ORTAM DEĞİŞKENLERİ


Ortam değişkenleri, çalıştırdığımız her CGI programına web tarayıcı (ve web sunucusu) tarafından gönderilen bir takım gizli bilgilerdir. CGI bunları ayrıştırır, yorumlar ve kendisine bu şekilde gönderilen verileri kullanır. Perl’de ortam değişkenleri ve değerleri %ENV adlı bir özel tabloda tutulurlar. Bazı ortam değişkenleri aşağıda verilmiştir.

 

Değişken 

Değeri

DOCUMENT_ROOT

Web sunucusunun (göreceli) kök dizini

HTTP_COOKIE

Ziyaretiye ait çerez, eğer varsa.

HTTP_HOST

Sunucunun adı

HTTP_REFERER 

Betiğinizin çağrıldığı sayfanın URL adresi

HTTP_USER_AGENT 

Ziyaretçinin tarayıcısının türü

PATH 

Sunucuya ait sistem yolu (genellikle /bin, /usr/bin, vb..)

QUERY_STRİNG 

Sorgulama stringi (GET ile) ***

REMOTE_ADDR 

Ziyaretçinin IP adresi

REMOTE_HOST 

Ziyaretçinin makina adı (eğer ters-DNS yoksa yine IP adresi)

REMOTE_PORT 

Ziyaretçinin web sunucuya bağlandığı port numarası

REMOTE_USER 

Ziyaretçinin kullanıcı adı (.htacces’te belirtilen izne göre)

REQUEST_METHOD 

GET veya POST

SCRIPT_FILENAME 

Şuanki (çalışan) betiğin tam yolu (fiziksel)

SERVER_ADMIN 

Webmaster’ın e-mail adresi

SERVER_NAME 

Sunucunun kayıtlı domain adı

SERVER_PORT 

Sunucunun dinlediği (takip ettiği) port numarası

SERVER_SOFTWARE 

Kullandığınız HTTPd sunucu yazılımın adı (örn, Apache/1.3)

Bazı sunucular daha farklı ortam değişkenleri de sunabilirler. Bunun için sunucunun dökümanlarına bakmak gerekir. Dikkat etmek gerekir ki, bazı ortam değişkenleri bize sunucu hakkında bilgi verirler ve bunlar değişmezler (örn, SERVER_NAME ve SERVER_ADMIN); bazıları ise kullanıcılar hakkında ve istekler hakkında bilgiler verirler ve değişiklikler gösterirler.

Her CGI programı için tüm ortam değişkenlerinin kullanılması gerektiği gibi bir durum söz konusu değildir; gerekenler kullanılır, gerekmeyenler kullanılmazlar. Örneğin, REMOTE_USER değişkeni, .htaccess dosyası ile şifrelenerek korumaya alınmış dizin ve altdizinlerde yer alan sayfalara erişim için kullanılır. Bir kişinin e-mail adresini öğrenmek için güvenilir bir yol bulunmamaktadır; en kestirme olanı bir form kullanarak kullanıcıdan bizzat sormaktır.

Her CGI programı için %ENV tablosu otomatik olarak baştan yeniden oluşturulur, bunlardan bize gerekenlerini yada tamamını kullanmak mümkündür. Örneğin, sizin CGI programınızın çağrıldığı sayfanın URL adresini ekrana yazdırmak istersek,

print "Şuanki sayfanızın adresi = $ENV{'HTTP_REFERER'}\n\n";

deyimini kullanırız. Perl’de tüm ortam değişkenlerini elde etmek, sonradan kullanmak üzere bir diziye aktarmak yada ekrana yazdırmak oldukça kolay bir iştir. Şimdi env.cgi adında bir dosya oluşturalım ve aşağıdaki kodları girelim.

#!/usr/bin/perl
 
print "Content-type:text/html\n\n";
print <<EndOfHTML;
<html><head><title>Ortam Değişkenleri</title></head>
<body>
EndOfHTML;
foreach $key (sort(keys %ENV)) {
   print "$key = $ENV{$key}<br>\n";
}
print "</body></html>";

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-kitap/cgi-bin/env.cgi

Yukarıdaki CGI programını web tarayıcınızden çağırınız. Ne gördünüz?

Bu örnekte, sort fonksiyonu kullanılarak %ENV tablosundaki anahtarlar alfabetik olarak sıralanmıştır. 

Unutmadan söylemek gerekirse Perl’deki sort fonksiyonu sıralama işlemini string değerler üzerinde gerçekleştirir. Bu demektir ki sort fonksiyonu sayılar üzerinde istenildiği gibi doğru çalışmayacaktır. Allahtan ki Perl’de kendimize özel yeni sıralama rutinleri oluşturabiliriz. Sayısal ve özel kriterlere göre sıralama işlemini ileride ele alacağız.

Etkileşimli Formlar Oluşturmak

Web sayfalarının en güzel imkanlarından biri, kullanıcıların sayfa üzerinde çeşitli bilgiler girerek bunları web sunuculara gönderebilmesidir. Örneğin, ticari amaçlı bir sayfa tasarlıyorsak, bu sayfa üzerine bir sipariş formu yerleştirebilir ve siparişlerin bu form aracılığıyla bize ulaşmasını sağlayabiliriz.

Yada bir veritabanımız varsa ve bunu bir web sayfası aracılığıyla hizmete sunuyorsak, oluşturacağımız bir arama formu ile kullanıcıların bu veritabanı üzerinde etkin sorgulamalar yapmasını sağlayabiliriz.

Form üzerinde çeşitli seçenekler yerleştirerek kullanıcıların radyo butonları veya işaretleme kutucukları aracılığıyla bu seçeneklerden birini seçmelerini sağlatabiliriz. Hatta oyun oynama mekanizmaları bile oluşturabiliriz.

Formlar üzerinde aşağıdaki nesne tiplerini kullanabiliriz:

1.      Seçenek butonları (radio button)

2.      İşaretleme kutucukları (check box)

3.      Listeler (list)

4.      Bilgi giriş alanları (text box)

5.      Çok satırlı bilgi giriş alanları (memo)

6.      Tekli yada çoklu seçim yapılabilen menüler (combo box)

7.      Dosya arama pencereleri

8.      Sıfırlama (reset) ve gönderme (submit) butonları

9.      Gizli alanlar (hidden fields)

Web sayfaları üzerinde formlar oluşturmak için FORM tag’ı kullanılır. İç içe formlar oluşturulamaz. Bir döküman içinde birden fazla form kullanılabilir. FORM tag’nın sentaksı şöyledir:

<FORM ACTION="URL/script.cgi" METHOD="POST|GET" ENCTYPE="encryp-type">
   ...
</FORM>

Eğer METHOD belirtilmezse varsayılan metod GET’dir, ancak POST metodu da tercih edilebilir. Bu iki metod arasındaki fark nedir, diye sorarsak; GET ile bazı kısıtlamalar söz konudur. POST daha güçlüdür ve veri güvenliği için kullanılması şarttır. POST metodu ile gönderilen veriler, application/x-www-form-urlencoded olarak tanımlanan MIME formatında gönderilirler.

Basit Bir Sorgulama Formu

Yukarıda da belirtildiği gibi, verilerin bir HTML formundan CGI’ya gönderilmesi için iki metod kullanılmaktadır: GET ve POST metodları (aslında üç metod vardır: HEAD). Bu metodlar, formdaki verilerin sunucuya ne şekilde gönderileceklerini belirtirler. GET metodunda, formdan girilen veriler URL’nin bir uzantısı olarak CGI’ya gönderilirler ve QUERY_STRING adlı ortam değişkeninde tutulurlar. POST metodunda ise veriler CGI programa veri blokları (stream) olarak gönderilir. Farklılıklar, ileride yeri geldikçe tekrar tekrar ele alınacaktır. Bu bölümde GET metodunu incelemeye çalışacağız.

QUERY_STRING ortam değişkenine değer atamak için farklı bir takım yollar vardır. İlk akla geleni, bir CGI programını çağırırken URL adresinin sonuna ?-soru işareti ile başlayan eklemeler yapmaktır. Örneğin, env.cgi programını şu şekillerde çağıralım:

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-kitap/cgi-bin/env.cgi?deneme1

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-bin/cgi-kitap/env.cgi?deneme12

Göreceğiz ki URL’de ?-soru işaretinden sonra yer alan kısım QUERY_STRING ortam değişkenine aktarılacaktır. Aynı şey, GET metodunu kullanan bir formdan bir CGI’ya veri postalandığında da söz konusudur.
Şimdi GET metodunu kullanan basit bir form oluşturalım (form.html) ve deneyelim.

<form action="env.cgi" method="GET">
      Çalıştığınız Bölümünüzü giriniz:
      <input type="text" name="bolumu" size="20"><p>
</form>

NOT: Bu örnekte “submit-gönder” butonu kullanılmamıştır. GET metodunu kullanan ve tek bir girdi alanı içeren formlarda ENTER’a basmakla girilen veri hemen CGI’ya gönderilir. Birden çok girdi alanı içeren formlarda “submit-gönder” butonu kullanmak zorunludur.

Şimdi, QUERY_STRING ortam değişkeninin iki kısımdan oluştuğunu görmekteyiz:

bolumu=Bilgisayar+Prg

Sol taraftaki değer, formumuzdaki alanın adıdır. Sağ taraftaki değer ise bizim metin kutusuna yazdığımız bilgidir. Buradan da görülmektedir ki girilen boşluk karakterleri +-artı ile; noktalama işaretleri ve diğer extra karakterler ise %HH şeklinde gösterilmektedirler. Burada HH, ilgili karakterin hexadesimal ASCII kodudur. Eğer form üzerinde birden çok alan kullanmışsak her alan-değer çifti birbirlerinden &-ampersan işareti ile ayrılırlar. Bu kodlama biçimine URL-kodlama (URL encoding) denilir ve hem GET, hem de POST metodları ile gönderilen veriler için uygulanır. GET metodu kullanılan formlarda bu kodlama işlemini web tarayıcımız bizim adımıza gerçekleştirir... (Yaşasın! Ne güzel! )

Uzun ve karmaşık veriler göndermek için POST metodu daha uygundur. GET metodu esas itibarıyla kısa, tek alanlı sorgulamalar için, özellikle de veritabanı sorgulamaları için elverişlidir. Dahası QUERY_STRING değişkeninin uzunluğu bazı web tarayıcılarda (ve web sunucularda) 255 karakter ile sınırlandırılmıştır.

Birden çok alan kullanımına da bir örnek verelim (env.html dosyası olarak kaydedin):

<form action="env.cgi" method="GET">
  Adınızı giriniz....:
  <input type="text" name="ad" value="Emre Tunahan" size="20"> <br>
  Soyadınızı giriniz.:
  <input type="text" name="soyad" value="GÜNEŞ" size="20"> <p>
  <input type="submit" value="Gönder">
  <input type="reset" value="Sil">
</form>

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-kitap/cgi-bin/env.html

Bu form, girilen verileri env.cgi betiğine şu şekilde gönderecektir:

$ENV{'QUERY_STRING'}= ad=Emre+Tunahan&soyad=G%DCNE%DE

Alanlar (ve değerler) birbirlerinden &-işareti ile ayrılmışlardır. Alan-değer çiftlerini elde etmek için Perl’de split adlı fonksiyon kullanılır:

Aşağıdaki kodları env2.cgi dosyasına kaydedelim, yukarıdaki formun action kısmını action=”env2.cgi” olarak değiştirelim (env2.html) ve deneyelim.

#!/usr/bin/perl
 
print "Content-type:text/html\n\n";
print <<EndOfHTML;
<html><head><title>Ortam Degişkenleri</title></head>
<body>
EndOfHTML
;
@values = split(/\&/, $ENV{'QUERY_STRING'});
foreach $i (@values) {
    ($varname, $mydata) = split(/=/, $i);
    print "$varname = $mydata <br>";
}
print "</body></html>";

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-kitap/cgi-bin/env2.html

GET Metoduna İlişkin Önemli Uyarılar

GET metodu ile verileri göndermek, güvenlik açısından oldukça tehlikelidir; bu nedenle şifre, kredi kartı bilgileri ve diğer önemli bilgileri göndermek için kesinlikle kullanılmamalıdır. GET metodunda veriler gönderilirken URL’nin bir uzantısı olarak gönderildiğinden, web sunucunun log dosyalarına bakılarak bu tür bilgilerin tamamının herhangi bir kullanıcı tarafından öğrenilmesi mümkündür. Gizli ve özel bilgiler gönderilirken POST metodu kullanılmalıdır. POST metodu ayrıca verileri kriptolama özelliğine de sahiptir ve bir sonraki bölümde incelenecektir.

GET metodunun en çok kullanıldığı durumlar, bir veritabanından basit sorgulamalar yapmak suretiyle çeşitli bilgilerin listelenmesi gibi kullanımlardır. Örneğin, yazdığınız makalelerden oluşan bir veritabanını, verdiğiniz numaraları kullanarak sorgulamak için makale.cgi adında bir CGI betiği yazabilirsiniz ve örn., 23 no’lu makaleyi görmek için “ .../makale.cgi?23” gibi bir URL kullanabilirsiniz.