Cgi сценарий что это

This article is about the software interface between a Web server and programs. For other uses, see CGI (disambiguation).

This article is about the software interface between a Web server and programs. For other uses, see CGI (disambiguation).

In computing, Common Gateway Interface (CGI) is an interface specification that enables web servers to execute an external program, typically to process user requests.[1]

Such programs are often written in a scripting language and are commonly referred to as CGI scripts, but they may include compiled programs.[2]

A typical use case occurs when a web user submits a web form on a web page that uses CGI. The form’s data is sent to the web server within an HTTP request with a URL denoting a CGI script. The web server then launches the CGI script in a new computer process, passing the form data to it. The output of the CGI script, usually in the form of HTML, is returned by the script to the Web server, and the server relays it back to the browser as its response to the browser’s request.[3]

Developed in the early 1990s, CGI was the earliest common method available that allowed a web page to be interactive.

History[edit]

The official CGI logo from the spec announcement

In 1993, the National Center for Supercomputing Applications (NCSA) team wrote the specification for calling command line executables on the www-talk mailing list.[4][5][6] The other Web server developers adopted it, and it has been a standard for Web servers ever since. A work group chaired by Ken Coar started in November 1997 to get the NCSA definition of CGI more formally defined.[7] This work resulted in RFC 3875, which specified CGI Version 1.1. Specifically mentioned in the RFC are the following contributors:[3]

  • Rob McCool (author of the NCSA HTTPd Web server)
  • John Franks (author of the GN Web server)
  • Ari Luotonen (the developer of the CERN httpd Web server)
  • Tony Sanders (author of the Plexus Web server)
  • George Phillips (Web server maintainer at the University of British Columbia)

Historically CGI programs were often written using the C programming language. RFC 3875 «The Common Gateway Interface (CGI)» partially defines CGI using C,[3] in saying that environment variables «are accessed by the C library routine getenv() or variable environ».

The name CGI comes from the early days of the Web, where webmasters wanted to connect legacy information systems such as databases to their Web servers. The CGI program was executed by the server that provided a common «gateway» between the Web server and the legacy information system.

Purpose of the CGI specification[edit]

Each Web server runs HTTP server software, which responds to requests from web browsers. Generally, the HTTP server has a directory (folder), which is designated as a document collection – files that can be sent to Web browsers connected to this server.[8] For example, if the Web server has the domain name example.com, and its document collection is stored at /usr/local/apache/htdocs/ in the local file system, then the Web server will respond to a request for http://example.com/index.html by sending to the browser the (pre-written) file /usr/local/apache/htdocs/index.html.

For pages constructed on the fly, the server software may defer requests to separate programs and relay the results to the requesting client (usually, a Web browser that displays the page to the end user). In the early days of the Web, such programs were usually small and written in a scripting language; hence, they were known as scripts.

Such programs usually require some additional information to be specified with the request. For instance, if Wikipedia were implemented as a script, one thing the script would need to know is whether the user is logged in and, if logged in, under which name. The content at the top of a Wikipedia page depends on this information.

HTTP provides ways for browsers to pass such information to the Web server, e.g. as part of the URL. The server software must then pass this information through to the script somehow.

Conversely, upon returning, the script must provide all the information required by HTTP for a response to the request: the HTTP status of the request, the document content (if available), the document type (e.g. HTML, PDF, or plain text), et cetera.

Initially, different server software would use different ways to exchange this information with scripts. As a result, it wasn’t possible to write scripts that would work unmodified for different server software, even though the information being exchanged was the same. Therefore, it was decided to specify a way for exchanging this information: CGI (the Common Gateway Interface, as it defines a common way for server software to interface with scripts).
Webpage generating programs invoked by server software that operate according to the CGI specification are known as CGI scripts.

This specification was quickly adopted and is still supported by all well-known server software, such as Apache, IIS, and (with an extension) node.js-based servers.

An early use of CGI scripts was to process forms. In the beginning of HTML, HTML forms typically had an «action» attribute and a button designated as the «submit» button. When the submit button is pushed the URI specified in the «action» attribute would be sent to the server with the data from the form sent as a query string. If the «action» specifies a CGI script then the CGI script would be executed and it then produces an HTML page.

Using CGI scripts[edit]

A Web server allows its owner to configure which URLs shall be handled by which CGI scripts.

