Python: Higher order functions and closures
リクエストに応じて異なるコンテンツを返す
前のコードを少し簡略化します:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8090))
server_socket. listen(128)
while True:
client_socket, client_addr = server_socket. accept()
data = client_socket.recv(1024).decode('utf8')
# response header
response_header = 'HTTP/1.1 200 OK ' + 'content-type: text/html '
response_header += ' '
# response body
response_body = 'hello world'
# response
response = response_header + response_body
# send to client
client_socket. send(response. encode('utf8'))
このコードを実行すると、レスポンスは「hello world」になります。ここで、リクエストに応じて異なるコンテンツを返すように実装します。これにより、ブラウザから /register や /login にアクセスして異なるコンテンツを返すことができます。
リクエストヘッダーの最初の行からリクエストパスを取得できます。ブラウザからのリクエストでデータが空の場合があるため、ループ本体に以下のコードを追加します:
path = ''
if data: # # The data sent by the browser may be empty
path = data.splitlines()[0].split(' ')[1]
print('The requested path is {}'.format(path))
ブラウザで localhost:8090/login にアクセスすると、コンソールにアクセスパスが出力されます:
次に、このパス情報を使用して、パスごとに異なる response_body をカスタマイズできます(このとき、ブラウザのデフォルトの読み取りエンコーディングは gbk なので、コード内で調整が必要です):
if path == '/login':
response_body = 'Welcome to the login page'
elif path == '/register':
response_body = 'Welcome to the registration page'
elif path == '/':
response_body = 'Welcome to the homepage'
UTF-8 エンコーディングで返したい場合は、レスポンスヘッダーの content-type:text/html を content-type:text/html;charset=utf8 に書き換えて、ブラウザにレスポンスコンテンツのエンコーディング方式を通知するだけで対応できます。
ブラウザでどのパスにもアクセスしなかった場合にも、対応するレスポンスコンテンツを返す必要があります。分岐処理に以下の分岐を追加します:
else:
# Page not found 404 Page Not Found
response_header = 'HTTP/1.1 404 Page Not Found '
response_body = 'Sorry, the page you are looking for does not exist。。。'
ブラウザでアクセスすると、以下のようになります:
オブジェクト指向によるサーバーのカプセル化
import socket
class MyServer(object):
def __init__(self, ip, port):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind((ip, port))
self. socket. listen(128)
def run_forever(self):
while True:
client_socket, client_addr = self.socket.accept()
data = client_socket.recv(1024).decode('utf8')
path = ''
if data:
path = data.splitlines()[0].split(' ')[1]
response_header = 'HTTP/1.1 200 OK '
if path == '/login':
response_body = 'Welcome to the login page'
elif path == '/register':
response_body = 'Welcome to the registration page'
elif path == '/':
response_body = 'Welcome to the homepage'
else:
response_header = 'HTTP/1.1 404 Page Not Found '
response_body = 'Sorry, the page you are looking for does not exist。。。'
response_header += 'content-type:text/html;charset=utf8 '
response_header += ' '
response = response_header + response_body
client_socket. send(response. encode('utf8'))
server = MyServer('0.0.0.0', 9090)
server. run_forever()
前のコードを少し簡略化します:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8090))
server_socket. listen(128)
while True:
client_socket, client_addr = server_socket. accept()
data = client_socket.recv(1024).decode('utf8')
# response header
response_header = 'HTTP/1.1 200 OK ' + 'content-type: text/html '
response_header += ' '
# response body
response_body = 'hello world'
# response
response = response_header + response_body
# send to client
client_socket. send(response. encode('utf8'))
このコードを実行すると、レスポンスは「hello world」になります。ここで、リクエストに応じて異なるコンテンツを返すように実装します。これにより、ブラウザから /register や /login にアクセスして異なるコンテンツを返すことができます。
リクエストヘッダーの最初の行からリクエストパスを取得できます。ブラウザからのリクエストでデータが空の場合があるため、ループ本体に以下のコードを追加します:
path = ''
if data: # # The data sent by the browser may be empty
path = data.splitlines()[0].split(' ')[1]
print('The requested path is {}'.format(path))
ブラウザで localhost:8090/login にアクセスすると、コンソールにアクセスパスが出力されます:
次に、このパス情報を使用して、パスごとに異なる response_body をカスタマイズできます(このとき、ブラウザのデフォルトの読み取りエンコーディングは gbk なので、コード内で調整が必要です):
if path == '/login':
response_body = 'Welcome to the login page'
elif path == '/register':
response_body = 'Welcome to the registration page'
elif path == '/':
response_body = 'Welcome to the homepage'
UTF-8 エンコーディングで返したい場合は、レスポンスヘッダーの content-type:text/html を content-type:text/html;charset=utf8 に書き換えて、ブラウザにレスポンスコンテンツのエンコーディング方式を通知するだけで対応できます。
ブラウザでどのパスにもアクセスしなかった場合にも、対応するレスポンスコンテンツを返す必要があります。分岐処理に以下の分岐を追加します:
else:
# Page not found 404 Page Not Found
response_header = 'HTTP/1.1 404 Page Not Found '
response_body = 'Sorry, the page you are looking for does not exist。。。'
ブラウザでアクセスすると、以下のようになります:
オブジェクト指向によるサーバーのカプセル化
import socket
class MyServer(object):
def __init__(self, ip, port):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind((ip, port))
self. socket. listen(128)
def run_forever(self):
while True:
client_socket, client_addr = self.socket.accept()
data = client_socket.recv(1024).decode('utf8')
path = ''
if data:
path = data.splitlines()[0].split(' ')[1]
response_header = 'HTTP/1.1 200 OK '
if path == '/login':
response_body = 'Welcome to the login page'
elif path == '/register':
response_body = 'Welcome to the registration page'
elif path == '/':
response_body = 'Welcome to the homepage'
else:
response_header = 'HTTP/1.1 404 Page Not Found '
response_body = 'Sorry, the page you are looking for does not exist。。。'
response_header += 'content-type:text/html;charset=utf8 '
response_header += ' '
response = response_header + response_body
client_socket. send(response. encode('utf8'))
server = MyServer('0.0.0.0', 9090)
server. run_forever()
Related Articles
-
A detailed explanation of Hadoop core architecture HDFS
Knowledge Base Team
-
What Does IOT Mean
Knowledge Base Team
-
6 Optional Technologies for Data Storage
Knowledge Base Team
-
What Is Blockchain Technology
Knowledge Base Team
Explore More Special Offers
-
Short Message Service(SMS) & Mail Service
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00
