mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
remove relative imports. new close function
This commit is contained in:
parent
4e6f60f4d8
commit
4bfdd60501
@ -34,7 +34,7 @@ import socket
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from .worker import Worker
|
from gunicorn.worker import Worker
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -122,18 +122,19 @@ class Arbiter(object):
|
|||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.set_sockopts(sock)
|
self.set_sockopts(sock)
|
||||||
sock.bind(address)
|
sock.bind(address)
|
||||||
sock.listen(2048)
|
sock.listen(1024)
|
||||||
return sock
|
return sock
|
||||||
|
|
||||||
def set_sockopts(self, sock):
|
def set_sockopts(self, sock):
|
||||||
sock.setblocking(0)
|
sock.setblocking(0)
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 0)
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
if hasattr(socket, "TCP_CORK"):
|
if hasattr(socket, "TCP_CORK"):
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_CORK, 1)
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_CORK, 1)
|
||||||
elif hasattr(socket, "TCP_NOPUSH"):
|
elif hasattr(socket, "TCP_NOPUSH"):
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NOPUSH, 1)
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NOPUSH, 1)
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.manage_workers()
|
self.manage_workers()
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
@ -24,5 +24,5 @@
|
|||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
# OTHER DEALINGS IN THE SOFTWARE.
|
# OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
from request import HTTPRequest, RequestError
|
from gunicorn.http.request import HTTPRequest, RequestError
|
||||||
from response import HTTPResponse
|
from gunicorn.http.response import HTTPResponse
|
||||||
@ -22,7 +22,6 @@
|
|||||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
# OTHER DEALINGS IN THE SOFTWARE.
|
# OTHER DEALINGS IN THE SOFTWARE.
|
||||||
from ctypes import *
|
|
||||||
|
|
||||||
class HttpParser(object):
|
class HttpParser(object):
|
||||||
|
|
||||||
@ -35,7 +34,8 @@ class HttpParser(object):
|
|||||||
|
|
||||||
def headers(self, headers, buf):
|
def headers(self, headers, buf):
|
||||||
""" take a string buff. It return
|
""" take a string buff. It return
|
||||||
environ or None if parsing isn't done.
|
new position or -1 if parsing isn't done.
|
||||||
|
headers dict is updated.
|
||||||
"""
|
"""
|
||||||
if self._headers:
|
if self._headers:
|
||||||
return self._headers
|
return self._headers
|
||||||
@ -53,6 +53,7 @@ class HttpParser(object):
|
|||||||
return -1
|
return -1
|
||||||
|
|
||||||
def finalize_headers(self, headers, headers_str, pos):
|
def finalize_headers(self, headers, headers_str, pos):
|
||||||
|
""" parse the headers """
|
||||||
lines = headers_str.split("\r\n")
|
lines = headers_str.split("\r\n")
|
||||||
|
|
||||||
# parse first line of headers
|
# parse first line of headers
|
||||||
@ -75,12 +76,14 @@ class HttpParser(object):
|
|||||||
return pos
|
return pos
|
||||||
|
|
||||||
def _first_line(self, line):
|
def _first_line(self, line):
|
||||||
|
""" parse first line """
|
||||||
method, path, version = line.strip().split(" ")
|
method, path, version = line.strip().split(" ")
|
||||||
self.version = version.strip()
|
self.version = version.strip()
|
||||||
self.method = method.upper()
|
self.method = method.upper()
|
||||||
self.path = path
|
self.path = path
|
||||||
|
|
||||||
def _parse_headerl(self, line):
|
def _parse_headerl(self, line):
|
||||||
|
""" parse header line"""
|
||||||
name, value = line.split(": ", 1)
|
name, value = line.split(": ", 1)
|
||||||
name = name.strip()
|
name = name.strip()
|
||||||
self._headers[name] = value.strip()
|
self._headers[name] = value.strip()
|
||||||
@ -99,11 +102,14 @@ class HttpParser(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def is_chunked(self):
|
def is_chunked(self):
|
||||||
|
""" is TE: chunked ?"""
|
||||||
transfert_encoding = self._headers.get('Transfer-Encoding', False)
|
transfert_encoding = self._headers.get('Transfer-Encoding', False)
|
||||||
return (transfert_encoding == "chunked")
|
return (transfert_encoding == "chunked")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content_len(self):
|
def content_len(self):
|
||||||
|
""" return content length as integer or
|
||||||
|
None."""
|
||||||
transfert_encoding = self._headers.get('Transfer-Encoding')
|
transfert_encoding = self._headers.get('Transfer-Encoding')
|
||||||
content_length = self._headers.get('Content-Length')
|
content_length = self._headers.get('Content-Length')
|
||||||
if transfert_encoding is None:
|
if transfert_encoding is None:
|
||||||
@ -114,6 +120,7 @@ class HttpParser(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def body_eof(self):
|
def body_eof(self):
|
||||||
|
"""do we have all the body ?"""
|
||||||
#TODO : add chunk
|
#TODO : add chunk
|
||||||
if self._content_len == 0:
|
if self._content_len == 0:
|
||||||
return True
|
return True
|
||||||
@ -122,7 +129,7 @@ class HttpParser(object):
|
|||||||
def read_chunk(self, data):
|
def read_chunk(self, data):
|
||||||
dlen = len(data)
|
dlen = len(data)
|
||||||
i = data.find("\n")
|
i = data.find("\n")
|
||||||
if i != -1:
|
if i != -1:
|
||||||
chunk = data[:i].strip().split(";", 1)
|
chunk = data[:i].strip().split(";", 1)
|
||||||
chunk_size = int(line.pop(0), 16)
|
chunk_size = int(line.pop(0), 16)
|
||||||
if chunk_size <= 0:
|
if chunk_size <= 0:
|
||||||
@ -131,6 +138,11 @@ class HttpParser(object):
|
|||||||
self.start_offset = i+1
|
self.start_offset = i+1
|
||||||
|
|
||||||
def filter_body(self, data):
|
def filter_body(self, data):
|
||||||
|
""" filter body and return a tuple:
|
||||||
|
body_chunk, new_buffer. They could be None.
|
||||||
|
new_fubber is always None if it's empty.
|
||||||
|
|
||||||
|
"""
|
||||||
dlen = len(data)
|
dlen = len(data)
|
||||||
chunk = None
|
chunk = None
|
||||||
if self.is_chunked:
|
if self.is_chunked:
|
||||||
@ -138,10 +150,9 @@ class HttpParser(object):
|
|||||||
else:
|
else:
|
||||||
if self._content_len > 0:
|
if self._content_len > 0:
|
||||||
nr = min(dlen, self._content_len)
|
nr = min(dlen, self._content_len)
|
||||||
print nr
|
|
||||||
chunk = data[:nr]
|
chunk = data[:nr]
|
||||||
self._content_len -= nr
|
self._content_len -= nr
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
self.start_offset = 0
|
self.start_offset = 0
|
||||||
return chunk, data
|
return (chunk, data)
|
||||||
@ -35,9 +35,9 @@ import array
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from gunicorn import __version__
|
from gunicorn import __version__
|
||||||
from .http_parser import HttpParser
|
from gunicorn.http.http_parser import HttpParser
|
||||||
from .tee import TeeInput
|
from gunicorn.http.tee import TeeInput
|
||||||
from ..util import CHUNK_SIZE, read_partial
|
from gunicorn.util import CHUNK_SIZE, read_partial
|
||||||
|
|
||||||
|
|
||||||
NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
|
NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
|
||||||
@ -80,8 +80,7 @@ class HTTPRequest(object):
|
|||||||
buf += data
|
buf += data
|
||||||
i = self.parser.headers(headers, buf)
|
i = self.parser.headers(headers, buf)
|
||||||
if i != -1: break
|
if i != -1: break
|
||||||
if not buf:
|
|
||||||
self.socket.close()
|
|
||||||
if not headers:
|
if not headers:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|||||||
@ -26,15 +26,17 @@
|
|||||||
|
|
||||||
import errno
|
import errno
|
||||||
import socket
|
import socket
|
||||||
|
import select
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from ..util import http_date, write, read_partial
|
import os
|
||||||
|
from gunicorn.util import http_date, write, read_partial, close
|
||||||
|
|
||||||
class HTTPResponse(object):
|
class HTTPResponse(object):
|
||||||
|
|
||||||
def __init__(self, sock, response, req):
|
def __init__(self, sock, response, req):
|
||||||
self.req = req
|
self.req = req
|
||||||
self.sock = sock
|
self.sock = sock.dup()
|
||||||
self.data = response
|
self.data = response
|
||||||
self.headers = req.response_headers or {}
|
self.headers = req.response_headers or {}
|
||||||
self.status = req.response_status
|
self.status = req.response_status
|
||||||
@ -59,7 +61,8 @@ class HTTPResponse(object):
|
|||||||
for chunk in self.data:
|
for chunk in self.data:
|
||||||
write(self.sock, chunk)
|
write(self.sock, chunk)
|
||||||
|
|
||||||
self.sock.close()
|
|
||||||
|
close(self.sock)
|
||||||
|
|
||||||
if hasattr(self.data, "close"):
|
if hasattr(self.data, "close"):
|
||||||
self.data.close()
|
self.data.close()
|
||||||
@ -34,9 +34,8 @@ read or restart etc ... It's based on TeeInput from unicorn.
|
|||||||
import os
|
import os
|
||||||
import StringIO
|
import StringIO
|
||||||
import tempfile
|
import tempfile
|
||||||
from ctypes import create_string_buffer
|
|
||||||
|
|
||||||
from ..util import MAX_BODY, CHUNK_SIZE
|
from gunicorn.util import MAX_BODY, CHUNK_SIZE
|
||||||
|
|
||||||
class TeeInput(object):
|
class TeeInput(object):
|
||||||
|
|
||||||
@ -122,7 +121,6 @@ class TeeInput(object):
|
|||||||
line = self.readline()
|
line = self.readline()
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def next(self):
|
def next(self):
|
||||||
r = self.readline()
|
r = self.readline()
|
||||||
if not r:
|
if not r:
|
||||||
|
|||||||
@ -29,7 +29,7 @@ import optparse as op
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from arbiter import Arbiter
|
from gunicorn.arbiter import Arbiter
|
||||||
|
|
||||||
LOG_LEVELS = {
|
LOG_LEVELS = {
|
||||||
"critical": logging.CRITICAL,
|
"critical": logging.CRITICAL,
|
||||||
|
|||||||
@ -42,12 +42,22 @@ monthname = [None,
|
|||||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||||
|
|
||||||
|
|
||||||
|
def close(sock):
|
||||||
|
try:
|
||||||
|
sock.shutdown(2)
|
||||||
|
except socket.error:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
sock.close()
|
||||||
|
except socket.error:
|
||||||
|
pass
|
||||||
|
|
||||||
def read_partial(sock, length):
|
def read_partial(sock, length):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
ret = select.select([sock.fileno()], [], [], 2.0)
|
ret = select.select([sock.fileno()], [], [], 2.0)
|
||||||
if ret[0]: break
|
if ret[0]: break
|
||||||
except socket.error, e:
|
except select.error, e:
|
||||||
if e[0] == errno.EINTR:
|
if e[0] == errno.EINTR:
|
||||||
break
|
break
|
||||||
raise
|
raise
|
||||||
@ -70,7 +80,6 @@ def write_nonblock(sock, data):
|
|||||||
if ret[1]: break
|
if ret[1]: break
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
if e[0] == errno.EINTR:
|
if e[0] == errno.EINTR:
|
||||||
time.sleep(1)
|
|
||||||
break
|
break
|
||||||
raise
|
raise
|
||||||
write(sock, data)
|
write(sock, data)
|
||||||
|
|||||||
@ -35,8 +35,8 @@ import sys
|
|||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from . import http
|
from gunicorn import http
|
||||||
from . import util
|
from gunicorn import util
|
||||||
|
|
||||||
class Worker(object):
|
class Worker(object):
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ class Worker(object):
|
|||||||
|
|
||||||
while self.alive:
|
while self.alive:
|
||||||
try:
|
try:
|
||||||
ret = select.select([self.socket], [], [], 2.0)
|
ret = select.select([self.socket], [], [], 15)
|
||||||
if ret[0]:
|
if ret[0]:
|
||||||
break
|
break
|
||||||
except select.error, e:
|
except select.error, e:
|
||||||
@ -115,11 +115,7 @@ class Worker(object):
|
|||||||
# loop and wait for some lovin.
|
# loop and wait for some lovin.
|
||||||
while self.alive:
|
while self.alive:
|
||||||
try:
|
try:
|
||||||
res = self.socket.accept()
|
client, addr = self.socket.accept()
|
||||||
if res is None:
|
|
||||||
break
|
|
||||||
client, addr = res
|
|
||||||
client.setblocking(0)
|
|
||||||
|
|
||||||
# handle connection
|
# handle connection
|
||||||
self.handle(client, addr)
|
self.handle(client, addr)
|
||||||
@ -143,5 +139,7 @@ class Worker(object):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.log.exception("Error processing request. [%s]" % str(e))
|
self.log.exception("Error processing request. [%s]" % str(e))
|
||||||
msg = "HTTP/1.0 500 Internal Server Error\r\n\r\n"
|
msg = "HTTP/1.0 500 Internal Server Error\r\n\r\n"
|
||||||
util.write_nonblock(client, msg)
|
#util.write_nonblock(client, msg)
|
||||||
client.close()
|
util.close(client)
|
||||||
|
|
||||||
|
del client
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user