This is usually done by marking a new directory within the document collection as containing CGI scripts – its name is often cgi-bin. For example, /usr/local/apache/htdocs/cgi-bin could be designated as a CGI directory on the Web server. When a Web browser requests a URL that points to a file within the CGI directory (e.g., http://example.com/cgi-bin/printenv.pl/with/additional/path?and=a&query=string), then, instead of simply sending that file (/usr/local/apache/htdocs/cgi-bin/printenv.pl) to the Web browser, the HTTP server runs the specified script and passes the output of the script to the Web browser. That is, anything that the script sends to standard output is passed to the Web client instead of being shown on-screen in a terminal window.

As remarked above, the CGI specification defines how additional information passed with the request is passed to the script.
For instance, if a slash and additional directory name(s) are appended to the URL immediately after the name of the script (in this example, /with/additional/path), then that path is stored in the PATH_INFO environment variable before the script is called. If parameters are sent to the script via an HTTP GET request (a question mark appended to the URL, followed by param=value pairs; in the example, ?and=a&query=string), then those parameters are stored in the QUERY_STRING environment variable before the script is called. If parameters are sent to the script via an HTTP POST request, they are passed to the script’s standard input. The script can then read these environment variables or data from standard input and adapt to the Web browser’s request.[9]

Example[edit]

The following Perl program shows all the environment variables passed by the Web server:

#!/usr/bin/env perl

=head1 DESCRIPTION

printenv — a CGI program that just prints its environment

=cut
print "Content-Type: text/plainnn";

foreach ( sort keys %ENV ) {
    print "$_="$ENV{$_}"n";
}

If a Web browser issues a request for the environment variables at http://example.com/cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with%20percent%20encoding, a 64-bit Windows 7 Web server running cygwin returns the following information:

COMSPEC="C:Windowssystem32cmd.exe"
DOCUMENT_ROOT="C:/Program Files (x86)/Apache Software Foundation/Apache2.4/htdocs"
GATEWAY_INTERFACE="CGI/1.1"
HOME="/home/SYSTEM"
HTTP_ACCEPT="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q=0.7,*;q=0.7"
HTTP_ACCEPT_ENCODING="gzip, deflate, br"
HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5"
HTTP_CONNECTION="keep-alive"
HTTP_HOST="example.com"
HTTP_USER_AGENT="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:67.0) Gecko/20100101 Firefox/67.0"
PATH="/home/SYSTEM/bin:/bin:/cygdrive/c/progra~2/php:/cygdrive/c/windows/system32:..."
PATHEXT=".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC"
PATH_INFO="/foo/bar"
PATH_TRANSLATED="C:Program Files (x86)Apache Software FoundationApache2.4htdocsfoobar"
QUERY_STRING="var1=value1&var2=with%20percent%20encoding"
REMOTE_ADDR="127.0.0.1"
REMOTE_PORT="63555"
REQUEST_METHOD="GET"
REQUEST_URI="/cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with%20percent%20encoding"
SCRIPT_FILENAME="C:/Program Files (x86)/Apache Software Foundation/Apache2.4/cgi-bin/printenv.pl"
SCRIPT_NAME="/cgi-bin/printenv.pl"
SERVER_ADDR="127.0.0.1"
SERVER_ADMIN="(server admin's email address)"
SERVER_NAME="127.0.0.1"
SERVER_PORT="80"
SERVER_PROTOCOL="HTTP/1.1"
SERVER_SIGNATURE=""
SERVER_SOFTWARE="Apache/2.4.39 (Win32) PHP/7.3.7"
SYSTEMROOT="C:Windows"
TERM="cygwin"
WINDIR="C:Windows"

Some, but not all, of these variables are defined by the CGI standard.
Some, such as PATH_INFO, QUERY_STRING, and the ones starting with HTTP_, pass information along from the HTTP request.

From the environment, it can be seen that the Web browser is Firefox running on a Windows 7 PC, the Web server is Apache running on a system that emulates Unix, and the CGI script is named cgi-bin/printenv.pl.

The program could then generate any content, write that to standard output, and the Web server will transmit it to the browser.

The following are environment variables passed to CGI programs:

  • Server specific variables:
    • SERVER_SOFTWARE: name/version of HTTP server.
    • SERVER_NAME: host name of the server, may be dot-decimal IP address.
    • GATEWAY_INTERFACE: CGI/version.
  • Request specific variables:
    • SERVER_PROTOCOL: HTTP/version.
    • SERVER_PORT: TCP port (decimal).
    • REQUEST_METHOD: name of HTTP method (see above).
    • PATH_INFO: path suffix, if appended to URL after program name and a slash.
    • PATH_TRANSLATED: corresponding full path as supposed by server, if PATH_INFO is present.
    • SCRIPT_NAME: relative path to the program, like /cgi-bin/script.cgi.
    • QUERY_STRING: the part of URL after ? character. The query string may be composed of *name=value pairs separated with ampersands (such as var1=val1&var2=val2…) when used to submit form data transferred via GET method as defined by HTML application/x-www-form-urlencoded.
    • REMOTE_HOST: host name of the client, unset if server did not perform such lookup.
    • REMOTE_ADDR: IP address of the client (dot-decimal).
    • AUTH_TYPE: identification type, if applicable.
    • REMOTE_USER used for certain AUTH_TYPEs.
    • REMOTE_IDENT: see ident, only if server performed such lookup.
    • CONTENT_TYPE: Internet media type of input data if PUT or POST method are used, as provided via HTTP header.
    • CONTENT_LENGTH: similarly, size of input data (decimal, in octets) if provided via HTTP header.
    • Variables passed by user agent (HTTP_ACCEPT, HTTP_ACCEPT_LANGUAGE, HTTP_USER_AGENT, HTTP_COOKIE and possibly others) contain values of corresponding HTTP headers and therefore have the same sense.

The program returns the result to the Web server in the form of standard output, beginning with a header and a blank line.

The header is encoded in the same way as an HTTP header and must include the MIME type of the document returned.[10] The headers, supplemented by the Web server, are generally forwarded with the response back to the user.

Here is a simple CGI program written in Python 3 along with the HTML that handles a simple addition problem.[11]

add.html:

<!DOCTYPE html>
<html>
 <body>
  <form action="add.cgi" method="POST">
   <fieldset>
     <legend>Enter two numbers to add</legend>
     <label>First Number: <input type="number" name="num1"></label><br/>
     <label>Second Number: <input type="number" name="num2"></label><br/>
   </fieldset>
   <button>Add</button>
  </form>
 </body>
</html>

add.cgi:

#!/usr/bin/env python3

import cgi, cgitb
cgitb.enable()

input_data = cgi.FieldStorage()

print("Content-Type: text/html") # HTML is following
print("")                        # Leave a blank line
print("<h1>Addition Results</h1>")
try:
    num1 = int(input_data["num1"].value)
    num2 = int(input_data["num2"].value)
except:
    print("<output>Sorry, the script cannot turn your inputs into numbers (integers).</output>")
    raise SystemExit(1)
print("<output>{0} + {1} = {2}</output>".format(num1, num2, num1 + num2))

This Python 3 CGI program gets the inputs from the HTML and adds the two numbers together.

Deployment[edit]

A Web server that supports CGI can be configured to interpret a URL that it serves as a reference to a CGI script. A common convention is to have a cgi-bin/ directory at the base of the directory tree and treat all executable files within this directory (and no other, for security) as CGI scripts. Another popular convention is to use filename extensions; for instance, if CGI scripts are consistently given the extension .cgi, the Web server can be configured to interpret all such files as CGI scripts. While convenient, and required by many prepackaged scripts, it opens the server to attack if a remote user can upload executable code with the proper extension.

In the case of HTTP PUT or POSTs, the user-submitted data are provided to the program via the standard input. The Web server creates a subset of the environment variables passed to it and adds details pertinent to the HTTP environment.

Uses[edit]

CGI is often used to process input information from the user and produce the appropriate output. An example of a CGI program is one implementing a wiki. If the user agent requests the name of an entry, the Web server executes the CGI program. The CGI program retrieves the source of that entry’s page (if one exists), transforms it into HTML, and prints the result. The Web server receives the output from the CGI program and transmits it to the user agent. Then if the user agent clicks the «Edit page» button, the CGI program populates an HTML textarea or other editing control with the page’s contents. Finally if the user agent clicks the «Publish page» button, the CGI program transforms the updated HTML into the source of that entry’s page and saves it.

Security[edit]

CGI programs run, by default, in the security context of the Web server. When first introduced a number of example scripts were provided with the reference distributions of the NCSA, Apache and CERN Web servers to show how shell scripts or C programs could be coded to make use of the new CGI. One such example script was a CGI program called PHF that implemented a simple phone book.

In common with a number of other scripts at the time, this script made use of a function: escape_shell_cmd(). The function was supposed to sanitize its argument, which came from user input and then pass the input to the Unix shell, to be run in the security context of the Web server. The script did not correctly sanitize all input and allowed new lines to be passed to the shell, which effectively allowed multiple commands to be run. The results of these commands were then displayed on the Web server. If the security context of the Web server allowed it, malicious commands could be executed by attackers.

This was the first widespread example of a new type of Web based attack, where unsanitized data from Web users could lead to execution of code on a Web server. Because the example code was installed by default, attacks were widespread and led to a number of security advisories in early 1996.[12]

Alternatives[edit]

For each incoming HTTP request, a Web server creates a new CGI process for handling it and destroys the CGI process after the HTTP request has been handled. Creating and destroying a process can consume much more CPU and memory than the actual work of generating the output of the process, especially when the CGI program still needs to be interpreted by a virtual machine. For a high number of HTTP requests, the resulting workload can quickly overwhelm the Web server.

The overhead involved in CGI process creation and destruction can be reduced by the following techniques:

  • CGI programs precompiled to machine code, e.g. precompiled from C or C++ programs, rather than CGI programs interpreted by a virtual machine, e.g. Perl, PHP or Python programs.
  • Web server extensions such as Apache modules (e.g. mod_perl, mod_php, mod_python), NSAPI plugins, and ISAPI plugins which allow long-running application processes handling more than one request and hosted within the Web server. Web 2.0 allows to transfer data from the client to the server without using HTML forms and without the user noticing.[13]
  • FastCGI, SCGI, and AJP which allow long-running application processes handling more than one request to be hosted externally; i.e., separately from the Web server. Each application process listens on a socket; the Web server handles an HTTP request and sends it via another protocol (FastCGI, SCGI or AJP) to the socket only for dynamic content, while static content is usually handled directly by the Web server. This approach needs fewer application processes so consumes less memory than the Web server extension approach. And unlike converting an application program to a Web server extension, FastCGI, SCGI, and AJP application programs remain independent of the Web server.
  • Jakarta EE runs Jakarta Servlet applications in a Web container to serve dynamic content and optionally static content which replaces the overhead of creating and destroying processes with the much lower overhead of creating and destroying threads. It also exposes the programmer to the library that comes with Java SE on which the version of Jakarta EE in use is based.

The optimal configuration for any Web application depends on application-specific details, amount of traffic, and complexity of the transaction; these trade-offs need to be analyzed to determine the best implementation for a given task and time budget. Web frameworks offer an alternative to using CGI scripts to interact with user agents.

See also[edit]

  • CGI.pm
  • DOS Gateway Interface (DGI)
  • FastCGI
  • Perl Web Server Gateway Interface
  • Rack (web server interface)
  • Server Side Includes
  • Web Server Gateway Interface

References[edit]

  1. ^ Robinson <drtr@apache.org>, David. «The Common Gateway Interface (CGI) Version 1.1». tools.ietf.org. Retrieved 16 February 2021.
  2. ^ Robinson <drtr@apache.org>, David. «The Common Gateway Interface (CGI) Version 1.1». tools.ietf.org. Archived from the original on 11 February 2007. Retrieved 16 February 2021.
  3. ^ a b c «RFC3875: The Common Gateway Interface (CGI) Version 1.1».
  4. ^ McCool, Rob (November 14, 1993). «Server Scripts». www-talk (Mailing list). Retrieved 2019-05-15.
  5. ^ «The Common Gateway Interface». hoohoo.ncsa.uiuc.edu. National Center for Supercomputing Applications (NCSA). Archived from the original on 27 January 2010.
  6. ^ «CGI: Common Gateway Interface». w3.org. World Wide Web Consortium. Retrieved 2019-05-15.
  7. ^ «Common Gateway Interface RFC Project Page». Archived from the original on 25 August 2013.
  8. ^ «Mapping URLs to Filesystem Locations Apache HTTP Server Version 2.2».
  9. ^ Nelson, Anne Fulcher, and Nelson, William Harris Morehead. (2001). Building Electronic Commerce with Web Database Constructions. Boston, MA: Addison Wesley.
  10. ^ «CGI Primer (Mirror at citycat.ru)».
  11. ^ «Abacles HTML Forms». www.abacles.com. Archived from the original on 19 April 2016. Retrieved 6 April 2016.
  12. ^ «phf CGI Script fails to guard against newline characters». Software Engineering Institute CERT Coordination Center. Retrieved 21 November 2019.
  13. ^ Enrico Marino (11 September 2018). Information Management in the Distributed Web (PDF) (phd). Roma Tre University. Archived (PDF) from the original on 12 February 2019. Retrieved 11 February 2019.

External links[edit]

  • GNU cgicc, a C++ class library for writing CGI applications
  • CGI, a standard Perl module for CGI request parsing and HTML response generation
  • CGI Programming 101: Learn CGI Today!, a CGI tutorial
  • The Invention of CGI

This article is about the software interface between a Web server and programs. For other uses, see CGI (disambiguation).

In computing, Common Gateway Interface (CGI) is an interface specification that enables web servers to execute an external program, typically to process user requests.[1]

Such programs are often written in a scripting language and are commonly referred to as CGI scripts, but they may include compiled programs.[2]

A typical use case occurs when a web user submits a web form on a web page that uses CGI. The form’s data is sent to the web server within an HTTP request with a URL denoting a CGI script. The web server then launches the CGI script in a new computer process, passing the form data to it. The output of the CGI script, usually in the form of HTML, is returned by the script to the Web server, and the server relays it back to the browser as its response to the browser’s request.[3]

Developed in the early 1990s, CGI was the earliest common method available that allowed a web page to be interactive.

History[edit]

The official CGI logo from the spec announcement

In 1993, the National Center for Supercomputing Applications (NCSA) team wrote the specification for calling command line executables on the www-talk mailing list.[4][5][6] The other Web server developers adopted it, and it has been a standard for Web servers ever since. A work group chaired by Ken Coar started in November 1997 to get the NCSA definition of CGI more formally defined.[7] This work resulted in RFC 3875, which specified CGI Version 1.1. Specifically mentioned in the RFC are the following contributors:[3]

  • Rob McCool (author of the NCSA HTTPd Web server)
  • John Franks (author of the GN Web server)
  • Ari Luotonen (the developer of the CERN httpd Web server)
  • Tony Sanders (author of the Plexus Web server)
  • George Phillips (Web server maintainer at the University of British Columbia)

Historically CGI programs were often written using the C programming language. RFC 3875 «The Common Gateway Interface (CGI)» partially defines CGI using C,[3] in saying that environment variables «are accessed by the C library routine getenv() or variable environ».

The name CGI comes from the early days of the Web, where webmasters wanted to connect legacy information systems such as databases to their Web servers. The CGI program was executed by the server that provided a common «gateway» between the Web server and the legacy information system.

Purpose of the CGI specification[edit]

Each Web server runs HTTP server software, which responds to requests from web browsers. Generally, the HTTP server has a directory (folder), which is designated as a document collection – files that can be sent to Web browsers connected to this server.[8] For example, if the Web server has the domain name example.com, and its document collection is stored at /usr/local/apache/htdocs/ in the local file system, then the Web server will respond to a request for http://example.com/index.html by sending to the browser the (pre-written) file /usr/local/apache/htdocs/index.html.

For pages constructed on the fly, the server software may defer requests to separate programs and relay the results to the requesting client (usually, a Web browser that displays the page to the end user). In the early days of the Web, such programs were usually small and written in a scripting language; hence, they were known as scripts.

Such programs usually require some additional information to be specified with the request. For instance, if Wikipedia were implemented as a script, one thing the script would need to know is whether the user is logged in and, if logged in, under which name. The content at the top of a Wikipedia page depends on this information.

HTTP provides ways for browsers to pass such information to the Web server, e.g. as part of the URL. The server software must then pass this information through to the script somehow.

Conversely, upon returning, the script must provide all the information required by HTTP for a response to the request: the HTTP status of the request, the document content (if available), the document type (e.g. HTML, PDF, or plain text), et cetera.

Initially, different server software would use different ways to exchange this information with scripts. As a result, it wasn’t possible to write scripts that would work unmodified for different server software, even though the information being exchanged was the same. Therefore, it was decided to specify a way for exchanging this information: CGI (the Common Gateway Interface, as it defines a common way for server software to interface with scripts).
Webpage generating programs invoked by server software that operate according to the CGI specification are known as CGI scripts.

This specification was quickly adopted and is still supported by all well-known server software, such as Apache, IIS, and (with an extension) node.js-based servers.

An early use of CGI scripts was to process forms. In the beginning of HTML, HTML forms typically had an «action» attribute and a button designated as the «submit» button. When the submit button is pushed the URI specified in the «action» attribute would be sent to the server with the data from the form sent as a query string. If the «action» specifies a CGI script then the CGI script would be executed and it then produces an HTML page.

Using CGI scripts[edit]

A Web server allows its owner to configure which URLs shall be handled by which CGI scripts.

This is usually done by marking a new directory within the document collection as containing CGI scripts – its name is often cgi-bin. For example, /usr/local/apache/htdocs/cgi-bin could be designated as a CGI directory on the Web server. When a Web browser requests a URL that points to a file within the CGI directory (e.g., http://example.com/cgi-bin/printenv.pl/with/additional/path?and=a&query=string), then, instead of simply sending that file (/usr/local/apache/htdocs/cgi-bin/printenv.pl) to the Web browser, the HTTP server runs the specified script and passes the output of the script to the Web browser. That is, anything that the script sends to standard output is passed to the Web client instead of being shown on-screen in a terminal window.

As remarked above, the CGI specification defines how additional information passed with the request is passed to the script.
For instance, if a slash and additional directory name(s) are appended to the URL immediately after the name of the script (in this example, /with/additional/path), then that path is stored in the PATH_INFO environment variable before the script is called. If parameters are sent to the script via an HTTP GET request (a question mark appended to the URL, followed by param=value pairs; in the example, ?and=a&query=string), then those parameters are stored in the QUERY_STRING environment variable before the script is called. If parameters are sent to the script via an HTTP POST request, they are passed to the script’s standard input. The script can then read these environment variables or data from standard input and adapt to the Web browser’s request.[9]

Example[edit]

The following Perl program shows all the environment variables passed by the Web server:

#!/usr/bin/env perl

=head1 DESCRIPTION

printenv — a CGI program that just prints its environment

=cut
print "Content-Type: text/plainnn";

foreach ( sort keys %ENV ) {
    print "$_="$ENV{$_}"n";
}

If a Web browser issues a request for the environment variables at http://example.com/cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with%20percent%20encoding, a 64-bit Windows 7 Web server running cygwin returns the following information:

COMSPEC="C:Windowssystem32cmd.exe"
DOCUMENT_ROOT="C:/Program Files (x86)/Apache Software Foundation/Apache2.4/htdocs"
GATEWAY_INTERFACE="CGI/1.1"
HOME="/home/SYSTEM"
HTTP_ACCEPT="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q=0.7,*;q=0.7"
HTTP_ACCEPT_ENCODING="gzip, deflate, br"
HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5"
HTTP_CONNECTION="keep-alive"
HTTP_HOST="example.com"
HTTP_USER_AGENT="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:67.0) Gecko/20100101 Firefox/67.0"
PATH="/home/SYSTEM/bin:/bin:/cygdrive/c/progra~2/php:/cygdrive/c/windows/system32:..."
PATHEXT=".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC"
PATH_INFO="/foo/bar"
PATH_TRANSLATED="C:Program Files (x86)Apache Software FoundationApache2.4htdocsfoobar"
QUERY_STRING="var1=value1&var2=with%20percent%20encoding"
REMOTE_ADDR="127.0.0.1"
REMOTE_PORT="63555"
REQUEST_METHOD="GET"
REQUEST_URI="/cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with%20percent%20encoding"
SCRIPT_FILENAME="C:/Program Files (x86)/Apache Software Foundation/Apache2.4/cgi-bin/printenv.pl"
SCRIPT_NAME="/cgi-bin/printenv.pl"
SERVER_ADDR="127.0.0.1"
SERVER_ADMIN="(server admin's email address)"
SERVER_NAME="127.0.0.1"
SERVER_PORT="80"
SERVER_PROTOCOL="HTTP/1.1"
SERVER_SIGNATURE=""
SERVER_SOFTWARE="Apache/2.4.39 (Win32) PHP/7.3.7"
SYSTEMROOT="C:Windows"
TERM="cygwin"
WINDIR="C:Windows"

Some, but not all, of these variables are defined by the CGI standard.
Some, such as PATH_INFO, QUERY_STRING, and the ones starting with HTTP_, pass information along from the HTTP request.

From the environment, it can be seen that the Web browser is Firefox running on a Windows 7 PC, the Web server is Apache running on a system that emulates Unix, and the CGI script is named cgi-bin/printenv.pl.

The program could then generate any content, write that to standard output, and the Web server will transmit it to the browser.

The following are environment variables passed to CGI programs:

  • Server specific variables:
    • SERVER_SOFTWARE: name/version of HTTP server.
    • SERVER_NAME: host name of the server, may be dot-decimal IP address.
    • GATEWAY_INTERFACE: CGI/version.
  • Request specific variables:
    • SERVER_PROTOCOL: HTTP/version.
    • SERVER_PORT: TCP port (decimal).
    • REQUEST_METHOD: name of HTTP method (see above).
    • PATH_INFO: path suffix, if appended to URL after program name and a slash.
    • PATH_TRANSLATED: corresponding full path as supposed by server, if PATH_INFO is present.
    • SCRIPT_NAME: relative path to the program, like /cgi-bin/script.cgi.
    • QUERY_STRING: the part of URL after ? character. The query string may be composed of *name=value pairs separated with ampersands (such as var1=val1&var2=val2…) when used to submit form data transferred via GET method as defined by HTML application/x-www-form-urlencoded.
    • REMOTE_HOST: host name of the client, unset if server did not perform such lookup.
    • REMOTE_ADDR: IP address of the client (dot-decimal).
    • AUTH_TYPE: identification type, if applicable.
    • REMOTE_USER used for certain AUTH_TYPEs.
    • REMOTE_IDENT: see ident, only if server performed such lookup.
    • CONTENT_TYPE: Internet media type of input data if PUT or POST method are used, as provided via HTTP header.
    • CONTENT_LENGTH: similarly, size of input data (decimal, in octets) if provided via HTTP header.
    • Variables passed by user agent (HTTP_ACCEPT, HTTP_ACCEPT_LANGUAGE, HTTP_USER_AGENT, HTTP_COOKIE and possibly others) contain values of corresponding HTTP headers and therefore have the same sense.

The program returns the result to the Web server in the form of standard output, beginning with a header and a blank line.

The header is encoded in the same way as an HTTP header and must include the MIME type of the document returned.[10] The headers, supplemented by the Web server, are generally forwarded with the response back to the user.

Here is a simple CGI program written in Python 3 along with the HTML that handles a simple addition problem.[11]

add.html:

<!DOCTYPE html>
<html>
 <body>
  <form action="add.cgi" method="POST">
   <fieldset>
     <legend>Enter two numbers to add</legend>
     <label>First Number: <input type="number" name="num1"></label><br/>
     <label>Second Number: <input type="number" name="num2"></label><br/>
   </fieldset>
   <button>Add</button>
  </form>
 </body>
</html>

add.cgi:

#!/usr/bin/env python3

import cgi, cgitb
cgitb.enable()

input_data = cgi.FieldStorage()

print("Content-Type: text/html") # HTML is following
print("")                        # Leave a blank line
print("<h1>Addition Results</h1>")
try:
    num1 = int(input_data["num1"].value)
    num2 = int(input_data["num2"].value)
except:
    print("<output>Sorry, the script cannot turn your inputs into numbers (integers).</output>")
    raise SystemExit(1)
print("<output>{0} + {1} = {2}</output>".format(num1, num2, num1 + num2))

This Python 3 CGI program gets the inputs from the HTML and adds the two numbers together.

Deployment[edit]

A Web server that supports CGI can be configured to interpret a URL that it serves as a reference to a CGI script. A common convention is to have a cgi-bin/ directory at the base of the directory tree and treat all executable files within this directory (and no other, for security) as CGI scripts. Another popular convention is to use filename extensions; for instance, if CGI scripts are consistently given the extension .cgi, the Web server can be configured to interpret all such files as CGI scripts. While convenient, and required by many prepackaged scripts, it opens the server to attack if a remote user can upload executable code with the proper extension.

In the case of HTTP PUT or POSTs, the user-submitted data are provided to the program via the standard input. The Web server creates a subset of the environment variables passed to it and adds details pertinent to the HTTP environment.

Uses[edit]

CGI is often used to process input information from the user and produce the appropriate output. An example of a CGI program is one implementing a wiki. If the user agent requests the name of an entry, the Web server executes the CGI program. The CGI program retrieves the source of that entry’s page (if one exists), transforms it into HTML, and prints the result. The Web server receives the output from the CGI program and transmits it to the user agent. Then if the user agent clicks the «Edit page» button, the CGI program populates an HTML textarea or other editing control with the page’s contents. Finally if the user agent clicks the «Publish page» button, the CGI program transforms the updated HTML into the source of that entry’s page and saves it.

Security[edit]

CGI programs run, by default, in the security context of the Web server. When first introduced a number of example scripts were provided with the reference distributions of the NCSA, Apache and CERN Web servers to show how shell scripts or C programs could be coded to make use of the new CGI. One such example script was a CGI program called PHF that implemented a simple phone book.

In common with a number of other scripts at the time, this script made use of a function: escape_shell_cmd(). The function was supposed to sanitize its argument, which came from user input and then pass the input to the Unix shell, to be run in the security context of the Web server. The script did not correctly sanitize all input and allowed new lines to be passed to the shell, which effectively allowed multiple commands to be run. The results of these commands were then displayed on the Web server. If the security context of the Web server allowed it, malicious commands could be executed by attackers.

This was the first widespread example of a new type of Web based attack, where unsanitized data from Web users could lead to execution of code on a Web server. Because the example code was installed by default, attacks were widespread and led to a number of security advisories in early 1996.[12]

Alternatives[edit]

For each incoming HTTP request, a Web server creates a new CGI process for handling it and destroys the CGI process after the HTTP request has been handled. Creating and destroying a process can consume much more CPU and memory than the actual work of generating the output of the process, especially when the CGI program still needs to be interpreted by a virtual machine. For a high number of HTTP requests, the resulting workload can quickly overwhelm the Web server.

The overhead involved in CGI process creation and destruction can be reduced by the following techniques:

  • CGI programs precompiled to machine code, e.g. precompiled from C or C++ programs, rather than CGI programs interpreted by a virtual machine, e.g. Perl, PHP or Python programs.
  • Web server extensions such as Apache modules (e.g. mod_perl, mod_php, mod_python), NSAPI plugins, and ISAPI plugins which allow long-running application processes handling more than one request and hosted within the Web server. Web 2.0 allows to transfer data from the client to the server without using HTML forms and without the user noticing.[13]
  • FastCGI, SCGI, and AJP which allow long-running application processes handling more than one request to be hosted externally; i.e., separately from the Web server. Each application process listens on a socket; the Web server handles an HTTP request and sends it via another protocol (FastCGI, SCGI or AJP) to the socket only for dynamic content, while static content is usually handled directly by the Web server. This approach needs fewer application processes so consumes less memory than the Web server extension approach. And unlike converting an application program to a Web server extension, FastCGI, SCGI, and AJP application programs remain independent of the Web server.
  • Jakarta EE runs Jakarta Servlet applications in a Web container to serve dynamic content and optionally static content which replaces the overhead of creating and destroying processes with the much lower overhead of creating and destroying threads. It also exposes the programmer to the library that comes with Java SE on which the version of Jakarta EE in use is based.

The optimal configuration for any Web application depends on application-specific details, amount of traffic, and complexity of the transaction; these trade-offs need to be analyzed to determine the best implementation for a given task and time budget. Web frameworks offer an alternative to using CGI scripts to interact with user agents.

See also[edit]

  • CGI.pm
  • DOS Gateway Interface (DGI)
  • FastCGI
  • Perl Web Server Gateway Interface
  • Rack (web server interface)
  • Server Side Includes
  • Web Server Gateway Interface

References[edit]

  1. ^ Robinson <drtr@apache.org>, David. «The Common Gateway Interface (CGI) Version 1.1». tools.ietf.org. Retrieved 16 February 2021.
  2. ^ Robinson <drtr@apache.org>, David. «The Common Gateway Interface (CGI) Version 1.1». tools.ietf.org. Archived from the original on 11 February 2007. Retrieved 16 February 2021.
  3. ^ a b c «RFC3875: The Common Gateway Interface (CGI) Version 1.1».
  4. ^ McCool, Rob (November 14, 1993). «Server Scripts». www-talk (Mailing list). Retrieved 2019-05-15.
  5. ^ «The Common Gateway Interface». hoohoo.ncsa.uiuc.edu. National Center for Supercomputing Applications (NCSA). Archived from the original on 27 January 2010.
  6. ^ «CGI: Common Gateway Interface». w3.org. World Wide Web Consortium. Retrieved 2019-05-15.
  7. ^ «Common Gateway Interface RFC Project Page». Archived from the original on 25 August 2013.
  8. ^ «Mapping URLs to Filesystem Locations Apache HTTP Server Version 2.2».
  9. ^ Nelson, Anne Fulcher, and Nelson, William Harris Morehead. (2001). Building Electronic Commerce with Web Database Constructions. Boston, MA: Addison Wesley.
  10. ^ «CGI Primer (Mirror at citycat.ru)».
  11. ^ «Abacles HTML Forms». www.abacles.com. Archived from the original on 19 April 2016. Retrieved 6 April 2016.
  12. ^ «phf CGI Script fails to guard against newline characters». Software Engineering Institute CERT Coordination Center. Retrieved 21 November 2019.
  13. ^ Enrico Marino (11 September 2018). Information Management in the Distributed Web (PDF) (phd). Roma Tre University. Archived (PDF) from the original on 12 February 2019. Retrieved 11 February 2019.

External links[edit]

  • GNU cgicc, a C++ class library for writing CGI applications
  • CGI, a standard Perl module for CGI request parsing and HTML response generation
  • CGI Programming 101: Learn CGI Today!, a CGI tutorial
  • The Invention of CGI
.. seealso::

    * https://ru.wikipedia.org/wiki/CGI
    * http://www.ietf.org/rfc/rfc3875.txt
    * `Лекции ОмГТУ, кафедра АСОИУ <http://www.4stud.info/web-programming/cgi.html>`_
    * http://webpython.codepoint.net/cgi_tutorial

CGI (от англ. Common Gateway Interface — «общий интерфейс шлюза») — стандарт интерфейса, используемого для связи внешней программы с веб-сервером. Программу, которая работает по такому интерфейсу совместно с веб-сервером, принято называть шлюзом, хотя многие предпочитают названия «скрипт» (сценарий) или «CGI-программа».

Поскольку гипертекст статичен по своей природе, веб-страница не может непосредственно взаимодействовать с пользователем. До появления JavaScript, не было иной возможности отреагировать на действия пользователя, кроме как передать введенные им данные на веб-сервер для дальнейшей обработки. В случае CGI эта обработка осуществляется с помощью внешних программ и скриптов, обращение к которым выполняется через стандартизованный (см. RFC 3875: CGI Version 1.1) интерфейс — общий шлюз.

Упрощенная модель, иллюстрирующая работу CGI:

/_static/5.web.server/cgi.*

Сам интерфейс разработан таким образом, чтобы можно было использовать любой язык программирования, который может работать со стандартными устройствами ввода-вывода. Такими возможностями обладают даже скрипты для встроенных командных интерпретаторов операционных систем, поэтому в простых случаях могут использоваться даже командные скрипты.

Как работает CGI?

Обобщенный алгоритм работы через CGI можно представить в следующем виде:

  1. Клиент запрашивает CGI-приложение по его URI.
  2. Веб-сервер принимает запрос и устанавливает переменные окружения, через них приложению передаются данные и служебная информация.
  3. Веб-сервер перенаправляет запросы через стандартный поток ввода (stdin) на вход вызываемой программы.
  4. CGI-приложение выполняет все необходимые операции и формирует результаты в виде HTML.
  5. Сформированный гипертекст возвращается веб-серверу через стандартный поток вывода (stdout). Сообщения об ошибках передаются через stderr.
  6. Веб-сервер передает результаты запроса клиенту.

Области применения CGI

Наиболее частая задача, для решения которой применяется CGI — создание интерактивных страниц, содержание которых зависит от действий пользователя. Типичными примерами таких веб-страниц является форма регистрации на сайте или форма для отправки комментария. Другая область применения CGI, остающаяся за кулисами взаимодействия с пользователем, связана со сбором и обработкой информации о клиенте: установка и чтение «печенюшек»-cookies; получение данных о браузере и операционной системе; подсчет количества посещений веб-страницы; мониторинг веб-трафика и т.п.

Это обеспечивается возможностью подключения CGI-скрипта к базе данных, а также возможностью обращаться к файловой системе сервера. Таким образом CGI-скрипт может сохранять информацию в таблицах БД или файлах и получать ее оттуда по запросу, чего нельзя сделать средствами HTML.

Warning

CGI — это не язык программирования! Это простой протокол, позволяющий веб-серверу передавать данные через stdin и читать их из stdout. Поэтому в качестве CGI-обработчика может использоваться любая серверная программа, способная работать со стандартными потоками ввода-вывода.

Примеры

Пример на Python:

#!/usr/bin/python
print("""Content-Type: text/plain

Hello, world!""")

В этом коде строка #!/usr/bin/python указывает полный путь к интерпретатору Python.

Пример на Си:

#include <stdio.h>
int main(void) {
  printf("Content-Type: text/plainnn");
  printf("Hello, world!nn");
  return 0;
}

Строка Content-type: text/htmlnn — http-заголовок, задающий тип содержимого (mime-type). Удвоенный символ разрыва строки (nn) — обязателен, он отделяет заголовки от тела сообщения.

Все скрипты, как правило, помещают в каталог cgi (или cgi-bin) сервера, но это необязательно: скрипт может располагаться где угодно, но при этом большинство веб-серверов требуют специальной настройки. В веб-сервере Apache, например, такая настройка может производиться при помощи общего файла настроек httpd.conf или с помощью файла .htaccess в том каталоге, где содержится этот скрипт. Также скрипты должны иметь права на исполнение (chmod +x hello.py).

Переменные окружения

Все CGI-приложения имеют доступ к переменным окружения, устанавливаемым веб-сервером. Эти переменные играют важную роль при написании CGI-программ. В таблице перечислены некоторые из переменных, доступных CGI.

Пример вывода переменных окружения CGI-скрипта:

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/2.environment.py
   :language: python
   :linenos:

/_static/5.web.server/cgi_env.png

Преимущества CGI

  • Процесс CGI скрипта не зависит от Веб-сервера и, в случае падения, никак не отразится на работе последнего
  • Может быть написан на любом языке программирования
  • Поддерживается большинством Веб-серверов

Недостатки CGI

Самым большим недостатком этой технологии являются повышенные требования к производительности веб-сервера. Дело в том, что каждое обращение к CGI-приложению вызывает порождение нового процесса, со всеми вытекающими отсюда накладными расходами. Если же приложение написано с ошибками, то возможна ситуация, когда оно, например, зациклится. Браузер прервет соединение по истечении тайм-аута, но на серверной стороне процесс будет продолжаться, пока администратор не снимет его принудительно.

Альтернативы

  • FastCGI — дальнейшее развитие технологии CGI. Поддерживается
    многими Веб-серверами, например Nginx.
  • Веб-сервера, в которые уже встроена поддержка дополнительных
    стандартов и протоколов, таких как WSGI (Gunicorn, waitress, uwsgi)
  • Веб-сервер, функционал которого расширяется через модули, например,
    Apache (mod_wsgi, mod_php, mod_fastcgi)

Практика

.. seealso::

   * https://docs.python.org/2/library/cgihttpserver.html
   * https://docs.python.org/3/library/http.server.html

Для запуска CGI сервера необходимо перейти в директорию sourcecode
и выполнить команду:

python -m CGIHTTPServer 8000

или

python3 -m http.server --cgi 8000

или cgiserver.py

.. literalinclude:: /../sourcecode/5.web.server/cgiserver.py
   :language: python
   :linenos:

Теперь CGI-скрипты доступны на 8000 порту,
например по адресу http://localhost:8000/cgi-bin/1.hello.py

  • Пример CGI скриптов на Python
  • Пример CGI скриптов на C++

Note

Для компиляции кода на C++ необходимо установить библиотеку cgicc:

sudo apt-get install libcgicc5-dev

Пример компиляции:

g++ -o 3.get.post.cgi 3.get.post.cpp -lcgicc

Hello World!

Note

  • http://localhost:8000/cgi-bin/1.hello.cgi
  • http://localhost:8000/cgi-bin/1.hello.go.cgi
  • http://localhost:8000/cgi-bin/1.hello.py
  • http://localhost:8000/cgi-bin/1.hello.rb

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/1.hello.py
   :language: python
   :linenos:

Ruby

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/1.hello.rb
   :language: ruby
   :linenos:

C++

Для компиляции: make 1_hello

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/1.hello.cpp
   :language: cpp
   :linenos:

Go

Для компиляции: make 1_hello_go

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/1.hello.go
   :language: go
   :linenos:

Вывод переменных окружения

Note

  • http://localhost:8000/cgi-bin/2.environment.cgi
  • http://localhost:8000/cgi-bin/2.environment.py
  • http://localhost:8000/cgi-bin/2.environment.rb

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/2.environment.py
   :language: python
   :linenos:

Ruby

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/2.environment.rb
   :language: ruby
   :linenos:

C++

Для компиляции: make 2_environment

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/2.environment.cpp
   :language: cpp
   :linenos:

GET и POST запросы

Note

  • http://localhost:8000/cgi-bin/3.get.post.cgi?first_name=Lev&last_name=Tolstoy
  • http://localhost:8000/cgi-bin/3.get.post.py?first_name=Lev&last_name=Tolstoy
  • http://localhost:8000/cgi-bin/3.get.post.rb?first_name=Lev&last_name=Tolstoy
  • GET (action=»http://localhost:8000/cgi-bin/3.get.post.cgi» method=»get»)

    .. todo:: Add LaTeX support
    
    

    First Name:
    Last Name:

  • POST (action=»http://localhost:8000/cgi-bin/3.get.post.cgi» method=»post»)

    .. todo:: Add LaTeX support
    
    

    First Name:
    Last Name:

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/3.get.post.py
   :language: python
   :linenos:

Ruby

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/3.get.post.rb
   :language: ruby
   :linenos:

C++

Для компиляции: make 3_get_post

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/3.get.post.cpp
   :language: cpp
   :linenos:

Checkbox

.. todo:: Add LaTeX support

Maths
Physics

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/4.checkbox.py
   :language: python
   :linenos:

C++

Для компиляции: make 4_checkbox

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/4.checkbox.cpp
   :language: cpp
   :linenos:

Radio

.. todo:: Add LaTeX support

Maths
Physics

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/5.radio.py
   :language: python
   :linenos:

C++

Для компиляции: make 5_radio

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/5.radio.cpp
   :language: cpp
   :linenos:

TextArea

.. todo:: Add LaTeX support

Type your text here…

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/6.textarea.py
   :language: python
   :linenos:

C++

Для компиляции: make 6_textarea

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/6.textarea.cpp
   :language: cpp
   :linenos:

Drop Down Box

.. todo:: Add LaTeX support

Maths
Physics

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/7.dropdown.py
   :language: python
   :linenos:

C++

Для компиляции: make 7_dropdown

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/7.dropdown.cpp
   :language: cpp
   :linenos:

Печать Cookie

Note

  • http://localhost:8000/cgi-bin/8.getcookie.cgi
  • http://localhost:8000/cgi-bin/8.getcookie.py

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/8.getcookie.py
   :language: python
   :linenos:

C++

Для компиляции: make 8_getcookie

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/8.getcookie.cpp
   :language: cpp
   :linenos:

Установка Cookie

Note

  • http://localhost:8000/cgi-bin/9.setcookie.cgi
  • http://localhost:8000/cgi-bin/9.setcookie.py

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/9.setcookie.py
   :language: python
   :linenos:

C++

Для компиляции: make 9_setcookie

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/9.setcookie.cpp
   :language: cpp
   :linenos:

Загрузка файлов

.. todo:: Add LaTeX support

File:

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/10.fileupload.py
   :language: python
   :linenos:

C++

Для компиляции: make 10_fileupload

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/10.fileupload.cpp
   :language: cpp
   :linenos:

Отладка

.. seealso::

   * http://pymotw.com/2/cgitb/
   * https://docs.python.org/2/library/cgitb.html

Python

.. literalinclude:: /../sourcecode/5.web.server/cgi-bin/test.py
   :language: python
   :linenos:
   :emphasize-lines: 24

/_static/5.web.server/cgitb.png

Стандарт cgi. Сценарии. Сценарные языки: классификация по быстродействию. Язык Python. Язык Ruby. Технология asp. Интерфейс isapi.

Для
расширения возможностей клиент-серверного
взаимодействия в рамках протокола HTTP
помимо создания на клиентской стороне
расширений стандартных возможностей,
предоставляемых языками разметки и
браузерами, можно также разрабатывать
на стороне веб-сервера приложения,
плагины и сценарии, расширяющие
возможности самого веб-сервера.

Плагин
(plug-in) — независимо компилируемый
программный модуль, динамически
подключаемый к основной программе,
предназначенный для расширения или
использования ее возможностей. Обычно
выполняются в виде разделяемых библиотек.

Сценарий
(скрипт,
script) — программа, которая автоматизирует
некоторую задачу, которую пользователь
выполняет вручную используя интерфейсы
программы.

Стандарт cgi

Круг
задач, решаемых Web-сервером, ограничен.
В основном он сводится к поддержке
НТТР-взаимодействия и доставке клиенту
Web-документов. Любые «нестандартные»
действия реализуются с помощью специальной
программы, которая взаимодействует с
веб-сервером и клиентом. Это взаимодействие
подчиняется определенным правилам.

Основной
набор таких правил — стандарт CGI (Common
Gateway Interface — интерфейс общего шлюза),
который определяет порядок запуска
программы на компьютере-сервере, способы
передачи программе параметров и доставки
результатов ее выполнения клиенту.
Программа, написанная по правилам CGI,
называется CGI-сценарием (script CGI), хотя
это не означает, что на сервере не может
выполняться двоичный файл.

Благодаря
этому интерфейсу для разработки
приложений можно использовать любой
язык программирования, который располагает
средствами взаимодействия со стандартными
устройствами ввода/вывода. Такими
возможностями обладают в также сценарии
для встроенных командных интерпретаторов
операционных систем.

Выполнение
любой программы (в том числе CGI-сценария)
можно условно разделить на пять этапов.

  1. Запуск
    программы.

  2. Инициализация
    и чтение выходных данных.

  3. Обработка
    данных.

  4. Вывод
    результатов выполнения.

  5. Завершение
    программы.

Различия
между CGI-сценарием и консольным приложением
касаются первого, второго и четвертого
этапов выполнения.

Каждый
раз, когда веб-сервер получает запрос
от клиента, он анализирует содержимое
запроса и возвращает соответствующий
ответ:

  • Если
    запрос содержит указание на файл,
    находящийся на жестком диске, то сервер
    возвращает в составе ответа этот файл;

  • Если
    запрос содержит указание на программу
    и необходимые для нее аргументы, то
    сервер исполняет программу и результат
    ее работы возвращает клиенту.

Cgi определяет:

  • каким
    образом информация о сервере и запросе
    клиента передается программе в форме
    аргументов и переменных окружения;

  • каким
    образом программа может передавать
    назад дополнительную информацию о
    результатах (например о типе данных) в
    форме заголовков ответа сервера.

В
подавляющем большинстве случаев запуск
CGI-сценария осуществляется щелчком на
кнопке Submit, сформированной с помощью
дескриптора <input tyре = «submit»>,
который находится на HTML-странице между
<form> и </form>. Не зная назначения
атрибутов action и method, невозможно понять,
как происходит вызов программы и передача
параметров.

Значением
атрибута action дескриптора <form> является
URL файла, содержащего код CGI-сценария.
Так, приведенное ниже выражение означает,
что файл с кодом CGI-сценария находится
на сервере www.myhp.edu в каталоге cgi-bin в файле
script.рl.

<form
action=»http://www.myhp.edu/cgi-bin/script.pl»
method=»post»>

Как
веб-сервер различает, что надо сделать
с файлом, на который указывает URL, —
передать его содержимое клиенту или
запустить файл на выполнение? Существует
два способа распознавания файлов,
содержащих тексты CGI-сценариев.

Первый
способ

заключается в том, что при установке
веб-сервера один из каталогов специально
выделяется для хранения сценариев.
Обычно такой каталог получает имя
cgi-bin (или Scripts для веб-сервера IIS). В этом
случае, если клиент запрашивает файл
из каталога cgi-bin, сервер воспринимает
такой запрос как команду на запуск
сценария. Файлы из других каталогов
интерпретируются как HTML-документы.

Второй
способ

использует расширение файла. При
настройке сервера указывается, что
файлы с определенными расширениями
содержат коды сценариев.

Идентификация
по расширению используется относительно
редко. Чаще всего все сценарии помещаются
в cgi-bin, /Scripts или в другой каталог,
специально выделенный для их хранения.

Вывод
результатов выполнения CGI-сценария
осуществляется чрезвычайно просто. Для
того чтобы данные были переданы клиенту,
достаточно вывести их в стандартный
выходной поток. Однако, разрабатывая
CGI-сценарий, не следует забывать о том,
что он все же отличается от консольной
программы и имеет следующие особенности.

Информация,
передаваемая клиенту, должна соответствовать
протоколу HTTP, т.е. состоять из заголовка
и тела ответа. Как правило, получив
данные от сценария, сервер самостоятельно
добавляет первую строку заголовка.

НТТР/1.0
200 OK

Формирование
информационных полей, входящих в состав
заголовка, — задача сценария. Чтобы
данные, переданные сценарием, были
правильно интерпретированы клиентом,
необходимо, чтобы в заголовке присутствовало
как минимум поле Content-type. За заголовком
должна следовать пустая строка. При
отсутствии полей заголовка реакция
браузера будет непредсказуемой. В
подобных случаях браузер обычно пытается
отобразить полученную информацию как
текстовый файл.

Самый
естественный формат для браузера —
формат HTML. Результаты работы сценария
обычно оформляются в виде веб-страницы,
т.е. возвращаемые данные следует дополнить
дескрипторами HTML. Таким образом, ответ
CGI-сценария клиенту обычно выглядит
так:

Content-type:
text/html

<html>

<hеаd>

<titlе>ответ
сценария</titlе>

</hеаd>

<body>

……………………

</body>

</html>

Обратите
внимание на пустую строку после выражения
Content-type: text/html. Она обязательно должна
присутствовать в ответе, в противном
случае клиент воспримет все последующие
данные как продолжение заголовка.

После
компиляции программы необходимо
скопировать исполняемый файл в каталог
cgi-bin (или в другой каталог, предназначенный
для размещения исполняемых файлов) из
которого он может запускаться веб-сервером
на выполнение по запросу клиента.

Для
вызова данного сценария достаточно
включить в веб-страницу следующий
фрагмент HTML-кода:

<form
method=»post»
action=»http://www.intuit.ru/cgi-bin/hello.exe»>

<input
type=»submit»>

</form>

Если
сценарий вызывается из формы, ему
передаются те данные, которые пользователь
ввел с помощью интерактивных элементов,
отображаемых на веб-странице — передача
информации CGI-сценарию осуществляется
в два этапа: сначала браузер передает
данные веб-серверу, затем веб-сервер
передает их сценарию.

В
большинстве случаев кроме кнопки Submit
форма содержит другие интерактивные
элементы, каждый из которых имеет имя
(атрибут NAME) и значение (атрибут VALUE, либо
последовательность символов, введенная
пользователем). Из имен элементов и их
значений формируется строка параметров,
которая имеет следующий формат.

имя=значение&имя=значение&
. . . &имя=значение

Каждый
параметр представляет собой имя
управляющего элемента и его значение,
разделенные знаком равенства, а несколько
таких пар объединяют строку с помощью
символа «&». Если в состав имени
или значения входит символ «&»
или «=», то подобные символы кодируются
последовательность знака процента «%»,
за которым следуют две шестнадцатеричные
цифры, определяющие код символа. Так,
например, последовательностью «%21»
кодируется восклицательный знак «!».
Как правило, при передаче параметров
трехсимвольными последовательностями
заменяются все знаки, кроме латинских
букв, цифр и символа пробела (последний
заменяется знаком «+»).

Таким
образом, перед использованием строки
параметров ее надо декодировать. Алгоритм
декодирования чрезвычайно прост и
включает в себя следующие действия:

  • Выделить
    из строки параметров пары имя = значение.

  • Выделить
    из каждой пары имя и значение.

  • В
    каждом имени и каждом значении заменить
    символы «+» пробелами.

  • Каждую
    последовательность из символа «%»
    и двух шестнадцатеричных и преобразовать
    в ASCII-символ.

Атрибут
method дескриптора <form> имеет либо
значение «GET», либо значение «POST».
Значения «GET» и «POST» определяют
два различных метода передачи параметров
сценарию:

  • Если
    атрибут method имеет значение «GET»,
    строка параметров передается вместе
    с URL вызываемого сценария. Разделителем
    между URL и строкой параметров является
    символ «?».

  • Если
    атрибут method имеет значение «POST»,
    строка параметров передается в теле
    HTTP-запроса.

Рассмотрим,
как должен вести себя CGI-сценарий, чтобы
правильно обработать данные в зависимости
от метода, использованного при передаче
данных, строка параметров доставляется
CGI-сценарию различными способами.

Если
атрибут METHOD дескриптора <FORM> имел
значение «GET», строка параметр
передается серверу в качестве значения
переменной окружения QUERY_STRING.

При
использовании метода POST данные
доставляются сценарию по-другому. Они
передаются через стандартный поток
ввода (STDIN). Чтобы сценарий смог определить,
сколько символов следует читать из
стандартного ввода, веб-сервер
устанавливает значение переменной
окружения CONTENT_LENGTH, равным длине строки
параметров.

Получив
управление, сценарий в первую очередь
должен выяснить, с помощью какого метода
выполнялась передача параметров. Эта
информация содержится в переменной
окружения REQUEST_METHOD.

Таким
образом, в простейшем случае, чтобы
выполнить обработку строки параметров,
достаточно знать назначение трех
переменных окружения: REQUEST_METHOD, QUERY_STRING
и CONTENT_LENGTH.

Пример
сценария на языке Perl, который возвращает
клиенту строку параметров, приведен
ниже. Сценарий определяет, какой метод
использовался для передачи данных,
читает строку параметров и передает ее
клиенту, предварительно дополнив
HTML-дескрипторами.

$method
= $ENV{‘REQUEST_METHOD’};

if
($method eq «GET»)

{
$pars = $ENV{‘QUERY_STRING’}; }

else

{
$length =$ENV{‘CONTENT_LENGTH’}; }

read
(STDIN, $pars, $ length);

print
«Content-type: text/htmlnn»;

print
«<HTML><BODY>n»;

print
«<P>METHOD = «, $method;

print
«<P>String of parameters: <P>n»;

print
$pars;

print
«</HTML></BODY>n»;

При
разработке более сложных сценариев
может потребоваться дополнительная
информация. Информация о типах сервера
и браузера, адресе клиент-машины и многие
другие сведения передаются с помощью
переменных окружения. Некоторые из них
перечислены ниже

REMOTE_ADDR
IP-адрес узла, с которого поступил запрос

REMOTE_HOST
Доменное имя узла, с которого поступил
запрос

SERVER_PORT
Номер порта, который использовался при
обращении к серверу

SERVER_SOFTWARE
Имя и версия сервера, посредством
которого был запущен сценарий

SERVER_NAME
Имя или адрес узла, на котором выполняется
сервер

SERVER_PSOTOCOL
Название и версия протокола, с помощью
которого был передан запрос

HTTP_USER_AGENT
Клиентская программа, отправившая
запрос серверу

HTTP_REFERER
URL документа, отображаемого браузером
при вызове сценария

Соседние файлы в папке +Web-технол 1-36

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 17:27, 30 октября 2016.

CGI (англ. Common Gateway Interface — «общий интерфейс шлюза») — стандарт интерфейса, используемого для связи внешней программы с веб-сервером. Программу, которая работает по такому интерфейсу совместно с веб-сервером, принято называть шлюзом, хотя многие предпочитают названия «скрипт» (сценарий) или «CGI-программа». Обычно гипертекстовые документы, извлекаемые из www (world wide web) серверов, содержат статические данные. С помощью CGI можно создавать CGI-программы, называемые шлюзами, которые во взаимодействии с такими прикладными системами, как система управления базой данных, электронная таблица, деловая графика и др., смогут выдать на экран пользователя динамическую информацию.
Программа-шлюз запускается www сервером в реальном масштабе времени. www сервер обеспечивает передачу запроса пользователя шлюзу, а она в свою очередь, используя средства прикладной системы, возвращает результат обработки запроса на экран пользователя. [1]

Содержание

  • 1 Главное назначение CGI
  • 2 Общий шлюзовый интерфейс CGI
    • 2.1 Веб-серверы
  • 3 Принцип работы CGI
  • 4 Механизмы обмена данными
    • 4.1 Переменные окружения
      • 4.1.1 Общие переменные окружения
      • 4.1.2 Запрос-ориентированные окружения
      • 4.1.3 Идентификация пользователя и его машины
      • 4.1.4 Переменные, определяющие тип и длину передаваемой информации от клиента к серверу
    • 4.2 Опции командной строки
    • 4.3 Формат стандартного ввода
    • 4.4 Формат стандартного вывода
      • 4.4.1 Content-type
      • 4.4.2 Location
    • 4.5 Области применения CGI
    • 4.6 Преимущества CGI
    • 4.7 Недостатки CGI
  • 5 Примечания

Главное назначение CGI

Обеспечение единообразного потока данных между сервером и прикладной программой, которая запускается из-под сервера. CGI определяет протокол обмена данными между сервером и программой.

  • CGI определяет порядок взаимодействия сервера с прикладной программой, в котором сервер выступает инициирующей стороной;
  • CGI определяет механизм реального обмена данными и управляющими командами в этом взаимодействии, что не определено в HTTP.

Такие понятия, как метод доступа, переменные заголовка, MIME, типы данных, заимствованы из HTTP и делают спецификацию прозрачной для тех, кто знаком с самим протоколом.

При описании различных программ, которые вызываются сервером HTTP и реализованы в стандарте CGI, используют следующую терминологию:

CGI-скрипт — программа, написанная в соответствии со спецификацией Common Gateway Interface. CGI-скрипты могут быть написаны на любом языке программирования (C, C++ (язык программирования), PASCAL, FORTRAN и т.п.) или командном языке ( shell (Операционные Системы), cshell, командный язык MS-DOS, Perl и т.п.). Скрипт может быть написан даже на языке редактора EMAC в системах Unix.

Шлюз — это CGI-скрипт, который используется для обмена данными с другими информационными ресурсами Internet или приложениями-демонами. Обычная CGI-программа запускается сервером HTTP для выполнения некоторой работы, возвращает результаты серверу и завершает свое выполнение. Шлюз выполняется точно также, только, фактически, он инициирует взаимодействие в качестве клиента с третьей программой. Если эта третья программа является сервисом Internet, например, сервер Gopher, то шлюз становится клиентом Gopher, который посылает запрос по порту Gopher, а после получения ответа пересылает его серверу HTTP. [2]

Общий шлюзовый интерфейс CGI

CGI (Common Gateway Interface) — механизм доступа к программам на стороне веб-сервера. Спецификация CGI была разработана для расширения возможностей сервиса www за счет подключения различного внешнего программного обеспечения. При использовании CGI веб-сервер представляет браузеру доступ к исполнимым программам, запускаемым на его (серверной) стороне через стандартные потоки ввода и вывода.

Интерфейс CGI применяется для создания динамических веб-сайтов, например, когда веб-страницы формируются из результатов запроса к базе данных. Сейчас популярность CGI снизилась, т.к. появились более совершенные альтернативные решения (например, модульные расширения веб-серверов).

Веб-серверы

Веб-сервер — это сетевое приложение, обслуживающее HTTP-запросы от клиентов, обычно веб-браузеров. Веб-сервер принимает запросы и возвращает ответы, обычно вместе с HTML-страницей, изображением, файлом, медиа-потоком или другими данными. Веб-серверы — основа Всемирной паутины. С расширением спектра сетевых сервисов веб-серверы все чаще используются в качестве шлюзов для серверов приложений или сами представляют такие функции (например, Apache Tomcat).

Созданием программного обеспечения веб-серверов занимаются многие разработчики, но наибольшую популярность имеют такие программные продукты, как Apache (Apache Software Foundation), IIS (Microsoft), Google Web Server (GWS, Google Inc.) и nginx.

  • Apache — свободное программное обеспечение, распространяется под совместимой с GPL лицензией. Apache уже многие годы является лидером по распространенности во Всемирной паутине в силу своей надежности, гибкости, масштабируемости и безопасности.
  • IIS (Internet Information Services) — проприетарный набор серверов для нескольких служб Интернета, разработанный Майкрософт и распространяемый с серверными операционными системами семейства Windows. Основным компонентом IIS является веб-сервер, также поддерживаются протоколы FTP, POP3, SMTP, NNTP.
  • Google Web Server (GWS) — разработка компании Google на основе веб-сервера Apache. GWS оптимизирован для выполнения приложений сервиса Google Applications.
  • nginx [engine x]— это HTTP-сервер, совмещенный с кэширующим прокси-сервером. Разработан И. Сысоевым для компании Рамблер. Осенью 2004 года вышел первый публично доступный релиз, сейчас nginx используется на 9-12% веб-серверов. Браузеры
  • Браузер, веб-обозреватель (web-browser) — клиентское приложение для доступа к веб-серверам по протоколу HTTP и просмотра веб-страниц. Как правило браузеры дополнительно поддерживают и ряд других протоколов (например ftp, file, mms, pop3).

Первые HTTP-клиенты были консольными и работали в текстовом режиме, позволяя читать гипертекст и перемещаться по ссылкам. Сейчас консольные браузеры (такие, как lynx, w3m или links) практически не используются рядовыми посетителями веб-сайтов. Тем не менее такие браузеры весьма полезны для веб-разработчиков, так как позволяют «увидеть» веб-страницу «глазами» поискового робота.

Исторически первым браузером в современном понимании (т.е. с графическим интерфейсом и т.д.) была программа NCSA Mosaic, разработанная Марком Андерисеном и Эриком Бина. Mosaic имел довольно ограниченные возможности, но его открытый исходный код стал основой для многих последующих разработок. [3]

Принцип работы CGI

Обобщенный алгоритм работы через CGI можно представить в следующем виде:

  1. Элемент нумерованного списка
  2. Клиент запрашивает CGI-приложение по его URI.
  3. Веб-сервер принимает запрос и устанавливает переменные окружения, через них приложению передаются данные и служебная информация.
  4. Веб-сервер перенаправляет запросы через стандартный поток ввода (stdin) на вход вызываемой программы.
  5. CGI-приложение выполняет все необходимые операции и формирует результаты в виде HTML.
  6. Сформированный гипертекст возвращается веб-серверу через стандартный поток вывода (stdout). Сообщения об ошибках передаются через stderr.
  7. Веб-сервер передает результаты запроса клиенту.

Механизмы обмена данными

  • через переменные окружения;
  • через командную строку;
  • через стандартный ввод;
  • через стандартный вывод.

Переменные окружения

При запуске внешней программы сервер создает специфические переменные окружения, через которые передает приложению как служебную информацию, так и данные. Все переменные можно разделить на общие переменные окружения, которые генерируются при любой форме запроса, и запрос-ориентированные переменные.

Общие переменные окружения

  • SERVER_SOFTWARE — определяет имя и версию сервера.
  • SERVER_NAME — определяет доменное имя сервера.
  • GATEWAY_INTERFACE — определяет версию интерфейса.

Запрос-ориентированные окружения

  • SERVER_PROTOCOL — протокол сервера. Вообще говоря, CGI разрабатывалась не только для применения в www с протоколом HTTP, но и для других протоколов также, но широкое применение получила только в www.
  • SERVER_PORT — определяет порт TCP (Transmission Control Protocol) — протокол управления передачей), по которому осуществляется взаимодействие. По умолчанию для работы по HTTP используется 80 порт, но он может быть и переназначен при конфигурировании сервера.
  • REQUEST_METHOD — определяет метод доступа к информационному ресурсу. Это важнейшая переменная в CGI. Разные методы доступа используют различные механизмы передачи данных. Данная переменная может принимать значения GET, POST, HEAD и т. п.
  • PATH_INFO — передает программе путь, часть спецификации URL, в том виде, в котором она указана в клиенте. Реально это означает, что передается путь (адрес скрипта) в виде, указанном в HTML-документе.
  • PATH_TRANSLATED — то же самое, что и PATH_INFO, но только после подстановки сервером определенных в его конфигурации вставок.
  • SCRIPT_NAME — определяет адрес скрипта так, как он указан клиентом.
  • QUERY_STRING — переменная определяет содержание запроса к скрипту.

Идентификация пользователя и его машины

  • REMOTE_HOST — доменный адрес машины, с которой осуществляется запрос.
  • REMOTE_ADDR — IP-адрес запрашивающей машины.
  • AUTH_TYPE — тип идентификации пользователя. Используется в случае если скрипт защищен от несанкционированного использования.
  • REMOTE_USER — используется для идентификации пользователя.
  • REMOTE_IDENT — данная переменная порождается сервером, если он поддерживает идентификацию пользователя по протоколу RFC-931. Рекомендовано использование этой переменной для первоначального использования скрипта.

Переменные, определяющие тип и длину передаваемой информации от клиента к серверу

  • CONTENT_TYPE — определяет MIME-тип данных, передаваемых скрипту. Используя эту переменную можно одним скриптом обрабатывать различные форматы данных.
  • CONTENT_LENGTH — определяет размер данных в байтах, которые передаются скрипту. Данная переменная чрезвычайно важна при обмене данными по методу POST, т. к. нет другого способа определить размер данных, которые надо прочитать со стандартного ввода.

Возможна передача и других переменных окружения. В этом случае перед именем указывается префикс «HTTP_». Отдельный случай представляют переменные, порожденные в заголовке HTML-документа в тагах META. Они передаются в заголовке сообщения и некоторые серверы могут порождать переменные окружения из этих полей заголовка.

Опции командной строки

Командная строка используется только при запросах типа ISIN-DEX. При HTML FORMS или любых других запросах неопределенного типа командная строка не используется. Если сервер определил, что к скрипту обращаются через ISINDEX-документ, то поисковый критерий выделяется из URL и преобразуется в параметры командной строки. При этом знаком разделения параметров является символ «+». Тип запроса определяется по наличию или отсутствию символа «=» в запросе. Если этот символ есть, то запрос не является запросом ISINDEX, если символа нет, то запрос принадлежит к типу ISIN-DEX. Параметры, выделенные из запроса, помещаются в массив параметров командной строки argv. При этом после из выделения происходит преобразование всех шестнадцатеричных символов в их ASCII-коды. Если число параметров превышает ограничения, установленные в командном языке, например в shell, то формирования командной строки не происходит и данные передаются только через QUERY_STRING. Вообще говоря, следует заранее подумать об объеме данных, передаваемом скрипту и выбрать соответствующий метод доступа. Размер переменных окружения тоже ограничен, и если необходимо передавать много данных, то лучше сразу выбрать метод POST, т.е. передачу данных через стандартный ввод.

Формат стандартного ввода

Стандартный ввод используется при передаче данных в скрипт по методу POST. Объем передаваемых данных задается переменной окружения CONTENT_LENGTH, а тип данных — переменной CONTENT_TYPE. Если из HTML-формы надо передать запрос типа: a=b&b=c, то CONTENT_LENGTH=7, CONTENT_TYPE=application/x-www-form-urlencoded, а первым символом в стандартном вводе будет символ «а». Следует всегда помнить, что конец файла сервером в скрипт не передается, а поэтому завершать чтение следует по числу прочитанных символов. Позже мы разберем примеры скриптов и обсудим особенности их реализации в разных операционных системах.

Формат стандартного вывода

Стандартный вывод используется скриптом для возврата данных серверу. При этом вывод состоит из заголовка и собственно данных. Результат работы скрипта может передаваться клиенту без каких-либо преобразований со стороны сервера, если скрипт обеспечивает построение полного HTTP-заголовка, в противном случае сервер заголовок модифицирует в соответствии со спецификацией HTTP. Заголовок сообщения должен отделяться от тела сообщения пустой строкой. Обычно в скриптах указывают только три поля HTTP-заголовка: Content-type , Location , Status .

Content-type

Указывается в том случае, когда скрипт сам генерирует документ «на лету» и возвращает его клиенту. В этом случае реального документа в файловой системе сервера не остается. При использовании такого сорта скриптов следует учитывать, что не все серверы и клиенты отрабатывают так, как представляется разработчику скрипта. Так, при указании Content-type: text/html, некоторые клиенты не реализуют сканирования полученного текста на предмет наличия в нем встроенной графики. Обычно в Content-type указывают текстовые типы text/plain и text/html.

Location

Используется для переадресации. Иногда переадресация помогает преодолеть ограничения сервера или клиента на обработку встроенной графики или серверной предобработки. В этом случае скрипт создает файл на диске и указывает его адрес в Location. Сервер, таким образом, передает реально существующий файл. В последнее время серверы стали буферизовать возвращаемые клиентам данные, что приводит к решению вопросов, связанных с повторным запуском скриптов для встраивания графики и разгрузки компьютера с сервером HTTP. [4]

Области применения CGI

Наиболее частая задача, для решения которой применяется CGI — создание интерактивных страниц, содержание которых зависит от действий пользователя. Типичными примерами таких веб-страниц являются форма регистрации на сайте или форма для отправки комментария. Другая область применения CGI, остающаяся за кулисами взаимодействия с пользователем, связана со сбором и обработкой информации о клиенте: установка и чтение «cookies»; получение данных о браузере и операционной системе; подсчет количества посещений веб-страницы; мониторинг веб-трафика и т. п.

Эти возможности обеспечиваются тем, что CGI-скрипт может быть подключен к базе данных или обращаться к файловой системе сервера. Таким образом CGI-скрипт может сохранять информацию в таблицах БД или файлах и получать ее оттуда по запросу, чего нельзя сделать средствами HTML.

Важно знать, что CGI — это не язык программирования! Это простой протокол, позволяющий веб-серверу передавать данные через stdin и читать их из stdout. Поэтому, в качестве CGI-обработчика может использоваться любая серверная программа, способная работать со стандартными потоками ввода-вывода.

Преимущества CGI

Многие возможности CGI сейчас дублируются такими технологиями, как например DHTML, ActiveX или Java-апплетами. Основными преимуществами использования серверных скриптов является то, что вы можете быть уверены, что все клиенты (за редким исключением, как правило связанным с блокировкой доступа к определенным ресурсам на уровне файрвола) смогут работать с серверным приложением. Клиентские-же программы могут быть просто отключены в браузере, или вовсе не поддерживаться.

Недостатки CGI

Самым большим недостатком этой технологии являются повышенные требования к производительности веб-сервера. Дело в том, что каждое обращение к CGI-приложению вызывает порождение нового процесса, со всеми вытекающими отсюда накладными расходами. Если же приложение написано с ошибками, то возможна ситуация, когда оно, например, зациклится. Браузер прервет соединение по истечении тайм-аута, но на серверной стороне процесс будет продолжаться, пока администратор не снимет его принудительно. В этом отношении клиентские скрипты имеют существенное преимущество, т. к. они выполняются локально.

Другим недостатком CGI является меньшая, по сравнению с другими решениями, защищенность веб-сервера. Неправильная настройка прав доступа к серверным ресурсам из CGI-приложения может поставить под угрозу не только работоспособность веб-сервера, но и информационную безопасность. Впрочем, любую сетевую технологию можно считать потенциально небезопасной уже по определению. [5]

Примечания

  1. CGI (Common Gateway Interface) [Электронный ресурс]: — Режим доступа: http://citforum.ru/internet/cgi_tut/cgi.shtml
  2. CGI (Common Gateway Interface) [Электронный ресурс]: — Режим доступа: http://citforum.ru/nets/services/services0309.shtml
  3. CGI (Common Gateway Interface) [Электронный ресурс]: — Режим доступа: http://lectureswww.readthedocs.io/1.introduction/history.html
  4. CGI (Common Gateway Interface) [Электронный ресурс]: — Режим доступа: http://citforum.ru/nets/services/services0309.shtml
  5. CGI (Common Gateway Interface) [Электронный ресурс]: — Режим доступа: http://www.4stud.info/web-programming/cgi.html

Материал из Intuit

Перейти к: навигация, поиск

Разработка Web-приложений

Аннотация: Одна из главных сфер применения языка Python — web-приложения — представляется в этой лекции на конкретных примерах. Кроме того, делается акцент на типичных слабых местах безопасности web-приложений.

Содержание

  • 1 НЕТ ДАННЫХ
  • 2 CGI-сценарии
    • 2.1 Модуль cgi
    • 2.2 Что после CGI?
  • 3 Среды разработки
    • 3.1 Zope и его объектная модель
    • 3.2 Заключение

НЕТ ДАННЫХ

Под web-приложением будет пониматься программа, основной интерфейс пользователя которой работает в стандартном WWW-браузере под управлением HTML и XML-документов. Для улучшение качества интерфейса пользователя часто применяют JavaScript, однако это несколько снижает универсальность интерфейса. Следует заметить, что интерфейс можно построить на Java- или Flash-апплетах, однако, такие приложения сложно назвать web-приложениями, так как Java или Flash могут использовать собственные протоколы для общения с сервером, а не стандартный для WWW протокол HTTP.

При создании web-приложений стараются отделить Форму (внешний вид, стиль), Содержание и Логику обработки данных. Современные технологии построения web-сайтов дают возможность подойти достаточно близко к этому идеалу. Тем не менее, даже без применения многоуровневых приложений можно придерживаться стиля, позволяющего изменять любой из этих аспектов, не затрагивая (или почти не затрагивая) двух других. Рассуждения на эту тему будут продолжены в разделе, посвященном средам разработки.

CGI-сценарии

Классический путь создания приложений для WWW — написание CGI-сценариев (иногда говорят — скриптов). CGI (Common Gateway Interface, общий шлюзовой интерфейс) — это стандарт, регламентирующий взаимодействие сервера с внешними приложениями. В случае с WWW, web-сервер может направить запрос на генерацию страницы по определенному сценарию. Этот сценарий, получив на вход данные от web-сервера (тот, в свою очередь, мог получить их от пользователя), генерирует готовый объект (изображение, аудиоданные, таблицу стилей и т.п.).

При вызове сценария Web-сервер передает ему информацию через стандартный ввод, переменные окружения и, для ISINDEX, через аргументы командной строки (они доступны через sys.argv).

Два основных метода передачи данных из заполненной в браузере формы Web-серверу (и CGI-сценарию) — GET и POST. В зависимости от метода данные передаются по-разному. В первом случае они кодируются и помещаются прямо в URL, например: http://host/cgi-bin/a.cgi?a=1&b=3. Сценарий получает их в переменной окружения с именем QUERY_STRING. В случае метода POST они передаются на стандартный ввод.

Для корректной работы сценарии помещаются в предназначенный для этого каталог на web-сервере (обычно он называется cgi-bin) или, если это разрешено конфигурацией сервера, в любом месте среди документов HTML. Сценарий должен иметь признак исполняемости. В системе Unix его можно установить с помощью команды chmod a+x.

Следующий простейший сценарий выводит значения из словаря os.environ и позволяет увидеть, что же было ему передано:

Пример  
 
 #!/usr/bin/python
 
 import os
 print """Content-Type: text/plain
 
 %s""" % os.environ
 

С помощью него можно увидеть установленные Web-сервером переменные окружения. Выдаваемый CGI-сценарием web-серверу файл содержит заголовочную часть, в которой указаны поля с мета-информацией (тип содержимого, время последнего обновления документа, кодировка и т.п.).

Основные переменные окружения, достаточные для создания сценариев:

Пример  
 
 QUERY_STRING
 

Строка запроса.

Пример  
 
 REMOTE_ADDR
 

IP-адрес клиента.

Пример  
 
 REMOTE_USER
 

Имя клиента (если он был идентифицирован).

Пример  
 
 SCRIPT_NAME
 

Имя сценария.

Пример  
 
 SCRIPT_FILENAME
 

Имя файла со сценарием.

Пример  
 
 SERVER_NAME
 

Имя сервера.

Пример  
 
 HTTP_USER_AGENT
 

Название броузера клиента.

Пример  
 
 REQUEST_URI
 

Строка запроса (URI).

Пример  
 
 HTTP_ACCEPT_LANGUAGE
 

Желательный язык документа.

Вот что может содержать словарь os.environ в CGI-сценарии:

Пример  
 
 {
 'DOCUMENT_ROOT': '/var/www/html', 
 'SERVER_ADDR': '127.0.0.1', 
 'SERVER_PORT': '80', 
 'GATEWAY_INTERFACE': 'CGI/1.1', 
 'HTTP_ACCEPT_LANGUAGE': 'en-us, en;q=0.50', 
 'REMOTE_ADDR': '127.0.0.1', 
 'SERVER_NAME': 'rnd.onego.ru',
 'HTTP_CONNECTION': 'close', 
 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i586; en-US; 
 rv:1.0.1) Gecko/20021003', 
 'HTTP_ACCEPT_CHARSET': 'ISO-8859-1, utf-8;q=0.66, *;q=0.66', 
 'HTTP_ACCEPT': 'text/xml,application/xml,application/xhtml+xml,
 text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,
 image/gif;q=0.2,text/css,*/*;q=0.1',
 'REQUEST_URI': '/cgi-bin/test.py?a=1', 
 'PATH': '/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin',
 'QUERY_STRING': 'a=1&b=2', 
 'SCRIPT_FILENAME': '/var/www/cgi-bin/test.py', 
 'HTTP_KEEP_ALIVE': '300', 
 'HTTP_HOST': 'localhost', 
 'REQUEST_METHOD': 'GET', 
 'SERVER_SIGNATURE': 'Apache/1.3.23 Server at rnd.onego.ru Port 80', 
 'SCRIPT_NAME': '/cgi-bin/test.py', 
 'SERVER_ADMIN': 'root@localhost', 
 'SERVER_SOFTWARE': 'Apache/1.3.23 (Unix)  (Red-Hat/Linux) 
 mod_python/2.7.8 Python/1.5.2 PHP/4.1.2',
 'SERVER_PROTOCOL': 'HTTP/1.0', 
 'REMOTE_PORT': '39251'
 }
 

Следующий CGI-сценарий выдает черный квадрат (в нем используется модуль Image для обработки изображений):

Пример  
 
 #!/usr/bin/python
 
 import sys
 print """Content-Type: image/jpeg
 """
 
 import Image
 i = Image.new("RGB", (10,10))
 i.im.draw_rectangle((0,0,10,10), 1)
 i.save(sys.stdout, "jpeg")
 

Модуль cgi

В Python имеется поддержка CGI в виде модуля cgi. Следующий пример показывает некоторые из его возможностей:

Пример  
 
 #!/usr/bin/python
 # -*- coding: cp1251 -*-
 import cgi, os
 
 # анализ запроса
 f = cgi.FieldStorage()
 if f.has_key("a"):
   a = f["a"].value
 else:
   a = "0"
 
 # обработка запроса
 b = str(int(a)+1)
 mytext = open(os.environ["SCRIPT_FILENAME"]).read()
 mytext_html = cgi.escape(mytext)
 
 # формирование ответа
 print """Content-Type: text/html
 
 <html><head><title>Решение примера: %(b)s = %(a)s + 1</title></head>
 <body>
 %(b)s
 <table width="80%%"><tr><td>
 <form action="me.cgi" method="GET">
 <input type="text" name="a" value="0" size="6">
 <input type="submit" name="b" value="Обработать">
 </form></td></tr></table>
 <pre>
 %(mytext_html)s
 </pre>
 </body></html>""" % vars()
 

В этом примере к заданному в форме числу прибавляется 1. Кроме того, выводится исходный код самого сценария. Следует заметить, что для экранирования символов >, <, & использована функция cgi.escape(). Для формирования Web-страницы применена операция форматирования. В качестве словаря для выполнения подстановок использован словарь vars() со всеми локальными переменными. Знаки процента пришлось удвоить, чтобы они не интерпретировались командой форматирования. Стоит обратить внимание на то, как получено значение от пользователя. Объект FieldStorage «почти» словарь, с тем исключением, что для получения обычного значения нужно дополнительно посмотреть атрибут value. Дело в том, что в сценарий могут передаваться не только текстовые значения, но и файлы, а также множественные значения с одним и тем же именем.

Осторожно!

При обработке входных значений CGI-сценариев нужно внимательно и скрупулезно проверять допустимые значения. Лучше считать, что клиент может передать на вход все, что угодно. Из этого всего необходимо выбрать и проверить только то, что ожидает сценарий.

Например, не следует подставлять полученные от пользователя данные в путь к файлу, в качестве аргументов к функции eval() и ей подобных; параметров командной строки; частей в SQL-запросах к базе данных. Также не стоит вставлять полученные данные напрямую в формируемые страницы, если эти страницы будет видеть не только клиент, заказавший URL (например, такая ситуация обычна в web-чатах, форумах, гостевых книгах), и даже в том случае, если единственный читатель этой информации — администратор сайта. Тот, кто смотрит страницы с непроверенным HTML-кодом, поступившим напрямую от пользователя, рискуют обработать в своем браузере зловредный код, использующий брешь в его защите.

Даже если CGI-сценарий используется исключительно другими сценариями через запрос на URL, нужно проверять входные значения столь же тщательно, как если бы данные вводил пользователь. (Так как недоброжелатель может подать на web-сервер любые значения).

В примере выше проверка на допустимость произведена при вызове функции int(): если было бы задано нечисловое значение, сценарий аварийно завершился, а пользователь увидел Internal Server Error.

После анализа входных данных можно выделить фазу их обработки. В этой части CGI-сценария вычисляются переменные для дальнейшего вывода. Здесь необходимо учитывать не только значения переданных переменных, но и факт их присутствия или отсутствия, так как это тоже может влиять на логику сценария.

И, наконец, фаза вывода готового объекта (текста, HTML-документа, изображения, мультимедиа-объекта и т.п.). Проще всего заранее подготовить шаблон страницы (или ее крупных частей), а потом просто заполнить содержимым из переменных.

В приведенных примерах имена появлялись в строке запроса только один раз. Некоторые формы порождают несколько значений для одного имени. Получить все значения можно с помощью метода getlist():

Пример  
 
 lst = form.getlist("fld")
 

Список lst будет содержать столько значений, сколько полей с именем fld получено из web-формы (он может быть и пустым, если ни одно поле с заданным именем не было заполнено).

В некоторых случаях необходимо передать на сервер файлы (сделать upload). Следующий пример и комментарий к нему помогут разобраться с этой задачей:

Пример  
 
 #!/usr/bin/env python
 import cgi
 
 form = cgi.FieldStorage()
 file_contents = ""
 if form.has_key("filename"):
   fileitem = form["filename"]
   if fileitem.file:  
     file_contents = """<P>Содержимое переданного файла:
     <PRE>%s</PRE>""" % fileitem.file.read()
 
 print """Content-Type: text/html
 
 <HTML><HEAD><TITLE>Загрузка файла</TITLE></HEAD>
 <BODY><H1>Загрузка файла</H1>
 <P><FORM ENCTYPE="multipart/form-data" 
 ACTION="getfile.cgi" METHOD="POST">
 <br>Файл: <INPUT TYPE="file" NAME="filename">
 <br><INPUT TYPE="submit" NAME="button" VALUE="Передать файл">
 </FORM>
 %s
 </BODY></HTML>""" % file_contents
 

В начале следует рассмотреть web-форму, которая приведена в конце сценария: именно она будет выводиться пользователю при обращении по CGI-сценарию. Форма имеет поле типа file, которое в web-броузере представляется полоской ввода и кнопкой «Browse». Нажимая на кнопку «Browse», пользователь выбирает файл, доступный в ОС на его компьютере. После этого он может нажать кнопку «Передать файл» для передачи файла на сервер.

Для отладки CGI-сценария можно использовать модуль cgitb. При возникновении ошибки этот модуль выдаст красочную HTML-страницу с указанием места возбуждения исключения. В начале отлаживаемого сценария нужно поставить

Пример  
 
 import cgitb
 cgitb.enable(1)
 

Или, если не нужно показывать ошибки в браузере:

Пример  
 
   import cgitb
   cgitb.enable(0, logdir="/tmp")
 

Только необходимо помнить, что следует убрать эти строки, когда сценарий будет отлажен, так как он выдает кусочки кода сценария. Это может быть использовано злоумышленниками, с тем чтобы найти уязвимости в CGI-сценарии или подсмотреть пароли (если таковые присутствуют в сценарии).


Что после CGI?

К сожалению, строительство интерактивного и посещаемого сайта на основе CGI имеет свои ограничения, главным образом, связанные с производительностью. Ведь для каждого запроса нужно вызвать как минимум один сценарий (а значит — запустить интерпретатор Python), из него, возможно, сделать соединение с базой данных и т.д. Время запуска интерпретатора Python достаточно невелико, тем не менее, на занятом сервере оно может оказывать сильное влияние на загрузку процессора.

Желательно, чтобы интерпретатор уже находился в оперативной памяти, и были доступны соединения с базой данных.

Такие технологии существуют и обычно опираются на модули, встраиваемые в web-сервер.

Для ускорения работы CGI используются различные схемы, например, FastCGI или PCGI (Persistent CGI). В данной лекции предлагается к рассмотрению специальным модуль для web-сервера Apache, называемый mod_python.

Пусть модуль установлен на web-сервере в соответствии с инструкциями, данными в его документации.

Модуль mod_python позволяет сценарию-обработчику вклиниваться в процесс обработки HTTP-запроса сервером Apache на любом этапе, для чего сценарий должен иметь определенным образом названные функции.

Сначала нужно выделить каталог, в котором будет работать сценарий-обработчик. Пусть это каталог /var/www/html/mywebdir. Для того чтобы web-сервер знал, что в этом каталоге необходимо применять mod_python, следует добавить в файл конфигурации Apache следующие строки:

Пример  
 
 <Directory "/var/www/html/mywebdir">
   AddHandler python-program .py
   PythonHandler mprocess
 </Directory>
 

После этого необходимо перезапустить web-сервер и, если все прошло без ошибок, можно приступать к написанию обработчика mprocess.py. Этот сценарий будет реагировать на любой запрос вида http://localhost/*.py.

Следующий сценарий mprocess.py выведет в браузере страницу со словами Hello, world!:

Пример  
 
 from mod_python import apache
 
 def handler(req):
   req.content_type = "text/html"
   req.send_http_header()
   req.write("""<HTML><HEAD><TITLE>Hello, world!</TITLE></HEAD>
   <BODY>Hello, world!</BODY></HTML>""")
   return apache.OK
 

Отличия сценария-обработчика от CGI-сценария:

  • Сценарий-обработчик не запускается при каждом HTTP-запросе: он уже находится в памяти, и из него вызываются необходимые функции-обработчики (в приведенном примере такая функция всего одна — handler()). Каждый процесс-потомок web-сервера может иметь свою копию сценария и интерпретатора Python.
  • Как следствие п.1 различные HTTP-запросы делят одни и те же глобальные переменные. Например, таким образом можно инициализировать соединение с базой данных и применять его во всех запросах (хотя в некоторых случаях потребуются блокировки, исключающие одновременное использование соединения разными потоками (нитями) управления).
  • Обработчик задействуется при обращении к любому «файлу» с расширением py, тогда как CGI-сценарий обычно запускается при обращении по конкретному имени.
  • В сценарии-обработчике нельзя рассчитывать на то, что он увидит модули, расположенные в том же каталоге. Возможно, придется добавить некоторые каталоги в sys.path.
  • Текущий рабочий каталог (его можно узнать с помощью функции os.getcwd()) также не находится в одном каталоге с обработчиком.
  • #!-строка в первой строке сценария не определяет версию интерпретатора Python. Работает версия, для которой был скомпилирован mod_python.
  • Все необходимые параметры передаются в обработчик в виде Request-объекта. Возвращаемые значения также передаются через этот объект.
  • Web-сервер замечает, что сценарий-обработчик изменился, но не заметит изменений в импортируемых в него модулях. Команда touchmprocess.py обновит дату изменения файла сценария.
  • Отображение os.environ в обработчике может быть обрезанным. Кроме того, вызываемые из сценария-обработчика другие программы его не наследуют, как это происходит при работе с CGI-сценариями. Переменные можно получить другим путем: req.add_common_vars(); params = req.subprocess_env.
  • Так как сценарий-обработчик не является «одноразовым», как CGI-сценарий, из-за ошибок программирования (как самого сценария, так и других компонентов) могут возникать утечки памяти (программа не освобождает ставшую ненужной память). Следует установить значение параметра MaxRequestsPerChild (максимальное число запросов, обрабатываемое одним процессом-потомком) больше нуля.

Другой возможный обработчик — сценарий идентификации:

Пример  
 
 def authenhandler(req):
   password = req.get_basic_auth_pw()
   user = req.connection.user
   if user == "user1" and password == "secret":
       return apache.OK
   else:
       return apache.HTTP_UNAUTHORIZED
 

Эту функцию следует добавить в модуль mprocess.py, который был рассмотрен ранее. Кроме того, нужно дополнить конфигурацию, назначив обработчик для запросов идентификации (PythonAuthenHandler), а также обычные для Apache директивы AuthType, AuthName, require, определяющие способ авторизации:

Пример  
 
 <Directory "/var/www/html/mywebdir">
   AddHandler python-program .py
   PythonHandler mprocess
   PythonAuthenHandler mprocess
   AuthType Basic
   AuthName "My page"
   require valid-user
 </Directory>
 

Разумеется, это — всего лишь пример. В реальности идентификация может быть устроена намного сложнее.

Другие возможные обработчики (по документации к mod_python можно уточнить, в какие моменты обработки запроса они вызываются):

Пример  
 
 PythonPostReadRequestHandler
 

Обработка полученного запроса сразу после его получения.

Пример  
 
 PythonTransHandler
 

Позволяет изменить URI запроса (в том числе имя виртуального сервера).

Пример  
 
 PythonHeaderParserHandler
 

Обработка полей запроса.

Пример  
 
 PythonAccessHandler
 

Обработка ограничений доступа (например, по IP-адресу).

Пример  
 
 PythonAuthenHandler
 

Идентификация пользователя.

Пример  
 
 PythonTypeHandler
 

Определение и/или настройка типа документа, языка и т.д.

Пример  
 
 PythonFixupHandler
 

Изменение полей непосредственно перед вызовом обработчиков содержимого.

Пример  
 
 PythonHandler
 

Основной обработчик запроса.

Пример  
 
 PythonInitHandler
 

PythonPostReadRequestHandler или PythonHeaderParserHandler в зависимости от нахождения в конфигурации web-сервера.

Пример  
 
 PythonLogHandler
 

Управление записью в логи.

Пример  
 
 PythonCleanupHandler
 

Обработчик, вызываемый непосредственно перед уничтожением Request-объекта.

Некоторые из этих обработчиков работают только глобально, так как при вызове даже каталог их приложения может быть неизвестен (таков, например, PythonPostReadRequestHandler).

С помощью mod_python можно строить web-сайты с динамическим содержимым и контролировать некоторые аспекты работы web-сервера Apache через Python-сценарии.


Среды разработки

Для создания Web-приложений применяются и более сложные средства, чем web-сервер с расположенными на нем статическими документами и CGI-сценариями. В зависимости от назначения такие программные системы называются серверами web-приложений, системами управления содержимым (CMS, Content Management System), системы web-публикации и средствами для создания WWW-порталов. Причем CMS-система может быть выполнена как web-приложение, а средства для создания порталов могут базироваться на системах web-публикации, для которых CMS-система является подсистемой. Поэтому, выбирая систему для конкретных нужд, стоит уточнить, какие функции она должна выполнять.

Язык Python, хотя и уступает PHP по количеству созданных на нем web-систем, имеет несколько достаточно популярных приложений. Самым ярким примером средства для создания сервера web-приложений является Zope (произносится «зоп») (см. [1]) (Z Object Publishing Environment, среда публикации объектов). Zope имеет встроенный web-сервер, но может работать и с другими Web-серверами, например, Apache. На основе Zope можно строить web-порталы, например, с помощью Plone/Zope, но можно разрабатывать и собственные web-приложения. При этом Zope позволяет разделить Форму, Содержание и Логику до такой степени, что Содержанием могут заниматься одни люди (менеджеры по содержимому), Формой — другие (web-дизайнеры), а Логикой — третьи (программисты). В случае с Zope Логику можно задать с помощью языка Python (или, как вариант, Perl), Форма может быть создана в графических или специализированных web-редакторах, а работа с содержимым организована через Web-формы самого Zope.

Zope и его объектная модель

В рамках этой лекции невозможно детально рассмотреть такой инструмент как Zope, поэтому стоит лишь заметить, что он достаточно интересен не только в качестве среды разработки web-приложений, но и с точки зрения подходов. Например, уникальная объектно-ориентированная модель Zope позволяет довольно гибко описывать требуемое приложение.

Zope включает в себя следующие возможности:

  • Web-сервер. Zope может работать с Web-серверами через CGI или использовать свой встроенный Web-сервер (ZServer).
  • Среда разработчика выполнена как Web-приложение. Zope позволяет создавать Web-приложения через Web-интерфейс.
  • Поддержка сценариев. Zope поддерживает несколько языков сценариев: Python, Perl и собственный DTML (Document Template Markup Language, язык разметки шаблона документа).
  • База данных объектов. Zope использует в своей работе устойчивые объекты, хранимые в специальной базе данных (ZODB). Имеется достаточно простой интерфейс для управления этой базой данных.
  • Интеграция с реляционными базами данных. Zope может хранить свои объекты и другие данные в реляционных СУБД: Oracle, PostgreSQL, MySQL, Sybase и т.п.

В ряду других подобных систем Zope на первый взгляд кажется странным и неприступным, однако тем, кто с ним «на ты», он открывает большие возможности.

Разработчики Zope исходили из лежащей в основе WWW объектной модели, в которой загрузку документа по URI можно сравнить с отправкой сообщения объекту. Объекты Zope разложены по папкам (folders), к которым привязаны политики доступа для пользователей, имеющих определенные роли. В качестве объектов могут выступать документы, изображения, мультимедиа-файлы, адаптеры к базам данных и т.п.

Документы Zope можно писать на языке DTML — дополнении HTML с синтаксисом для включения значений подобно SSI (Server-Side Include). Например, для вставки переменной с названием документа можно использовать

Пример  
 
 <!- #var document_title ->
 

Следует заметить, что объекты Zope могут иметь свои атрибуты, а также методы, в частности, написанные на языке Python. Переменные же могут появляться как из заданных пользователем значений, так и из других источников данных (например, из базы данных посредством выполнения выборки функцией SELECT).

Сейчас для описания документа Zope все чаще применяется ZPT (Zope Page Templates, шаблоны страниц Zope), которые в свою очередь используют TAL (Template Attribute Language, язык шаблонных атрибутов). Он позволяет заменять, повторять или пропускать элементы документа описываемого шаблоном документа. «Операторами» языка TAL являются XML-атрибуты из пространства имен TAL. Пространство имен сегодня описывается следующим идентификатором:

Пример  
 
 xmlns:tal="http://xml.zope.org/namespaces/tal&quot;
 

Оператор TAL имеет имя и значение (что выражается именем и значением атрибута). Внутри значения обычно записано TAL-выражение, синтаксис которого описывается другим языком — TALES (Template Attribute Language Expression Syntax, синтаксис выражений TAL).

Таким образом, ZPT наполняет содержимым шаблоны, интерпретируя атрибуты TAL. Например, чтобы Zope подставил название документа (тег TITLE), шаблон может иметь следующий код:

Пример  
 
 <title tal:content="here/title">Doc Title</title>
 

Стоит заметить, что приведенный код сойдет за код на HTML, то есть, Web-дизайнер может на любом этапе работы над проектом редактировать шаблон в HTML-редакторе (при условии, что тот сохраняет незнакомые атрибуты из пространства имен tal). В этом примере here/titleявляется выражением TALES. Текст Doc Title служит ориентиром для web-дизайнера и заменяется значением выражения here/title, то есть, будет взято свойство title документа Zope.

Примечание:

В Zope объекты имеют свойства. Набор свойств зависит от типа объекта, но может быть расширен в индивидуальном порядке. Свойство id присутствует всегда, свойство title обычно тоже указывается.

В качестве более сложного примера можно рассмотреть организацию повтора внутри шаблона (для опробования этого примера в Zope нужно добавить объект Page Template):

Пример  
 
 <ul>
    <li tal:define="s modules/string" 
        tal:repeat="el python:s.digits"> 
    <a href="DUMMY"
       tal:attributes="href string:/digit/$el"
       tal:content="el">SELECTION</a>
   </li> 
 </ul>
 

Этот шаблон породит следующий результат:

Пример  
 
 <ul>
    <li><a href="/digit/0">0</a></li>
    <li><a href="/digit/1">1</a></li>
    <li><a href="/digit/2">2</a></li>
    <li><a href="/digit/3">3</a></li>
    <li><a href="/digit/4">4</a></li>
    <li><a href="/digit/5">5</a></li>
    <li><a href="/digit/6">6</a></li>
    <li><a href="/digit/7">7</a></li>
    <li><a href="/digit/8">8</a></li>
    <li><a href="/digit/9">9</a></li>
 </ul>
 

Здесь нужно обратить внимание на два основных момента:

  • в шаблоне можно использовать выражения Python (в данном примере переменная s определена как модуль Python) и переменную-счетчик цикла el, которая проходит итерации по строке string.digits.
  • с помощью TAL можно задавать не только содержимое элемента, но и атрибута тега (в данном примере использовался атрибут href).

Детали можно узнать по документации. Стоит лишь заметить, что итерация может происходить по самым разным источникам данных: содержимому текущей папки, выборке из базы данных или, как в приведенном примере, по объекту Python.

Любой программист знает, что программирование тем эффективнее, чем лучше удалось «расставить скобки», выведя «общий множитель за скобки». Другими словами, хорошие программисты должны быть достаточно «ленивы», чтобы найти оптимальную декомпозицию решаемой задачи. При проектировании динамического web-сайта Zope позволяет разместить «множители» и «скобки» так, чтобы достигнуть максимального повторного использования кода (как разметки, так и сценариев). Помогает этому уникальный подход к построению взаимоотношений между объектами: заимствование (acquisition).

Пусть некоторый объект (документ, изображение, сценарий, подключение к базе данных и т.п.) расположен в папке Example. Теперь объекты этой папки доступны по имени из любых нижележащих папок. Даже политики безопасности заимствуются более глубоко вложенными папками от папок, которые ближе к корню. Заимствование является очень важной концепцией Zope, без понимания которой Zope сложно грамотно применять, и наоборот, ее понимание позволяет экономить силы и время, повторно используя объекты в разработке.

Самое интересное, что заимствовать объекты можно также из параллельных папок. Пусть, например, рядом с папкой Example находится папка Zigzag, в которой лежит нужный объект (его наименование note). При этом в папке Example программиста интересует объект index_html, внутри которого вызывается note. Обычный путь к объекту index_html будет происходить по URI вроде http://zopeserver/Example/. А вот если нужно использовать note из Zigzag (и в папке Example его нет), то URI будет: http://zopeserver/Zigzag/Example/. Таким образом, указание пути в Zope отличается от традиционного пути, скажем, в Unix: в пути могут присутствовать «зигзаги» через параллельные папки, дающие возможность заимствовать объекты из этих папок. Таким образом, можно сделать конкретную страницу, комбинируя один или несколько независимых аспектов.

Заключение

В этой лекции были рассмотрены различные подходы к использованию Python в web-приложениях. Самый простой способ реализации web-приложения — использование CGI-сценариев. Более сложным является использование специальных модулей для web-сервера, таких как mod_python. Наконец, существуют технологии вроде Zope, которые предоставляют специализированные сервисы, позволяющие создавать web-приложения.

Понравилась статья? Поделить с друзьями:
  • Castle flipper праздник удался
  • Carol singing праздник перевод
  • Carnival праздник дата
  • Canterville ghost сценарий
  • Calgary stampede праздник