@ -17,29 +17,26 @@ import sys
import threading
import threading
import traceback
import traceback
# 检查 Python 版本
PY3 = sys . version_info > = ( 3 , 0 )
PY3 = sys . version_info > = ( 3 , 0 )
UNICODE_ENCODING = " utf-8 "
UNICODE_ENCODING = " utf-8 " # 定义 Unicode 编码
DEBUG = False
DEBUG = False # 调试模式标志
if PY3 :
if PY3 :
from http . client import INTERNAL_SERVER_ERROR
# 导入 Python 3 中的 HTTP 相关模块
from http . client import NOT_FOUND
from http . client import INTERNAL_SERVER_ERROR , NOT_FOUND , OK
from http . client import OK
from http . server import BaseHTTPRequestHandler , HTTPServer
from http . server import BaseHTTPRequestHandler
from http . server import HTTPServer
from socketserver import ThreadingMixIn
from socketserver import ThreadingMixIn
from urllib . parse import parse_qs
from urllib . parse import parse_qs , unquote_plus
from urllib . parse import unquote_plus
else :
else :
from BaseHTTPServer import BaseHTTPRequestHandler
# 对于 Python 2, 导入相应的 HTTP 相关模块
from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler , HTTPServer
from httplib import INTERNAL_SERVER_ERROR
from httplib import INTERNAL_SERVER_ERROR , NOT_FOUND , OK
from httplib import NOT_FOUND
from httplib import OK
from SocketServer import ThreadingMixIn
from SocketServer import ThreadingMixIn
from urlparse import parse_qs
from urlparse import parse_qs
from urllib import unquote_plus
from urllib import unquote_plus
# SQLite 模式定义,创建用户表并插入示例数据
SCHEMA = """
SCHEMA = """
CREATE TABLE users (
CREATE TABLE users (
id INTEGER ,
id INTEGER ,
@ -54,9 +51,11 @@ SCHEMA = """
INSERT INTO users ( id , name , surname ) VALUES ( 5 , NULL , ' nameisnull ' ) ;
INSERT INTO users ( id , name , surname ) VALUES ( 5 , NULL , ' nameisnull ' ) ;
"""
"""
# 定义监听地址和端口
LISTEN_ADDRESS = " localhost "
LISTEN_ADDRESS = " localhost "
LISTEN_PORT = 8440
LISTEN_PORT = 8440
# 全局变量
_conn = None
_conn = None
_cursor = None
_cursor = None
_lock = None
_lock = None
@ -68,13 +67,15 @@ def init(quiet=False):
global _cursor
global _cursor
global _lock
global _lock
# 在内存中创建 SQLite 数据库连接
_conn = sqlite3 . connect ( " :memory: " , isolation_level = None , check_same_thread = False )
_conn = sqlite3 . connect ( " :memory: " , isolation_level = None , check_same_thread = False )
_cursor = _conn . cursor ( )
_cursor = _conn . cursor ( ) # 创建游标,用于执行 SQL 命令
_lock = threading . Lock ( )
_lock = threading . Lock ( ) # 创建线程锁,以处理多线程环境下的数据库访问
_cursor . executescript ( SCHEMA )
_cursor . executescript ( SCHEMA ) # 执行脚本以创建表并插入数据
if quiet :
if quiet :
# 如果 quiet 为 True, 则禁止输出
global print
global print
def _ ( * args , * * kwargs ) :
def _ ( * args , * * kwargs ) :
@ -83,6 +84,7 @@ def init(quiet=False):
print = _
print = _
class ThreadingServer ( ThreadingMixIn , HTTPServer ) :
class ThreadingServer ( ThreadingMixIn , HTTPServer ) :
# 允许多线程处理 HTTP 请求
def finish_request ( self , * args , * * kwargs ) :
def finish_request ( self , * args , * * kwargs ) :
try :
try :
HTTPServer . finish_request ( self , * args , * * kwargs )
HTTPServer . finish_request ( self , * args , * * kwargs )
@ -91,13 +93,16 @@ class ThreadingServer(ThreadingMixIn, HTTPServer):
traceback . print_exc ( )
traceback . print_exc ( )
class ReqHandler ( BaseHTTPRequestHandler ) :
class ReqHandler ( BaseHTTPRequestHandler ) :
# 请求处理类
def do_REQUEST ( self ) :
def do_REQUEST ( self ) :
# 处理请求,分割路径和查询字符串
path , query = self . path . split ( ' ? ' , 1 ) if ' ? ' in self . path else ( self . path , " " )
path , query = self . path . split ( ' ? ' , 1 ) if ' ? ' in self . path else ( self . path , " " )
params = { }
params = { }
if query :
if query :
params . update ( parse_qs ( query ) )
params . update ( parse_qs ( query ) ) # 解析查询字符串为字典
# 检查是否出现恶意脚本
if " <script> " in unquote_plus ( query ) :
if " <script> " in unquote_plus ( query ) :
self . send_response ( INTERNAL_SERVER_ERROR )
self . send_response ( INTERNAL_SERVER_ERROR )
self . send_header ( " X-Powered-By " , " Express " )
self . send_header ( " X-Powered-By " , " Express " )
@ -106,18 +111,25 @@ class ReqHandler(BaseHTTPRequestHandler):
self . wfile . write ( " CLOUDFLARE_ERROR_500S_BOX " . encode ( UNICODE_ENCODING ) )
self . wfile . write ( " CLOUDFLARE_ERROR_500S_BOX " . encode ( UNICODE_ENCODING ) )
return
return
# 处理请求数据(如果有)
if hasattr ( self , " data " ) :
if hasattr ( self , " data " ) :
if self . data . startswith ( ' { ' ) and self . data . endswith ( ' } ' ) :
if self . data . startswith ( ' { ' ) and self . data . endswith ( ' } ' ) :
params . update ( json . loads ( self . data ) )
params . update ( json . loads ( self . data ) ) # JSON 数据
elif self . data . startswith ( ' < ' ) and self . data . endswith ( ' > ' ) :
elif self . data . startswith ( ' < ' ) and self . data . endswith ( ' > ' ) :
params . update ( dict ( ( _ [ 0 ] , _ [ 1 ] . replace ( " ' " , " ' " ) . replace ( " " " , ' " ' ) . replace ( " < " , ' < ' ) . replace ( " > " , ' > ' ) . replace ( " & " , ' & ' ) ) for _ in re . findall ( r ' name= " ([^ " ]+) " value= " ([^ " ]*) " ' , self . data ) ) )
# 解析 HTML 表单数据
params . update ( dict ( ( _ [ 0 ] , _ [ 1 ] . replace ( " ' " , " ' " ) . replace ( " " " , ' " ' )
. replace ( " < " , ' < ' ) . replace ( " > " , ' > ' ) . replace ( " & " , ' & ' ) )
for _ in re . findall ( r ' name= " ([^ " ]+) " value= " ([^ " ]*) " ' , self . data ) ) )
else :
else :
self . data = self . data . replace ( ' ; ' , ' & ' ) # Note: seems that Python3 started ignoring parameter splitting with ';'
# 处理 URL 编码数据
self . data = self . data . replace ( ' ; ' , ' & ' ) # 兼容性处理
params . update ( parse_qs ( self . data ) )
params . update ( parse_qs ( self . data ) )
# 处理请求头参数
for name in self . headers :
for name in self . headers :
params [ name . lower ( ) ] = self . headers [ name ]
params [ name . lower ( ) ] = self . headers [ name ]
# 处理 Cookie 参数
if " cookie " in params :
if " cookie " in params :
for part in params [ " cookie " ] . split ( ' ; ' ) :
for part in params [ " cookie " ] . split ( ' ; ' ) :
part = part . strip ( )
part = part . strip ( )
@ -125,14 +137,17 @@ class ReqHandler(BaseHTTPRequestHandler):
name , value = part . split ( ' = ' , 1 )
name , value = part . split ( ' = ' , 1 )
params [ name . strip ( ) ] = unquote_plus ( value . strip ( ) )
params [ name . strip ( ) ] = unquote_plus ( value . strip ( ) )
# 将多值参数转换为单值
for key in params :
for key in params :
if params [ key ] and isinstance ( params [ key ] , ( tuple , list ) ) :
if params [ key ] and isinstance ( params [ key ] , ( tuple , list ) ) :
params [ key ] = params [ key ] [ - 1 ]
params [ key ] = params [ key ] [ - 1 ]
self . url , self . params = path , params
self . url , self . params = path , params # 存储 URL 和参数
if self . url == ' / ' :
if self . url == ' / ' :
# 主页处理
if not any ( _ in self . params for _ in ( " id " , " query " ) ) :
if not any ( _ in self . params for _ in ( " id " , " query " ) ) :
# 如果没有 ID 或查询参数,则显示主页面
self . send_response ( OK )
self . send_response ( OK )
self . send_header ( " Content-type " , " text/html; charset= %s " % UNICODE_ENCODING )
self . send_header ( " Content-type " , " text/html; charset= %s " % UNICODE_ENCODING )
self . send_header ( " Connection " , " close " )
self . send_header ( " Connection " , " close " )
@ -142,27 +157,33 @@ class ReqHandler(BaseHTTPRequestHandler):
code , output = OK , " "
code , output = OK , " "
try :
try :
# 处理回显参数
if self . params . get ( " echo " , " " ) :
if self . params . get ( " echo " , " " ) :
output + = " %s <br> " % self . params [ " echo " ]
output + = " %s <br> " % self . params [ " echo " ]
if self . params . get ( " reflect " , " " ) :
if self . params . get ( " reflect " , " " ) :
output + = " %s <br> " % self . params . get ( " id " )
output + = " %s <br> " % self . params . get ( " id " )
with _lock :
with _lock : # 使用锁来确保线程安全
if " query " in self . params :
if " query " in self . params :
# 执行任意 SQL 查询
_cursor . execute ( self . params [ " query " ] )
_cursor . execute ( self . params [ " query " ] )
elif " id " in self . params :
elif " id " in self . params :
# 通过 ID 查询用户
if " base64 " in self . params :
if " base64 " in self . params :
_cursor . execute ( " SELECT * FROM users WHERE id= %s LIMIT 0, 1 " % base64 . b64decode ( " %s === " % self . params [ " id " ] , altchars = self . params . get ( " altchars " ) ) . decode ( ) )
_cursor . execute ( " SELECT * FROM users WHERE id= %s LIMIT 0, 1 " %
base64 . b64decode ( " %s === " % self . params [ " id " ] ,
altchars = self . params . get ( " altchars " ) ) . decode ( ) )
else :
else :
_cursor . execute ( " SELECT * FROM users WHERE id= %s LIMIT 0, 1 " % self . params [ " id " ] )
_cursor . execute ( " SELECT * FROM users WHERE id= %s LIMIT 0, 1 " % self . params [ " id " ] )
results = _cursor . fetchall ( )
results = _cursor . fetchall ( ) # 获取查询结果
output + = " <b>SQL results:</b><br> \n "
output + = " <b>SQL results:</b><br> \n "
# 根据查询结果决定响应的状态码和内容
if self . params . get ( " code " , " " ) :
if self . params . get ( " code " , " " ) :
if not results :
if not results :
code = INTERNAL_SERVER_ERROR
code = INTERNAL_SERVER_ERROR # 出错
else :
else :
if results :
if results :
output + = " <table border= \" 1 \" > \n "
output + = " <table border= \" 1 \" > \n "
@ -175,15 +196,16 @@ class ReqHandler(BaseHTTPRequestHandler):
output + = " </table> \n "
output + = " </table> \n "
else :
else :
output + = " no results found "
output + = " no results found " # 查询无结果
output + = " </body></html> "
output + = " </body></html> "
except Exception as ex :
except Exception as ex :
code = INTERNAL_SERVER_ERROR
code = INTERNAL_SERVER_ERROR
# 捕获异常并返回错误信息
output = " %s : %s " % ( re . search ( r " ' ([^ ' ]+) ' " , str ( type ( ex ) ) ) . group ( 1 ) , ex )
output = " %s : %s " % ( re . search ( r " ' ([^ ' ]+) ' " , str ( type ( ex ) ) ) . group ( 1 ) , ex )
# 发送响应
self . send_response ( code )
self . send_response ( code )
self . send_header ( " Content-type " , " text/html " )
self . send_header ( " Content-type " , " text/html " )
self . send_header ( " Connection " , " close " )
self . send_header ( " Connection " , " close " )
@ -194,26 +216,30 @@ class ReqHandler(BaseHTTPRequestHandler):
self . end_headers ( )
self . end_headers ( )
self . wfile . write ( output if isinstance ( output , bytes ) else output . encode ( UNICODE_ENCODING ) )
self . wfile . write ( output if isinstance ( output , bytes ) else output . encode ( UNICODE_ENCODING ) )
else :
else :
# 对于未定义的路径返回 404
self . send_response ( NOT_FOUND )
self . send_response ( NOT_FOUND )
self . send_header ( " Connection " , " close " )
self . send_header ( " Connection " , " close " )
self . end_headers ( )
self . end_headers ( )
def do_GET ( self ) :
def do_GET ( self ) :
self . do_REQUEST ( )
self . do_REQUEST ( ) # 处理 GET 请求
def do_PUT ( self ) :
def do_PUT ( self ) :
self . do_POST ( )
self . do_POST ( ) # 处理 PUT 请求
def do_HEAD ( self ) :
def do_HEAD ( self ) :
self . do_REQUEST ( )
self . do_REQUEST ( ) # 处理 HEAD 请求
def do_POST ( self ) :
def do_POST ( self ) :
# 处理 POST 请求
length = int ( self . headers . get ( " Content-length " , 0 ) )
length = int ( self . headers . get ( " Content-length " , 0 ) )
if length :
if length :
# 读取请求体数据
data = self . rfile . read ( length )
data = self . rfile . read ( length )
data = unquote_plus ( data . decode ( UNICODE_ENCODING , " ignore " ) )
data = unquote_plus ( data . decode ( UNICODE_ENCODING , " ignore " ) )
self . data = data
self . data = data
elif self . headers . get ( " Transfer-encoding " ) == " chunked " :
elif self . headers . get ( " Transfer-encoding " ) == " chunked " :
# 处理 chunked 请求
data , line = b " " , b " "
data , line = b " " , b " "
count = 0
count = 0
@ -232,10 +258,10 @@ class ReqHandler(BaseHTTPRequestHandler):
self . data = data . decode ( UNICODE_ENCODING , " ignore " )
self . data = data . decode ( UNICODE_ENCODING , " ignore " )
self . do_REQUEST ( )
self . do_REQUEST ( ) # 处理 POST 逻辑
def log_message ( self , format , * args ) :
def log_message ( self , format , * args ) :
return
return # 不记录日志
def run ( address = LISTEN_ADDRESS , port = LISTEN_PORT ) :
def run ( address = LISTEN_ADDRESS , port = LISTEN_PORT ) :
global _alive
global _alive
@ -244,16 +270,17 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
_alive = True
_alive = True
_server = ThreadingServer ( ( address , port ) , ReqHandler )
_server = ThreadingServer ( ( address , port ) , ReqHandler )
print ( " [i] running HTTP server at ' http:// %s : %d ' " % ( address , port ) )
print ( " [i] running HTTP server at ' http:// %s : %d ' " % ( address , port ) )
_server . serve_forever ( )
_server . serve_forever ( ) # 开始监听并处理请求
except KeyboardInterrupt :
except KeyboardInterrupt :
_server . socket . close ( )
_server . socket . close ( ) # 关闭服务器
raise
raise
finally :
finally :
_alive = False
_alive = False
if __name__ == " __main__ " :
if __name__ == " __main__ " :
try :
try :
init ( )
init ( ) # 初始化数据库和服务器
run ( sys . argv [ 1 ] if len ( sys . argv ) > 1 else LISTEN_ADDRESS , int ( sys . argv [ 2 ] if len ( sys . argv ) > 2 else LISTEN_PORT ) )
run ( sys . argv [ 1 ] if len ( sys . argv ) > 1 else LISTEN_ADDRESS ,
int ( sys . argv [ 2 ] if len ( sys . argv ) > 2 else LISTEN_PORT ) )
except KeyboardInterrupt :
except KeyboardInterrupt :
print ( " \r [x] Ctrl-C received " )
print ( " \r [x] Ctrl-C received " ) # 捕获 Ctrl-C 终止信号