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
587c98c8
Kaydet (Commit)
587c98c8
authored
Mar 17, 2002
tarafından
Martin v. Löwis
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Patch #430706: Persistent connections in BaseHTTPServer.
üst
8ec03e05
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
145 additions
and
40 deletions
+145
-40
libbasehttp.tex
Doc/lib/libbasehttp.tex
+16
-6
BaseHTTPServer.py
Lib/BaseHTTPServer.py
+123
-34
SimpleHTTPServer.py
Lib/SimpleHTTPServer.py
+3
-0
NEWS
Misc/NEWS
+3
-0
No files found.
Doc/lib/libbasehttp.tex
Dosyayı görüntüle @
587c98c8
...
...
@@ -123,9 +123,12 @@ class variable.
\end{memberdesc}
\begin{memberdesc}
{
protocol
_
version
}
This specifies the HTTP protocol version used in responses.
Typically, this should not be overridden. Defaults to
\code
{
'HTTP/1.0'
}
.
This specifies the HTTP protocol version used in responses. If set
to
\code
{
'HTTP/1.1'
}
, the server will permit HTTP persistent
connections; however, your server
\emph
{
must
}
then include an
accurate
\code
{
Content-Length
}
header (using
\method
{
send
_
header()
}
)
in all of its responses to clients. For backwards compatibility,
the setting defaults to
\code
{
'HTTP/1.0'
}
.
\end{memberdesc}
\begin{memberdesc}
{
MessageClass
}
...
...
@@ -148,9 +151,16 @@ error response, and \var{longmessage} as the \var{explain} key
A
\class
{
BaseHTTPRequestHandler
}
instance has the following methods:
\begin{methoddesc}
{
handle
}{}
Overrides the superclass'
\method
{
handle()
}
method to provide the
specific handler behavior. This method will parse and dispatch
the request to the appropriate
\method
{
do
_
*()
}
method.
Calls
\method
{
handle
_
one
_
request()
}
once (or, if persistent connections
are enabled, multiple times) to handle incoming HTTP requests.
You should never need to override it; instead, implement appropriate
\method
{
do
_
*()
}
methods.
\end{methoddesc}
\begin{methoddesc}
{
handle
_
one
_
request
}{}
This method will parse and dispatch
the request to the appropriate
\method
{
do
_
*()
}
method. You should
never need to override it.
\end{methoddesc}
\begin{methoddesc}
{
send
_
error
}{
code
\optional
{
, message
}}
...
...
Lib/BaseHTTPServer.py
Dosyayı görüntüle @
587c98c8
...
...
@@ -2,7 +2,8 @@
Note: the class in this module doesn't implement any HTTP request; see
SimpleHTTPServer for simple implementations of GET, HEAD and POST
(including CGI scripts).
(including CGI scripts). It does, however, optionally implement HTTP/1.1
persistent connections, as of version 0.3.
Contents:
...
...
@@ -11,12 +12,9 @@ Contents:
XXX To do:
- send server version
- log requests even later (to capture byte count)
- log user-agent header and other interesting goodies
- send error log to separate file
- are request names really case sensitive?
"""
...
...
@@ -28,7 +26,15 @@ XXX To do:
# Expires September 8, 1995 March 8, 1995
#
# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
#
# and
#
# Network Working Group R. Fielding
# Request for Comments: 2616 et al
# Obsoletes: 2068 June 1999
# Category: Standards Track
#
# URL: http://www.faqs.org/rfcs/rfc2616.html
# Log files
# ---------
...
...
@@ -60,8 +66,7 @@ XXX To do:
# (Actually, the latter is only true if you know the server configuration
# at the time the request was made!)
__version__
=
"0.2"
__version__
=
"0.3"
__all__
=
[
"HTTPServer"
,
"BaseHTTPRequestHandler"
]
...
...
@@ -70,6 +75,7 @@ import time
import
socket
# For gethostbyaddr()
import
mimetools
import
SocketServer
import
cStringIO
# Default error message
DEFAULT_ERROR_MESSAGE
=
"""
\
...
...
@@ -122,9 +128,9 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
where <command> is a (case-sensitive) keyword such as GET or POST,
<path> is a string containing path information for the request,
and <version> should be the string "HTTP/1.0"
. <path> is encoded
using the URL encoding scheme (using
%
xx to signify the ASCII
character with hex code xx).
and <version> should be the string "HTTP/1.0"
or "HTTP/1.1".
<path> is encoded using the URL encoding scheme (using
%
xx to signify
the ASCII
character with hex code xx).
The protocol is vague about whether lines are separated by LF
characters or by CRLF pairs -- for compatibility with the widest
...
...
@@ -143,7 +149,7 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
0.9 request; this form has no optional headers and data part and
the reply consists of just the data.
The reply form of the HTTP 1.
0
protocol again has three parts:
The reply form of the HTTP 1.
x
protocol again has three parts:
1. One line giving the response code
2. An optional set of RFC-822-style headers
...
...
@@ -155,7 +161,7 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
<version> <responsecode> <responsestring>
where <version> is the protocol version (
always "HTTP/1.0
"),
where <version> is the protocol version (
"HTTP/1.0" or "HTTP/1.1
"),
<responsecode> is a 3-digit response code indicating success or
failure of the request, and <responsestring> is an optional
human-readable string explaining what the response code means.
...
...
@@ -221,6 +227,7 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
"""
self
.
request_version
=
version
=
"HTTP/0.9"
# Default
self
.
close_connection
=
1
requestline
=
self
.
raw_requestline
if
requestline
[
-
2
:]
==
'
\r\n
'
:
requestline
=
requestline
[:
-
2
]
...
...
@@ -233,20 +240,52 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
if
version
[:
5
]
!=
'HTTP/'
:
self
.
send_error
(
400
,
"Bad request version (
%
s)"
%
`version`
)
return
0
try
:
version_number
=
float
(
version
.
split
(
'/'
,
1
)[
1
])
except
ValueError
:
self
.
send_error
(
400
,
"Bad request version (
%
s)"
%
`version`
)
return
0
if
version_number
>=
1.1
and
self
.
protocol_version
>=
"HTTP/1.1"
:
self
.
close_connection
=
0
if
version_number
>=
2.0
:
self
.
send_error
(
505
,
"Invalid HTTP Version (
%
f)"
%
version_number
)
return
0
elif
len
(
words
)
==
2
:
[
command
,
path
]
=
words
self
.
close_connection
=
1
if
command
!=
'GET'
:
self
.
send_error
(
400
,
"Bad HTTP/0.9 request type (
%
s)"
%
`command`
)
return
0
elif
not
words
:
return
0
else
:
self
.
send_error
(
400
,
"Bad request syntax (
%
s)"
%
`requestline`
)
return
0
self
.
command
,
self
.
path
,
self
.
request_version
=
command
,
path
,
version
self
.
headers
=
self
.
MessageClass
(
self
.
rfile
,
0
)
# Deal with pipelining
bytes
=
""
while
1
:
line
=
self
.
rfile
.
readline
()
bytes
=
bytes
+
line
if
line
==
'
\r\n
'
or
line
==
'
\n
'
or
line
==
''
:
break
# Examine the headers and look for a Connection directive
hfile
=
cStringIO
.
StringIO
(
bytes
)
self
.
headers
=
self
.
MessageClass
(
hfile
)
conntype
=
self
.
headers
.
get
(
'Connection'
,
""
)
if
conntype
.
lower
()
==
'close'
:
self
.
close_connection
=
1
elif
(
conntype
.
lower
()
==
'keep-alive'
and
self
.
protocol_version
>=
"HTTP/1.1"
):
self
.
close_connection
=
0
return
1
def
handle
(
self
):
def
handle
_one_request
(
self
):
"""Handle a single HTTP request.
You normally don't need to override this method; see the class
...
...
@@ -254,8 +293,10 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
commands such as GET and POST.
"""
self
.
raw_requestline
=
self
.
rfile
.
readline
()
if
not
self
.
raw_requestline
:
self
.
close_connection
=
1
return
if
not
self
.
parse_request
():
# An error code has been sent, just exit
return
mname
=
'do_'
+
self
.
command
...
...
@@ -265,6 +306,14 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
method
=
getattr
(
self
,
mname
)
method
()
def
handle
(
self
):
"""Handle multiple requests if necessary."""
self
.
close_connection
=
1
self
.
handle_one_request
()
while
not
self
.
close_connection
:
self
.
handle_one_request
()
def
send_error
(
self
,
code
,
message
=
None
):
"""Send and log an error reply.
...
...
@@ -286,13 +335,14 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
message
=
short
explain
=
long
self
.
log_error
(
"code
%
d, message
%
s"
,
code
,
message
)
content
=
(
self
.
error_message_format
%
{
'code'
:
code
,
'message'
:
message
,
'explain'
:
explain
})
self
.
send_response
(
code
,
message
)
self
.
send_header
(
"Content-Type"
,
"text/html"
)
self
.
send_header
(
'Connection'
,
'close'
)
self
.
end_headers
()
self
.
wfile
.
write
(
self
.
error_message_format
%
{
'code'
:
code
,
'message'
:
message
,
'explain'
:
explain
})
if
self
.
command
!=
'HEAD'
and
code
>=
200
and
code
not
in
(
204
,
304
):
self
.
wfile
.
write
(
content
)
error_message_format
=
DEFAULT_ERROR_MESSAGE
...
...
@@ -305,13 +355,14 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
"""
self
.
log_request
(
code
)
if
message
is
None
:
if
self
.
responses
.
has_key
(
code
)
:
if
code
in
self
.
responses
:
message
=
self
.
responses
[
code
][
0
]
else
:
message
=
''
if
self
.
request_version
!=
'HTTP/0.9'
:
self
.
wfile
.
write
(
"
%
s
%
s
%
s
\r\n
"
%
(
self
.
protocol_version
,
str
(
code
),
message
))
self
.
wfile
.
write
(
"
%
s
%
d
%
s
\r\n
"
%
(
self
.
protocol_version
,
code
,
message
))
# print (self.protocol_version, code, message)
self
.
send_header
(
'Server'
,
self
.
version_string
())
self
.
send_header
(
'Date'
,
self
.
date_time_string
())
...
...
@@ -320,6 +371,12 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
if
self
.
request_version
!=
'HTTP/0.9'
:
self
.
wfile
.
write
(
"
%
s:
%
s
\r\n
"
%
(
keyword
,
value
))
if
keyword
.
lower
()
==
'connection'
:
if
value
.
lower
()
==
'close'
:
self
.
close_connection
=
1
elif
value
.
lower
()
==
'keep-alive'
:
self
.
close_connection
=
0
def
end_headers
(
self
):
"""Send the blank line ending the MIME headers."""
if
self
.
request_version
!=
'HTTP/0.9'
:
...
...
@@ -413,8 +470,7 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
# Essentially static class variables
# The version of the HTTP protocol we support.
# Don't override unless you know what you're doing (hint: incoming
# requests are required to have exactly this version string).
# Set this to HTTP/1.1 to enable automatic keepalive
protocol_version
=
"HTTP/1.0"
# The Message-like class used to parse headers
...
...
@@ -424,18 +480,31 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
# form {code: (shortmessage, longmessage)}.
# See http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html
responses
=
{
100
:
(
'Continue'
,
'Request received, please continue'
),
101
:
(
'Switching Protocols'
,
'Switching to new protocol; obey Upgrade header'
),
200
:
(
'OK'
,
'Request fulfilled, document follows'
),
201
:
(
'Created'
,
'Document created, URL follows'
),
202
:
(
'Accepted'
,
'Request accepted, processing continues off-line'
),
203
:
(
'
Partial i
nformation'
,
'Request fulfilled from cache'
),
203
:
(
'
Non-Authoritative I
nformation'
,
'Request fulfilled from cache'
),
204
:
(
'No response'
,
'Request fulfilled, nothing follows'
),
205
:
(
'Reset Content'
,
'Clear input form for further input.'
),
206
:
(
'Partial Content'
,
'Partial content follows.'
),
301
:
(
'Moved'
,
'Object moved permanently -- see URI list'
),
300
:
(
'Multiple Choices'
,
'Object has several resources -- see URI list'
),
301
:
(
'Moved Permanently'
,
'Object moved permanently -- see URI list'
),
302
:
(
'Found'
,
'Object moved temporarily -- see URI list'
),
303
:
(
'
Method
'
,
'Object moved -- see Method and URL list'
),
303
:
(
'
See Other
'
,
'Object moved -- see Method and URL list'
),
304
:
(
'Not modified'
,
'Document has not changed singe given time'
),
'Document has not changed since given time'
),
305
:
(
'Use Proxy'
,
'You must use proxy specified in Location to access this '
'resource.'
),
307
:
(
'Temporary Redirect'
,
'Object moved temporarily -- see URI list'
),
400
:
(
'Bad request'
,
'Bad request syntax or unsupported method'
),
...
...
@@ -445,21 +514,40 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
'No payment -- see charging schemes'
),
403
:
(
'Forbidden'
,
'Request forbidden -- authorization will not help'
),
404
:
(
'Not found'
,
'Nothing matches the given URI'
),
404
:
(
'Not Found'
,
'Nothing matches the given URI'
),
405
:
(
'Method Not Allowed'
,
'Specified method is invalid for this server.'
),
406
:
(
'Not Acceptable'
,
'URI not available in preferred format.'
),
407
:
(
'Proxy Authentication Required'
,
'You must authenticate with '
'this proxy before proceeding.'
),
408
:
(
'Request Time-out'
,
'Request timed out; try again later.'
),
409
:
(
'Conflict'
,
'Request conflict.'
),
410
:
(
'Gone'
,
'URI no longer exists and has been permanently removed.'
),
411
:
(
'Length Required'
,
'Client must specify Content-Length.'
),
412
:
(
'Precondition Failed'
,
'Precondition in headers is false.'
),
413
:
(
'Request Entity Too Large'
,
'Entity is too large.'
),
414
:
(
'Request-URI Too Long'
,
'URI is too long.'
),
415
:
(
'Unsupported Media Type'
,
'Entity body in unsupported format.'
),
416
:
(
'Requested Range Not Satisfiable'
,
'Cannot satisfy request range.'
),
417
:
(
'Expectation Failed'
,
'Expect condition could not be satisfied.'
),
500
:
(
'Internal error'
,
'Server got itself in trouble'
),
501
:
(
'Not
i
mplemented'
,
501
:
(
'Not
I
mplemented'
,
'Server does not support this operation'
),
502
:
(
'Service temporarily overloaded'
,
502
:
(
'Bad Gateway'
,
'Invalid responses from another server/proxy.'
),
503
:
(
'Service temporarily overloaded'
,
'The server cannot process the request due to a high load'
),
50
3
:
(
'Gateway timeout'
,
50
4
:
(
'Gateway timeout'
,
'The gateway server did not receive a timely response'
),
505
:
(
'HTTP Version not supported'
,
'Cannot fulfill request.'
),
}
def
test
(
HandlerClass
=
BaseHTTPRequestHandler
,
ServerClass
=
HTTPServer
):
ServerClass
=
HTTPServer
,
protocol
=
"HTTP/1.0"
):
"""Test the HTTP request handler class.
This runs an HTTP server on port 8000 (or the first command line
...
...
@@ -473,6 +561,7 @@ def test(HandlerClass = BaseHTTPRequestHandler,
port
=
8000
server_address
=
(
''
,
port
)
HandlerClass
.
protocol_version
=
protocol
httpd
=
ServerClass
(
server_address
,
HandlerClass
)
sa
=
httpd
.
socket
.
getsockname
()
...
...
Lib/SimpleHTTPServer.py
Dosyayı görüntüle @
587c98c8
...
...
@@ -82,6 +82,7 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
return
None
self
.
send_response
(
200
)
self
.
send_header
(
"Content-type"
,
ctype
)
self
.
send_header
(
"Content-Length"
,
str
(
os
.
fstat
(
f
.
fileno
())[
6
]))
self
.
end_headers
()
return
f
...
...
@@ -115,9 +116,11 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
# Note: a link to a directory displays with @ and links with /
f
.
write
(
'<li><a href="
%
s">
%
s</a>
\n
'
%
(
linkname
,
displayname
))
f
.
write
(
"</ul>
\n
<hr>
\n
"
)
length
=
f
.
tell
()
f
.
seek
(
0
)
self
.
send_response
(
200
)
self
.
send_header
(
"Content-type"
,
"text/html"
)
self
.
send_header
(
"Content-Length"
,
str
(
length
))
self
.
end_headers
()
return
f
...
...
Misc/NEWS
Dosyayı görüntüle @
587c98c8
...
...
@@ -44,6 +44,9 @@ Extension modules
Library
- The BaseHTTPServer implements now optionally HTTP/1.1 persistent
connections.
- socket module: the SSL support was broken out of the main
_socket module C helper and placed into a new _ssl helper
which now gets imported by socket.py if available and working.
...
...
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