Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
e7d6b0a2
Kaydet (Commit)
e7d6b0a2
authored
Eyl 19, 2000
tarafından
Guido van Rossum
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
An honest attempt to make this work on Unix, Windows, and even
Macintosh (the latter untested). This closes Bug #110839.
üst
d9a8e965
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
123 additions
and
31 deletions
+123
-31
CGIHTTPServer.py
Lib/CGIHTTPServer.py
+123
-31
No files found.
Lib/CGIHTTPServer.py
Dosyayı görüntüle @
e7d6b0a2
...
@@ -3,28 +3,31 @@
...
@@ -3,28 +3,31 @@
This module builds on SimpleHTTPServer by implementing GET and POST
This module builds on SimpleHTTPServer by implementing GET and POST
requests to cgi-bin scripts.
requests to cgi-bin scripts.
If the os.fork() function is not present, this module will not work;
If the os.fork() function is not present (e.g. on Windows),
SystemError will be raised instead.
os.popen2() is used as a fallback, with slightly altered semantics; if
that function is not present either (e.g. on Macintosh), only Python
scripts are supported, and they are executed by the current process.
In all cases, the implementation is intentionally naive -- all
requests are executed sychronously.
SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL
-- it may execute arbitrary Python code or external programs.
"""
"""
__version__
=
"0.
3
"
__version__
=
"0.
4
"
import
os
import
os
import
sys
import
string
import
string
import
urllib
import
urllib
import
BaseHTTPServer
import
BaseHTTPServer
import
SimpleHTTPServer
import
SimpleHTTPServer
try
:
os
.
fork
except
AttributeError
:
raise
SystemError
,
__name__
+
" requires os.fork()"
class
CGIHTTPRequestHandler
(
SimpleHTTPServer
.
SimpleHTTPRequestHandler
):
class
CGIHTTPRequestHandler
(
SimpleHTTPServer
.
SimpleHTTPRequestHandler
):
"""Complete HTTP server with GET, HEAD and POST commands.
"""Complete HTTP server with GET, HEAD and POST commands.
...
@@ -35,6 +38,10 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
@@ -35,6 +38,10 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""
"""
# Determine platform specifics
have_fork
=
hasattr
(
os
,
'fork'
)
have_popen2
=
hasattr
(
os
,
'popen2'
)
# Make rfile unbuffered -- we need to read one line and then pass
# Make rfile unbuffered -- we need to read one line and then pass
# the rest to a subprocess, so we can't use buffered input.
# the rest to a subprocess, so we can't use buffered input.
rbufsize
=
0
rbufsize
=
0
...
@@ -59,9 +66,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
@@ -59,9 +66,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
return
SimpleHTTPServer
.
SimpleHTTPRequestHandler
.
send_head
(
self
)
return
SimpleHTTPServer
.
SimpleHTTPRequestHandler
.
send_head
(
self
)
def
is_cgi
(
self
):
def
is_cgi
(
self
):
"""
test whether PATH
corresponds to a CGI script.
"""
Test whether self.path
corresponds to a CGI script.
Return a tuple (dir, rest) if
PATH
requires running a
Return a tuple (dir, rest) if
self.path
requires running a
CGI script, None if not. Note that rest begins with a
CGI script, None if not. Note that rest begins with a
slash if it is not empty.
slash if it is not empty.
...
@@ -83,6 +90,15 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
@@ -83,6 +90,15 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
cgi_directories
=
[
'/cgi-bin'
,
'/htbin'
]
cgi_directories
=
[
'/cgi-bin'
,
'/htbin'
]
def
is_executable
(
self
,
path
):
"""Test whether argument path is an executable file."""
return
executable
(
path
)
def
is_python
(
self
,
path
):
"""Test whether argument path is a Python script."""
head
,
tail
=
os
.
path
.
splitext
(
path
)
return
tail
.
lower
()
in
(
".py"
,
".pyw"
)
def
run_cgi
(
self
):
def
run_cgi
(
self
):
"""Execute a CGI script."""
"""Execute a CGI script."""
dir
,
rest
=
self
.
cgi_info
dir
,
rest
=
self
.
cgi_info
...
@@ -105,22 +121,17 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
@@ -105,22 +121,17 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
self
.
send_error
(
403
,
"CGI script is not a plain file (
%
s)"
%
self
.
send_error
(
403
,
"CGI script is not a plain file (
%
s)"
%
`scriptname`
)
`scriptname`
)
return
return
if
not
executable
(
scriptfile
):
ispy
=
self
.
is_python
(
scriptname
)
self
.
send_error
(
403
,
"CGI script is not executable (
%
s)"
%
if
not
ispy
:
if
not
(
self
.
have_fork
or
self
.
have_popen2
):
self
.
send_error
(
403
,
"CGI script is not a Python script (
%
s)"
%
`scriptname`
)
`scriptname`
)
return
return
nobody
=
nobody_uid
()
if
not
self
.
is_executable
(
scriptfile
):
self
.
send_response
(
200
,
"Script output follows"
)
self
.
send_error
(
403
,
"CGI script is not executable (
%
s)"
%
self
.
wfile
.
flush
()
# Always flush before forking
`scriptname`
)
pid
=
os
.
fork
()
if
pid
!=
0
:
# Parent
pid
,
sts
=
os
.
waitpid
(
pid
,
0
)
if
sts
:
self
.
log_error
(
"CGI script exit status x
%
x"
%
sts
)
return
return
# Child
try
:
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
# XXX Much of the following could be prepared ahead of time!
# XXX Much of the following could be prepared ahead of time!
env
=
{}
env
=
{}
...
@@ -140,9 +151,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
@@ -140,9 +151,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
if
host
!=
self
.
client_address
[
0
]:
if
host
!=
self
.
client_address
[
0
]:
env
[
'REMOTE_HOST'
]
=
host
env
[
'REMOTE_HOST'
]
=
host
env
[
'REMOTE_ADDR'
]
=
self
.
client_address
[
0
]
env
[
'REMOTE_ADDR'
]
=
self
.
client_address
[
0
]
#
AUTH_TYPE
# XXX
AUTH_TYPE
#
REMOTE_USER
# XXX
REMOTE_USER
#
REMOTE_IDENT
# XXX
REMOTE_IDENT
if
self
.
headers
.
typeheader
is
None
:
if
self
.
headers
.
typeheader
is
None
:
env
[
'CONTENT_TYPE'
]
=
self
.
headers
.
type
env
[
'CONTENT_TYPE'
]
=
self
.
headers
.
type
else
:
else
:
...
@@ -164,21 +175,99 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
@@ -164,21 +175,99 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
if
co
:
if
co
:
env
[
'HTTP_COOKIE'
]
=
string
.
join
(
co
,
', '
)
env
[
'HTTP_COOKIE'
]
=
string
.
join
(
co
,
', '
)
# XXX Other HTTP_* headers
# XXX Other HTTP_* headers
if
not
self
.
have_fork
:
# Since we're setting the env in the parent, provide empty
# values to override previously set values
for
k
in
(
'QUERY_STRING'
,
'REMOTE_HOST'
,
'CONTENT_LENGTH'
,
'HTTP_USER_AGENT'
,
'HTTP_COOKIE'
):
env
.
setdefault
(
k
,
""
)
self
.
send_response
(
200
,
"Script output follows"
)
decoded_query
=
string
.
replace
(
query
,
'+'
,
' '
)
decoded_query
=
string
.
replace
(
query
,
'+'
,
' '
)
if
self
.
have_fork
:
# Unix -- fork as we should
args
=
[
script
]
if
'='
not
in
decoded_query
:
args
.
append
(
decoded_query
)
nobody
=
nobody_uid
()
self
.
wfile
.
flush
()
# Always flush before forking
pid
=
os
.
fork
()
if
pid
!=
0
:
# Parent
pid
,
sts
=
os
.
waitpid
(
pid
,
0
)
if
sts
:
self
.
log_error
(
"CGI script exit status
%#
x"
,
sts
)
return
# Child
try
:
try
:
try
:
os
.
setuid
(
nobody
)
os
.
setuid
(
nobody
)
except
os
.
error
:
except
os
.
error
:
pass
pass
os
.
dup2
(
self
.
rfile
.
fileno
(),
0
)
os
.
dup2
(
self
.
rfile
.
fileno
(),
0
)
os
.
dup2
(
self
.
wfile
.
fileno
(),
1
)
os
.
dup2
(
self
.
wfile
.
fileno
(),
1
)
print
scriptfile
,
script
,
decoded_query
os
.
execve
(
scriptfile
,
args
,
env
)
os
.
execve
(
scriptfile
,
[
script
,
decoded_query
],
env
)
except
:
except
:
self
.
server
.
handle_error
(
self
.
request
,
self
.
client_address
)
self
.
server
.
handle_error
(
self
.
request
,
self
.
client_address
)
os
.
_exit
(
127
)
os
.
_exit
(
127
)
elif
self
.
have_popen2
:
# Windows -- use popen2 to create a subprocess
import
shutil
os
.
environ
.
update
(
env
)
cmdline
=
scriptfile
if
self
.
is_python
(
scriptfile
):
interp
=
sys
.
executable
if
interp
.
lower
()
.
endswith
(
"w.exe"
):
# On Windows, use python.exe, not python.exe
interp
=
interp
[:
-
5
]
=
interp
[
-
4
:]
cmdline
=
"
%
s
%
s"
%
(
interp
,
cmdline
)
if
'='
not
in
query
and
'"'
not
in
query
:
cmdline
=
'
%
s "
%
s"'
%
(
cmdline
,
query
)
self
.
log_error
(
"command:
%
s"
,
cmdline
)
try
:
nbytes
=
int
(
length
)
except
:
nbytes
=
0
fi
,
fo
=
os
.
popen2
(
cmdline
)
if
self
.
command
.
lower
()
==
"post"
and
nbytes
>
0
:
data
=
self
.
rfile
.
read
(
nbytes
)
fi
.
write
(
data
)
fi
.
close
()
shutil
.
copyfileobj
(
fo
,
self
.
wfile
)
sts
=
fo
.
close
()
if
sts
:
self
.
log_error
(
"CGI script exit status
%#
x"
,
sts
)
else
:
self
.
log_error
(
"CGI script exited OK"
)
else
:
# Other O.S. -- execute script in this process
os
.
environ
.
update
(
env
)
save_argv
=
sys
.
argv
save_stdin
=
sys
.
stdin
save_stdout
=
sys
.
stdout
save_stderr
=
sys
.
stderr
try
:
try
:
sys
.
argv
=
[
scriptfile
]
if
'='
not
in
decoded_query
:
sys
.
argv
.
append
(
decoded_query
)
sys
.
stdout
=
self
.
wfile
sys
.
stdin
=
self
.
rfile
execfile
(
scriptfile
,
{
"__name__"
:
"__main__"
})
finally
:
sys
.
argv
=
save_argv
sys
.
stdin
=
save_stdin
sys
.
stdout
=
save_stdout
sys
.
stderr
=
save_stderr
except
SystemExit
,
sts
:
self
.
log_error
(
"CGI script exit status
%
s"
,
str
(
sts
))
else
:
self
.
log_error
(
"CGI script exited OK"
)
nobody
=
None
nobody
=
None
...
@@ -187,7 +276,10 @@ def nobody_uid():
...
@@ -187,7 +276,10 @@ def nobody_uid():
global
nobody
global
nobody
if
nobody
:
if
nobody
:
return
nobody
return
nobody
try
:
import
pwd
import
pwd
except
ImportError
:
return
-
1
try
:
try
:
nobody
=
pwd
.
getpwnam
(
'nobody'
)[
2
]
nobody
=
pwd
.
getpwnam
(
'nobody'
)[
2
]
except
KeyError
:
except
KeyError
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment