Wprowadzenie


CGI (ang. Common Gateway Interface) to znormalizowany interfejs, umożliwiający komunikację pomiędzy oprogramowaniem serwera WWW a innymi programami znajdującymi się na serwerze. Zazwyczaj program serwera WWW wysyła do przeglądarki statyczne dokumenty HTML. Za pomocą programów CGI można dynamicznie (na żądanie klienta) generować dokumenty HTML uzupełniając je np. treścią pobieraną z bazy danych. / Wikipedia /

CGI ...
  • ... nie jest językiem programowania
  • ... jest protokołem, poprzez który komunikują się ze sobą przeglądarka, serwer WWW i zainstalowane na maszynie-serwerze oprogramowanie
  • ... nie pozwala zaimplementować żadnych nowych funkcji
  • ... jest niezależne od przeglądarki
  • ... jest wykonywany po stronie serwera
  • ... jest mało wydajnym mechanizmem, w porównaniu do innych technologii
  • ... wymaga znacznych zasobów systemowych ze strony serwera
  • ... nie jest zbyt bezpieczne
idź do góry

"Hello World" w Bash'u


 1#!/bin/bash

 2echo "Content-Type: text/html"
 3echo

 4echo "<h2>Hello World</h2> "
 5echo "Made by Bash"
 6echo "<br><br><hr>"
 7echo "<B> (c) SPSK2013 </B>"

[pokaż zawartość pliku] [pobierz plik] [uruchom (text/html)] [uruchom (text/plain)] idź do góry

"Hello World" w Perl'u


 1#!/usr/bin/perl

 2print "Content-type: text/html\n";
 3print "\n";

 4print "<h2>Hello world</h2>\n";
 5print "Made by PERL\n";
 6print "<br><br><hr>\n";
 7print "<b> (c) SPSK2013 </b>\n";
[pokaż zawartość pliku] [pobierz plik] [uruchom] idź do góry

"Hello World" w C


 1#include <stdio.h>

 2int main(int argc, char * argv[])
 3{
 4  printf("Content-type: text/html\n");
 5  printf("\n");

 6  printf("<h2>Hello world</h2>\n");
 7  printf("Made by C\n");
 8  printf("<br><br><hr>\n");
 9  printf("<b> (c) SPSK2013 </b>\n");

10  return 0;
11}
[pokaż zawartość pliku] [pobierz plik] [uruchom] idź do góry

"Hello World" w Ruby


 1#!/usr/bin/ruby1.9

 2puts "Content-Type: text/html"
 3puts

 4puts "<h2>Hello World</h2> "
 5puts "Made by Ruby"
 6puts "<br><br><hr>"
 7puts "<B> (c) SPSK2013 </B>"

[pokaż zawartość pliku] [pobierz plik] [uruchom] idź do góry

Nagłówek HTTP


 1#!/bin/bash

 2echo "Location: http://www.onet.pl"
 3echo


[pokaż zawartość pliku] [uruchom] idź do góry

Zmienne środowiskowe


 1#!/bin/bash

 2echo -e "Content-type: text/html\n\n";

 3 ciekawy sposób tworzenia dokumentu wynikowego za pomocą komendy CAT
 4/bin/cat << EOM
 5<HTML>
 6 <BODY>
 7  <H1>Lista zmiennych</H1>
 8  <P>
 9   <PRE>
10EOM

11env

12/bin/cat << EOM
13   </PRE>
14  <P>
15 </BODY>
16</HTML>
17EOM


[pokaż zawartość pliku] [uruchom] idź do góry

Wykonanie polecenia


 1#!/bin/bash

 2echo -e "Content-Type: text/plain\n"
 3#echo
 4echo "to jest testowy dokument"
 5echo
 6echo "------------------------------------------"
 7uname -a
 8echo "------------------------------------------"
 9ps -ef | grep -v root
10echo
11echo "------------------------------------------"
12who
[pokaż zawartość pliku] [uruchom] idź do góry

