2024-10-05 17:07:49 +03:00
|
|
|
#
|
|
|
|
# CatNet Python Server
|
|
|
|
#
|
|
|
|
# Copyright (C) 2023-2024 John Solntsev
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
|
2024-07-03 14:06:19 +03:00
|
|
|
import logging
|
|
|
|
|
2024-10-05 17:07:49 +03:00
|
|
|
|
2024-07-03 14:06:19 +03:00
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
STATUS_BY_CODE = {
|
2024-02-26 02:21:00 +03:00
|
|
|
200: "OK",
|
2024-10-03 14:26:15 +03:00
|
|
|
|
|
|
|
400: "Bad Request",
|
2024-02-26 02:21:00 +03:00
|
|
|
404: "Not Found",
|
2024-10-03 14:26:15 +03:00
|
|
|
405: "Method Not Allowed",
|
|
|
|
413: "Payload Too Large",
|
|
|
|
|
2024-02-26 02:21:00 +03:00
|
|
|
500: "Internal Server Error",
|
2024-10-03 14:26:15 +03:00
|
|
|
505: "HTTP Version Not Supported",
|
2024-02-26 02:21:00 +03:00
|
|
|
}
|
|
|
|
|
2024-07-03 14:06:19 +03:00
|
|
|
|
2024-02-26 02:21:00 +03:00
|
|
|
class Response:
|
|
|
|
def __iter__(self):
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __init__(self, status_code=200, additional_headers={}, data=None):
|
|
|
|
self.status_code = status_code
|
|
|
|
self.additional_headers = additional_headers
|
|
|
|
self.data = data
|
|
|
|
self.first = True
|
|
|
|
|
|
|
|
def __next__(self):
|
|
|
|
if self.first:
|
2024-07-03 14:06:19 +03:00
|
|
|
log.debug("First packet generation of response")
|
|
|
|
|
2024-02-26 02:21:00 +03:00
|
|
|
resp = "HTTP/1.1 {} {}\r\n"
|
|
|
|
resp += "Server: cnserv\r\n"
|
2024-10-08 13:54:15 +03:00
|
|
|
resp += "Connection: keep-alive\r\n"
|
|
|
|
|
2024-02-26 02:21:00 +03:00
|
|
|
for key, val in self.additional_headers.items():
|
|
|
|
resp += "{}: {}\r\n".format(key, val)
|
|
|
|
|
2024-10-08 13:54:15 +03:00
|
|
|
if type(self.data) == bytes:
|
|
|
|
resp += "Content-Length: {}\r\n".format(len(self.data))
|
|
|
|
elif hasattr(self.data, "__iter__"):
|
|
|
|
resp += "Content-Length: {}\r\n".format(next(self.data))
|
|
|
|
|
|
|
|
resp += "\r\n"
|
2024-07-03 14:06:19 +03:00
|
|
|
resp = resp.format(self.status_code, STATUS_BY_CODE[self.status_code])
|
2024-02-26 02:21:00 +03:00
|
|
|
resp = resp.encode("UTF-8")
|
|
|
|
|
|
|
|
if type(self.data) == bytes:
|
|
|
|
resp += self.data
|
|
|
|
|
|
|
|
self.first = False
|
2024-07-03 14:06:19 +03:00
|
|
|
|
2024-02-26 02:21:00 +03:00
|
|
|
return resp
|
|
|
|
|
|
|
|
else:
|
|
|
|
if type(self.data) == bytes:
|
|
|
|
raise StopIteration
|
|
|
|
|
|
|
|
elif hasattr(self.data, "__iter__"):
|
2024-07-03 14:06:19 +03:00
|
|
|
log.debug("Data is iterator, just generate next part")
|
2024-02-26 02:21:00 +03:00
|
|
|
try:
|
|
|
|
return next(self.data)
|
|
|
|
except StopIteration:
|
|
|
|
raise StopIteration
|