Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
77b3114d
Commit
77b3114d
authored
May 15, 2010
by
Denis Bilenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pywsgi: get rid of the dependency BaseHTTPServer. Based on the patch by Ralf Schmitt
parent
ccf96afa
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
154 additions
and
48 deletions
+154
-48
gevent/pywsgi.py
gevent/pywsgi.py
+154
-48
No files found.
gevent/pywsgi.py
View file @
77b3114d
...
@@ -5,10 +5,11 @@ import errno
...
@@ -5,10 +5,11 @@ import errno
import
sys
import
sys
import
time
import
time
import
traceback
import
traceback
import
mimetools
from
datetime
import
datetime
from
urllib
import
unquote
from
urllib
import
unquote
from
gevent
import
socket
from
gevent
import
socket
import
BaseHTTPServer
import
gevent
import
gevent
from
gevent.server
import
StreamServer
from
gevent.server
import
StreamServer
from
gevent.hub
import
GreenletExit
from
gevent.hub
import
GreenletExit
...
@@ -31,6 +32,8 @@ _INTERNAL_ERROR_BODY = 'Internal Server Error'
...
@@ -31,6 +32,8 @@ _INTERNAL_ERROR_BODY = 'Internal Server Error'
_INTERNAL_ERROR_HEADERS
=
[(
'Content-Type'
,
'text/plain'
),
_INTERNAL_ERROR_HEADERS
=
[(
'Content-Type'
,
'text/plain'
),
(
'Connection'
,
'close'
),
(
'Connection'
,
'close'
),
(
'Content-Length'
,
str
(
len
(
_INTERNAL_ERROR_BODY
)))]
(
'Content-Length'
,
str
(
len
(
_INTERNAL_ERROR_BODY
)))]
_REQUEST_TOO_LONG_RESPONSE
=
"HTTP/1.0 414 Request URI Too Long
\
r
\
n
Connection: close
\
r
\
n
Content-length: 0
\
r
\
n
\
r
\
n
"
_BAD_REQUEST_RESPONSE
=
"HTTP/1.0 400 Bad Request
\
r
\
n
Connection: close
\
r
\
n
Content-length: 0
\
r
\
n
\
r
\
n
"
def
format_date_time
(
timestamp
):
def
format_date_time
(
timestamp
):
...
@@ -42,8 +45,6 @@ class Input(object):
...
@@ -42,8 +45,6 @@ class Input(object):
def
__init__
(
self
,
rfile
,
content_length
,
wfile
=
None
,
wfile_line
=
None
,
chunked_input
=
False
):
def
__init__
(
self
,
rfile
,
content_length
,
wfile
=
None
,
wfile_line
=
None
,
chunked_input
=
False
):
self
.
rfile
=
rfile
self
.
rfile
=
rfile
if
content_length
is
not
None
:
content_length
=
int
(
content_length
)
self
.
content_length
=
content_length
self
.
content_length
=
content_length
self
.
wfile
=
wfile
self
.
wfile
=
wfile
self
.
wfile_line
=
wfile_line
self
.
wfile_line
=
wfile_line
...
@@ -109,42 +110,143 @@ class Input(object):
...
@@ -109,42 +110,143 @@ class Input(object):
return
list
(
self
)
return
list
(
self
)
def
__iter__
(
self
):
def
__iter__
(
self
):
while
True
:
return
self
def
next
(
self
):
line
=
self
.
readline
()
line
=
self
.
readline
()
if
not
line
:
if
not
line
:
break
raise
StopIteration
yield
line
return
line
class
WSGIHandler
(
BaseHTTPServer
.
BaseHTTPRequestHandler
):
class
WSGIHandler
(
object
):
protocol_version
=
'HTTP/1.1'
protocol_version
=
'HTTP/1.1'
MessageClass
=
mimetools
.
Message
def
handle_one_request
(
self
):
def
__init__
(
self
,
socket
,
address
,
server
):
if
self
.
rfile
.
closed
:
self
.
socket
=
socket
self
.
close_connection
=
1
self
.
client_address
=
address
return
self
.
server
=
server
self
.
rfile
=
socket
.
makefile
(
'rb'
,
-
1
)
self
.
wfile
=
socket
.
makefile
(
'wb'
,
0
)
def
handle
(
self
):
try
:
try
:
self
.
raw_requestline
=
self
.
rfile
.
readline
(
MAX_REQUEST_LINE
)
while
True
:
if
len
(
self
.
raw_requestline
)
==
MAX_REQUEST_LINE
:
self
.
time_start
=
time
.
time
()
self
.
status
=
'414'
self
.
time_finish
=
0
self
.
wfile
.
write
(
result
=
self
.
handle_one_request
()
"HTTP/1.0 414 Request URI Too Long
\
r
\
n
Connection: close
\
r
\
n
Content-length: 0
\
r
\
n
\
r
\
n
"
)
if
result
is
None
:
self
.
close_connection
=
1
break
if
result
is
True
:
continue
self
.
status
,
response_body
=
result
self
.
wfile
.
write
(
response_body
)
if
self
.
time_finish
==
0
:
self
.
time_finish
=
time
.
time
()
self
.
log_request
()
self
.
log_request
()
break
finally
:
self
.
__dict__
.
pop
(
'socket'
,
None
)
self
.
__dict__
.
pop
(
'rfile'
,
None
)
self
.
__dict__
.
pop
(
'wfile'
,
None
)
def
_check_http_version
(
self
):
version
=
self
.
request_version
if
not
version
.
startswith
(
"HTTP/"
):
return
False
version
=
tuple
(
int
(
x
)
for
x
in
version
[
5
:].
split
(
"."
))
# "HTTP/"
if
version
[
1
]
<
0
or
version
<
(
0
,
9
)
or
version
>=
(
2
,
0
):
return
False
return
True
def
read_request
(
self
,
raw_requestline
):
self
.
requestline
=
raw_requestline
.
rstrip
()
words
=
self
.
requestline
.
split
()
if
len
(
words
)
==
3
:
self
.
command
,
self
.
path
,
self
.
request_version
=
words
if
not
self
.
_check_http_version
():
self
.
log_error
(
'Invalid http version: %r'
,
raw_requestline
)
return
elif
len
(
words
)
==
2
:
self
.
command
,
self
.
path
=
words
if
self
.
command
!=
"GET"
:
self
.
log_error
(
'Expected GET method: %r'
,
raw_requestline
)
return
self
.
request_version
=
"HTTP/0.9"
else
:
self
.
log_error
(
'Invalid GET method: %r'
,
raw_requestline
)
return
return
except
socket
.
error
,
e
:
if
e
[
0
]
!=
errno
.
EBADF
and
e
[
0
]
!=
errno
.
ECONNRESET
:
raise
self
.
raw_requestline
=
''
if
not
self
.
raw_requestline
:
self
.
headers
=
self
.
MessageClass
(
self
.
rfile
,
0
)
self
.
close_connection
=
1
if
self
.
headers
.
status
:
self
.
log_error
(
'Invalid headers status: %r'
,
self
.
headers
.
status
)
return
return
if
not
self
.
parse_request
():
content_length
=
self
.
headers
.
get
(
"Content-Length"
)
if
content_length
is
not
None
:
content_length
=
int
(
content_length
)
if
content_length
<
0
:
self
.
log_error
(
'Invalid Content-Length: %r'
,
content_length
)
return
if
content_length
and
self
.
command
in
(
'GET'
,
'HEAD'
):
self
.
log_error
(
'Unexpected Content-Length'
)
return
return
self
.
content_length
=
content_length
if
self
.
request_version
==
"HTTP/1.1"
:
conntype
=
self
.
headers
.
get
(
"Connection"
,
""
).
lower
()
if
conntype
==
"close"
:
self
.
close_connection
=
True
else
:
self
.
close_connection
=
False
else
:
self
.
close_connection
=
True
return
True
def
log_error
(
self
,
msg
,
*
args
):
try
:
message
=
msg
%
args
except
Exception
:
traceback
.
print_exc
()
message
=
'%r %r'
%
(
msg
,
args
)
sys
.
exc_clear
()
try
:
message
=
'%s: %s'
%
(
self
.
socket
,
message
)
except
Exception
:
sys
.
exc_clear
()
try
:
sys
.
stderr
.
write
(
message
+
'
\
n
'
)
except
Exception
:
traceback
.
print_exc
()
sys
.
exc_clear
()
def
handle_one_request
(
self
):
if
self
.
rfile
.
closed
:
return
raw_requestline
=
self
.
rfile
.
readline
(
MAX_REQUEST_LINE
)
if
not
raw_requestline
:
return
self
.
response_length
=
0
if
len
(
raw_requestline
)
>=
MAX_REQUEST_LINE
:
return
(
'414'
,
_REQUEST_TOO_LONG_RESPONSE
)
try
:
if
not
self
.
read_request
(
raw_requestline
):
return
(
'400'
,
_BAD_REQUEST_RESPONSE
)
except
ValueError
,
ex
:
self
.
log_error
(
'Invalid request: %s'
,
str
(
ex
)
or
ex
.
__class__
.
__name__
)
return
(
'400'
,
_BAD_REQUEST_RESPONSE
)
except
Exception
,
ex
:
traceback
.
print_exc
()
self
.
log_error
(
'Invalid request: %s'
,
str
(
ex
)
or
ex
.
__class__
.
__name__
)
return
(
'400'
,
_BAD_REQUEST_RESPONSE
)
self
.
environ
=
self
.
get_environ
()
self
.
environ
=
self
.
get_environ
()
self
.
application
=
self
.
server
.
application
self
.
application
=
self
.
server
.
application
try
:
try
:
...
@@ -156,6 +258,14 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
...
@@ -156,6 +258,14 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
else
:
else
:
raise
raise
if
self
.
close_connection
:
return
if
self
.
rfile
.
closed
:
return
return
True
# read more requests
def
write
(
self
,
data
):
def
write
(
self
,
data
):
towrite
=
[]
towrite
=
[]
if
not
self
.
status
:
if
not
self
.
status
:
...
@@ -212,15 +322,16 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
...
@@ -212,15 +322,16 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self
.
response_headers_list
=
[
x
[
0
]
for
x
in
self
.
response_headers
]
self
.
response_headers_list
=
[
x
[
0
]
for
x
in
self
.
response_headers
]
return
self
.
write
return
self
.
write
def
log_request
(
self
,
*
args
):
def
log_request
(
self
):
log
=
self
.
server
.
log
log
=
self
.
server
.
log
if
log
is
not
None
:
if
log
is
not
None
:
log
.
write
(
self
.
format_request
(
*
args
)
+
'
\
n
'
)
log
.
write
(
self
.
format_request
()
+
'
\
n
'
)
def
format_request
(
self
,
length
=
'-'
):
def
format_request
(
self
):
now
=
datetime
.
now
().
replace
(
microsecond
=
0
)
return
'%s - - [%s] "%s" %s %s %.6f'
%
(
return
'%s - - [%s] "%s" %s %s %.6f'
%
(
self
.
client_address
[
0
],
self
.
client_address
[
0
],
self
.
log_date_time_string
()
,
now
,
self
.
requestline
,
self
.
requestline
,
(
self
.
status
or
'000'
).
split
()[
0
],
(
self
.
status
or
'000'
).
split
()[
0
],
self
.
response_length
,
self
.
response_length
,
...
@@ -295,23 +406,22 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
...
@@ -295,23 +406,22 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
env
[
'CONTENT_LENGTH'
]
=
length
env
[
'CONTENT_LENGTH'
]
=
length
env
[
'SERVER_PROTOCOL'
]
=
'HTTP/1.0'
env
[
'SERVER_PROTOCOL'
]
=
'HTTP/1.0'
host
,
port
=
self
.
reques
t
.
getsockname
()
host
,
port
=
self
.
socke
t
.
getsockname
()
env
[
'SERVER_NAME'
]
=
host
env
[
'SERVER_NAME'
]
=
host
env
[
'SERVER_PORT'
]
=
str
(
port
)
env
[
'SERVER_PORT'
]
=
str
(
port
)
env
[
'REMOTE_ADDR'
]
=
self
.
client_address
[
0
]
env
[
'REMOTE_ADDR'
]
=
self
.
client_address
[
0
]
env
[
'GATEWAY_INTERFACE'
]
=
'CGI/1.1'
env
[
'GATEWAY_INTERFACE'
]
=
'CGI/1.1'
for
h
in
self
.
headers
.
headers
:
for
header
in
self
.
headers
.
headers
:
k
,
v
=
h
.
split
(
':'
,
1
)
key
,
value
=
header
.
split
(
':'
,
1
)
k
=
k
.
replace
(
'-'
,
'_'
).
upper
()
key
=
key
.
replace
(
'-'
,
'_'
).
upper
()
v
=
v
.
strip
()
if
key
not
in
(
'CONTENT_TYPE'
,
'CONTENT_LENGTH'
):
if
k
in
env
:
value
=
value
.
strip
()
continue
key
=
'HTTP_'
+
key
envk
=
'HTTP_'
+
k
if
key
in
env
:
if
envk
in
env
:
env
[
key
]
+=
','
+
value
env
[
envk
]
+=
','
+
v
else
:
else
:
env
[
envk
]
=
v
env
[
key
]
=
value
if
env
.
get
(
'HTTP_EXPECT'
)
==
'100-continue'
:
if
env
.
get
(
'HTTP_EXPECT'
)
==
'100-continue'
:
wfile
=
self
.
wfile
wfile
=
self
.
wfile
...
@@ -320,14 +430,10 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
...
@@ -320,14 +430,10 @@ class WSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler):
wfile
=
None
wfile
=
None
wfile_line
=
None
wfile_line
=
None
chunked
=
env
.
get
(
'HTTP_TRANSFER_ENCODING'
,
''
).
lower
()
==
'chunked'
chunked
=
env
.
get
(
'HTTP_TRANSFER_ENCODING'
,
''
).
lower
()
==
'chunked'
self
.
wsgi_input
=
Input
(
self
.
rfile
,
length
,
wfile
=
wfile
,
wfile_line
=
wfile_line
,
chunked_input
=
chunked
)
self
.
wsgi_input
=
Input
(
self
.
rfile
,
self
.
content_
length
,
wfile
=
wfile
,
wfile_line
=
wfile_line
,
chunked_input
=
chunked
)
env
[
'wsgi.input'
]
=
self
.
wsgi_input
env
[
'wsgi.input'
]
=
self
.
wsgi_input
return
env
return
env
def
finish
(
self
):
BaseHTTPServer
.
BaseHTTPRequestHandler
.
finish
(
self
)
self
.
connection
.
close
()
class
WSGIServer
(
StreamServer
):
class
WSGIServer
(
StreamServer
):
"""A WSGI server based on :class:`StreamServer` that supports HTTPS."""
"""A WSGI server based on :class:`StreamServer` that supports HTTPS."""
...
...
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