Licznik


 1#!/bin/bash

 2echo "Content-type: text/html"
 3echo
 4touch count.txt
 5VAL=cat count.txt
 6if [ -z $VAL ] 
 7 then
 8  VAL=1
 9fi
10echo "<html><body>Do tej pory jest to $VAL wizyta <br>"
11VAL=$((VAL+1))

12grep $REMOTE_ADDR adresy.txt > /dev/null

13if [ ! $? -eq 0 ]
14 then
15  echo $REMOTE_ADDR >> adresy.txt
16  echo $VAL > count.txt
17fi

18echo "<a href=adresy.txt>Plik z adresami osób odwiedzających</a><br><hr>"
19cat adresy.txt
20echo "</body></html>"
[pokaż zawartość pliku] [uruchom] idź do góry

Zegar


 1#!/bin/bash

 2echo "Content-Type: text/html"
 3echo "Refresh: 1"
 4echo
 5echo "<html><body>"
 6date
 7echo "</body></html>"
[pokaż zawartość pliku] [uruchom] idź do góry

Przekierowanie


 1#!/bin/bash

 2SEC=5
 3URL="http://www.onet.pl"

 4echo "Content-type: text/html"
 5echo "Refresh: $SEC; URL=$URL"
 6echo
 7echo "Za $SEC sekund nastąpi przeniesienie"
[pokaż zawartość pliku] [uruchom] idź do góry

metoda GET


 1#!/bin/bash

 2echo "Content-Type: text/html"
 3echo 

 4echo "QUERY_STRING = [$QUERY_STRING]"
 5echo

 6Zakończ jeśli nie podano żadnych parametrów
 7[ -z $QUERY_STRING ] && exit 

 8QUERY=$QUERY_STRING"&"
 9while true
10do
11Ze zmiennej QUERY usuwany jest z końca najdłuższy (%%)
12pasujący do wzorca "&*" ciąg znaków
13np. QUERY="A=1&B=2&C=3" -> ARG="A=1"
14  ARG=${QUERY%%&*}

