Python手寫檔案伺服器延伸內容
應用上一篇的Python檔案伺服器,我們還可以寫一些不同的回應,像是..
1. 回應Client端要求HTML檔案
def responseHtmlFile(hdl, path):f = open(path, "rb")
fs = os.fstat(f.fileno())
hdl.send_response(200)
hdl.send_header("Content-type", "text/html; charset=UTF-8")
hdl.send_header("Content-Length", str(fs[6]))
hdl.send_header("Last-Modified", hdl.date_time_string(fs.st_mtime))
hdl.end_headers()
shutil.copyfileobj(f, hdl.wfile)
f.close()
del f
用法:
responseHtmlFile(hdl, '/home/user/your_html_file.htm')
2. 回應Client端,要求轉址到另一個目標位置
def responseHttpRedirect(hdl, target):hdl.send_response(301)
hdl.send_header("Location", target)
hdl.end_headers()
用法:
responseHttpRedirect(hdl, 'http://www.google.com')
3. 把Client的request資訊parse後再回應給Client
def responseGetRequest(hdl):parsed = urlparse(hdl.path)
hdl.send_response(200)
hdl.send_header("Content-type", "text/html; charset=UTF-8")
hdl.end_headers()
hdl.wfile.write("<html><body><h1>got GET request</h1><p>")
hdl.wfile.write(('scheme=%s<br/>' % parsed.scheme))
hdl.wfile.write(('netloc=%s<br/>' % parsed.netloc))
hdl.wfile.write(('path=%s<br/>' % parsed.path))
hdl.wfile.write(('params=%s<br/>' % parsed.params))
hdl.wfile.write(('query=%s<br/>' % parsed.query))
hdl.wfile.write(('fragments=%s<br/>' % parsed.fragment))
hdl.wfile.write("</p></body></html>")
用法:
responseGetRequest(hdl)
4. 接受使用者的檔案上傳
# 接受上傳需要使用表單網頁和POST方法,附在後面# 這只是個小 DEMO, 不建議直接使用在真正的網站中, 需要多考量一些網路攻擊的問題
# UploadedFilPath是儲存上傳檔案的完整路徑def responsePostRequest(hdl):
form = cgi.FieldStorage(
fp=hdl.rfile,
headers=hdl.headers,
environ={
'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': hdl.headers['Content-Type'],
}
)
hdl.send_response(200)
hdl.send_header("Content-type", "text/html; charset=UTF-8")
hdl.end_headers()
hdl.wfile.write("<html><body><h1>got POST request</h1><p>")
for name in form.keys():
item = form[name]
if item.filename:
uploadfile = None
try:
uploadfile = open(UploadedFilPath, 'wb')
uploadfile.write(item.file.read())
except IOError:
hdl.log_error("Uploading file IOError: %s", sys.exc_info())
finally:
if uploadfile:
hdl.log_message("clear uploadfile")
filelen = uploadfile.tell();
uploadfile.flush()
uploadfile.close()
del uploadfile
else:
filelen = 0;
hdl.wfile.write(
'Uploaded {} as {!r} ({} bytes)<br/>'.format(
name, item.filename, filelen)
)
else:
hdl.wfile.write('{}={}<br/>'.format(
name, form[name].value))
hdl.wfile.write("</p></body></html>");
用法:
在get部分加入回應搭配給使用者選擇檔案的網頁
在post部分加入處理的部分
def do_GET(hdl):
hdl.log_message("from %s req %s", hdl.client_address, hdl.path)
try:
if hdl.path == "/form.html":
responseHtmlFile(hdl, HtmlFormFilPath)
def do_POST(hdl):
hdl.log_message("from %s req %s", hdl.client_address, hdl.path)
try:
if hdl.path.startswith("/form_proc"):
responsePostRequest(hdl)
else:
hdl.log_error("invalid post operation")
hdl.send_error(404)
return None
except:
hdl.log_error("Unexpected error: %s", sys.exc_info())
hdl.send_error(404)
return None
搭配的表單form.html網頁
<html>
<head>
<title>html form</title>
</head>
<body>
<h1>POST method</h1>
<form id="postform" action="form_proc" method="post" enctype="multipart/form-data">
附加檔案:<input name="uploadedfile" type="file"/><br/>
<input type="submit" value="送出表單"/>
</form>
</body>
</html>
留言