Closed codeyoma closed 1 year ago
SERVER_SOFTWARE: name/version of HTTP server.
SERVER_NAME: host name of the server, may be dot-decimal IP address.
GATEWAY_INTERFACE: CGI/version.
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.
CONTENTLENGTH: similarly, size of input data (decimal, in [octets](https://www.wikiwand.com/en/Octet(computing))) 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 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/plain\n\n";
foreach ( sort keys %ENV ) {
print "$_=\"$ENV{$_}\"\n";
}
Here is a simple CGI program written in Python 3 along with the HTML that handles a simple addition problem.
<!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>
#!/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.
#!/usr/bin/perl
use CGI;
# Create a new CGI object
my $cgi = CGI->new;
# Get the values of the two numbers to add from the query string
# if query string case
# print $ENV{QUERY_STRING};
# else if post put case
my $num1 = $cgi->param('num1');
my $num2 = $cgi->param('num2');
# print "num1 : $num1 \n";
# print "num2 : $num2 \n";
# Convert the numbers to integers
if ($num1 eq "" || $num2 eq "") {
if (exists $ENV{QUERY_STRING}) {
$query = $ENV{'QUERY_STRING'};
@list = split( /\&/, $query);
foreach (@list) {
($var, $val) = split(/=/);
$val =~ s/\'//g;
$val =~ s/\+/ /g;
$val =~ s/%(\w\w)/sprintf("%c", hex($1))/ge;
if ($var eq "num1") {
if ($val ne ""){
$num1 = int($val);
}
} elsif ($var eq "num2") {
if ($val ne ""){
$num2 = int($val);
}
}
}
if ($num1 eq "" || $num2 eq "") {
print $cgi->header,
$cgi->start_html("Addition Result"),
$cgi->center($cgi->h1("Addition Result"), $cgi->p("num1 or num2 does not exist.")),
$cgi->end_html;
exit;
}else {
my $sum = $num1 + $num2;
print $cgi->header,
$cgi->start_html("Addition Result"),
$cgi->center($cgi->h1("Addition Result"), $cgi->p("The sum of $num1 and $num2 is $sum.")),
$cgi->end_html;
exit;
}
}else{
print $cgi->header,
$cgi->start_html("Addition Result"),
$cgi->center($cgi->h1("Addition Result"), $cgi->p("num1 and num2 does not exist.")),
$cgi->end_html;
exit;
}
}else{
$num1 = int($num1);
$num2 = int($num2);
# Add the numbers
my $sum = $num1 + $num2;
# Print the HTML response
print $cgi->header,
$cgi->start_html("Addition Result"),
$cgi->center($cgi->h1("Addition Result"), $cgi->p("The sum of $num1 and $num2 is $sum.")),
$cgi->end_html;
}
SERVER_SOFTWARE
argv[0]/version 1.0
SERVER_NAME
127.0.0.1
GATEWAY_INTERFACE
CGI/1.1
SERVER_PROTOCOL
HTTP/1.1
SERVER_PORT
PORT_NUMBER which request arrived
REQUEST_METHOD
METHOD(upper case) which request arrived
PATH_INFO
URI which request arrived? or substitution path
PATH_TRANSLATED
PWD/PATH_INFO
SCRIPT_NAME
CGI_PASS ( like /cgi-bin/script.cgi )
QUERY_STRING
(ex: var1=value1&var2=with%20percent%20encoding )
REMOTE_HOST
host ( host name of the client, unset if server did not perform such lookup. )
REMOTE_ADDR
IP address of the client (dot-decimal) (ex: "127.0.0.1" )
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.
AUTH_TYPE
identification type, if applicable. 'auth-scheme' token in the request Authorization header field. 서블릿을 보호하는 데 사용되는 인증 스키마의 이름입니다. 예를 들면 BASIC, SSL 또는 서블릿이 보호되지 않는 경우 null입니다.
REMOTE_USER
used for certain AUTH_TYPEs.
REMOTE_IDENT
see ident, only if server performed such lookup.
#!/usr/bin/python
import cgi, os
import cgitb; cgitb.enable()
# import cgitb; cgitb.enable(display=0, logdir="./log")
save_path = os.getenv("SAVED_PATH")
if save_path is None:
save_path = "./tmp/"
else:
save_path += "/"
if not os.path.exists(save_path):
os.mkdir(save_path)
print("Content-Type: text/html")
# Parse the form data
form = cgi.FieldStorage()
# Extract the uploaded files
files = {}
for field in form.keys():
# Check if the field is a file field
if isinstance(form[field], cgi.FieldStorage) and form[field].filename:
# Save the file to the specified location
with open(save_path + form[field].filename, 'wb') as f:
f.write(form[field].file.read())
files[field] = form[field].filename
if len(files) > 0:
message = "file uploaded success"
else:
message = "file uploaded failed"
# Print the uploaded files
response = "<html><body><center>"
response += "<h1>{}<h1>".format(message)
for field, filename in files.items():
response += "<p>{}: {}</p>\n".format(field, filename)
response += "</center></body></html>"
print("Content-Length: {}".format(len(response)))
print()
print(response)
내용
http://www.csce.uark.edu/~sgauch/cgicode/ https://www.tutorialspoint.com/python/python_cgi_programming.htm https://docs.python.org/3/library/cgi.html https://www.ibm.com/docs/en/netcoolomnibus/8.1?topic=scripts-environment-variables-in-cgi-script
태스크
[x]
any file with .bla as extension must answer to POST request by calling the cgi_test executable
| .이후 확장자 까지 config에 등록된 cgi찾고, 있으면 uri에서 확장자 이후 남은 /remain_uri 를 PATH_INFO로 파싱, 없으면 config에 등록된 saved_path를 PATH_INFO로 패스[x] CGI 테스트 ( NGINX는 CGI의 정합성을 체크하느냐? 헤더를 붙여서 넘기느냐?) -> 확인 힘듬 -> 도커로 확인해보기
[x] php cgi file -> cluster php 안깔림... brew 로도
[x] python cgi file
[x] perl cgi file
[x] dup, fork
[x] segment parsing( skip ) -> #이후 fragment로 취급 스킵
[x] query parsing -> 키 밸류로 저장 (case sensitive -> 다 대문자로) -> 선형 string으로 저장.
[x] CGI 환경 설정
[x] CGI return type check (4 rule) -> document만 적용
[x] CGI 리턴 밸류 검증
[x] CGI chunked로 pass, return 경우 Later