15Zakończ pętlę jeśli nic nie zostało 
16  [ "$ARG" = "" ] && break;
17  
18Ze zmiennej ARG usuwany jest z początku najkrótszy (#)
19pasujący do wzorca "*=" ciąg znaków
20np. ARG="A=1" -> ARG_VALUE="1"
21  ARG_VALUE=${ARG#*=}

22Ze zmiennej ARG usuwany jest z końca najkrótszy (%)
23pasujący do wzorca "*=" ciąg znaków
24np. ARG="A=1" -> ARG_NAME="A"
25  ARG_NAME=${ARG%=*}
26  
27  echo -e " arg:$ARG_NAME \t value:$ARG_VALUE\n<br/>"
28  QUERY=${QUERY#*&}
29done
[pokaż zawartość pliku] [uruchom] idź do góry

metoda POST


 1#!/bin/bash

 2echo "Content-Type: text/html"
 3echo 

 4read QUERY_STRING
 5echo "QUERY_STRING = [$QUERY_STRING]"
 6echo

 7[ -z $QUERY_STRING ] && exit 

 8QUERY=$QUERY_STRING"&"
 9while true
10do
11  ARG=${QUERY%%&*}
12  [ "$ARG" = "" ] && break;
13    
14  ARG_VALUE=${ARG#*=}
15  ARG_NAME=${ARG%=*}
16  echo -e " arg:$ARG_NAME \t value:$ARG_VALUE\n <br/>"
17  
18  QUERY=${QUERY#*&}
19done

[pokaż zawartość pliku] [uruchom] idź do góry

Generowanie strony pomocy systemowej (POST)


 1#!/bin/bash

 2echo -e "Content-Type: text/html\n"
 3echo

 4Analiza parametrów wejściowych
 5QUERY=$QUERY_STRING"&"
 6while true
 7do
 8 ARG=${QUERY%%&*}
 9 case ${ARG%=*} in
10       cmd) CMD=${ARG#*=};;
11   bgcolor) BG_COLOR=${ARG#*=};;
12   fgcolor) FG_COLOR=${ARG#*=};;
13        "") break;;
14 esac
15 QUERY=${QUERY#*&}
16done

17Tworzy znacznik BODY z odpowiednimi parametrami
18echo "<body"
19echo " bgcolor=${BG_COLOR:-lightgrey} "
20echo " text=${FG_COLOR:-blue} "
21echo ">"

22Generuje zawartość strony pomocy 
23[ -n "$CMD" ] && man $CMD -Thtml

24echo "</body></html>"
[pokaż zawartość pliku] [uruchom] idź do góry

Sposób kompilacji


Żeby skompilować przykłady przedstawione poniżej należy pobrać bibliotekę cgi-util , która znacznie upraszcza sposób pisania programów, w których wykorzystywane są parametry wejściowe.
kompilacja: gcc source.c cgi-util.o -o output_name</!i>

Pliki do pobrania: idź do góry

Przekazywanie parametrów


 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <string.h>
 4#include "cgi-util.h"

 5int main(int argc, char * argv[])
 6{
 7  int res;
 8  int i;
 9  
10  Initialize the CGI and send out an HTTP header:
11  res = cgi_init();
12  printf("Content-type: text/html\n\n");

13  Was there an error initializing the CGI???
14  if (res != CGIERR_NONE) {
15      printf("Error # %d: %s<p>\n", res, cgi_strerror(res));
16      exit(0);
17  }

18  Grab some fields from an HTML form and display them:
19  if (cgi_getentrystr("name") != NULL)
20    printf("name  : %s<p>\n", cgi_getentrystr("name"));

21  if (cgi_getentrystr("sex") != NULL)
22    printf("sex   : %s<p>\n", cgi_getentrystr("sex"));

23  for(i=0;i<cgi_getnumentries("hobby");i++) 
24    if (cgi_getentrystr("hobby") != NULL)
25      printf("hobby : %s<p>\n", cgi_getnentrystr("hobby",i));

26  if (cgi_getentrystr("PIN") != NULL)
27    printf("PIN   : %s<p>\n", cgi_getentrystr("PIN"));

28  Close up the CGI:
29  cgi_quit();
30  return(0);
31}
[pokaż zawartość pliku] [uruchom] idź do góry

Upload pliku


 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <string.h>
 4#include "cgi-util.h"

 5int main(int argc, char * argv[])
 6{
 7  int res;
 8  char filename[255]="./download/";
 9  char tmp[255]="";

10  Initialize the CGI and send out an HTTP header:   
11  res = cgi_init();  
12  printf("Content-type: text/html\n\n");

13  Was there an error initializing the CGI???  
14  if (res != CGIERR_NONE)
15  {
16      printf("Error # %d: %s<p>\n", res, cgi_strerror(res));
17      exit(0);
18  }

19  Display some text:   
20  printf("Witam,<br>\n");

21  Grab some fields from an HTML form and display them:   
22  if (cgi_getentrystr("name") != NULL) {
23    strncpy(tmp,cgi_getentrystr("name"),strlen(cgi_getentrystr("name"))-2);
24    strcat(filename,tmp);
25  }

26  if (cgi_getentrystr("filename") != NULL)
27    {
28      FILE * fi;      
29      printf("Plik [%s] został przesłany. <br>\n"
30            , cgi_getentrystr("name"));
31      printf("Rozmiar   : %d<br>\n"
32            , strlen(cgi_getentrystr("filename")));
33      printf("Nowa nazwa: <a href=\"./download\">%s</a><br>\n"
34            , filename);      
35      fi = fopen(filename, "w");
36      if (fi != NULL)
37      {
38             fprintf(fi, "%s", cgi_getentrystr("filename"));
39        fclose(fi);
40           }
41    }

42  Close up the CGI:   
43  printf("Koniec<br>\n");  
44  cgi_quit();  
45  return(0);
46}
[pokaż zawartość pliku] [uruchom] idź do góry