Programming/Python

[Python 2.7] 파이썬 웹 서버 오픈소스 소프트웨어 (1.1.0 / 20191022)

Talking1258 2019. 10. 22. 23:33

파이썬을 이용해 웹 서버를 실행할 수 있다. 로우 데이터의 이해를 도울뿐더러 웹 작동원리를 알 수 있다.

 

목적: 다른 소프트웨어를 의존하지 않고 직접 웹 서버를 만들고, 수정하고, 가동해 보자.

제작년월: 2019년 9월 ~

최초 공개일: 2019년 10월 19일

이번 공개일: 2019년 10월 22일

버전: 1.1.0

소프트웨어: Python 2.7.16

필요 모듈: (기본 설치 라이브러리)

 

import socket
import sys
import os.path
import os
import gzip

# DEFAULT SETTING
loc = {}
loc['default'] = "/home"
loc['nofile'] = "/notfound"
loc['imagetype'] = ['ico', 'png', 'jpg']
loc['downloadtype'] = ['zip', 'iso']
loc['downloadbuffer'] = 8192
# END OF DEFAULT SETTING


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", 80))
sock.listen(1)

def arrange(data):
    header = """
HTTP/1.1 200 OK
Date: SECURITY ALERT
Server: SECURITY ALERT (MCVKR Linux)
Last-Modified: SECURITY ALERT
Content-Type: text/html; charset=UTF-8
Content-Length: """ +  str(sys.getsizeof(data) - 33) + """
Accept-Ranges: bytes
Connection: close

"""
    return header + data

def arrangeimage(data):
    header = """
HTTP/1.1 200 OK
Date: SECURITY ALERT
Server: SECURITY ALERT (MCVKR Linux)
Last-Modified: SECURITY ALERT
ETag: "6da00e7-57e-4c8fbca4971c0"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Type: image/x-icon
Content-Length: """ +  str(sys.getsizeof(data) - 33) + """
Connection: close
Content-Encoding: identity
Age: 0

"""
    return header + data

def arrangedownload(size):
    header = """
HTTP/1.1 200 OK
Date: SECURITY ALERT
Server: SECURITY ALERT (MCVKR Linux)
Upgrade: h2,h2c
Connection: Upgrade, close
Last-Modified: SECURITY ALERT
Accept-Ranges: bytes
Content-Length: """ +  str(size) + """
Content-Type: application/octet-stream
Connection: close
Content-Encoding: identity

"""
    return header

archive = {}
while True:
    try:
        close = 0
        client, ipaddr = sock.accept()
        cldt = client.recv(4096)
        archive['get'] = cldt.split("\n")[0].split(" ")
        ## SECURITY CHECK ##
        print(ipaddr[0] + " Connected to " + archive['get'][1])
        if archive['get'][1] and len(archive['get'][1]) > 2:
            if '..' in archive['get'][1][1:]:
                client.send(arrange("SECURITY ALERT"))
        ## END OF SECURITY CHECK LINE ##
        if archive['get'][1][-1] == '/':
            archive['get'][1] = archive['get'][1][:-1]
        temp = archive['get'][1].split("?")
        if len(temp) > 1:
            getmsg = []
            for i in temp[1:]:
                getmsg.append(i)
        archive['get'][1] = temp[0]
        if archive['get'][1] == "":
            archive['get'][1] = loc['default']
        ## PROCESS
        if archive['get'][1].split('/')[-1].split('.')[-1] in loc['imagetype'] and os.path.isfile(archive['get'][1][1:]):
            close = 1
            f = open(archive['get'][1][1:], 'rb')
            client.send(arrangeimage(f.read()))
            f.close()
        if archive['get'][1].split('/')[-1].split('.')[-1] in loc['downloadtype'] and os.path.isfile(archive['get'][1][1:]):
            close = 1
            f = open(archive['get'][1][1:], 'rb')
            size = os.stat(archive['get'][1][1:]).st_size
            client.send(arrangedownload(size))
            temp = f.read(loc['downloadbuffer'])
            while temp:
                client.send(temp)
                temp = f.read(loc['downloadbuffer'])
            f.close()
        if close == 0 and os.path.isfile(archive['get'][1][1:]):
            close = 1
            f = open(archive['get'][1][1:], 'rb')
            client.send(arrange(f.read()))
            f.close()
        elif close == 0 and len(loc['nofile']) > 1 and os.path.isfile(loc['nofile'][1:]):
            close = 1
            f = open(loc['nofile'][1:], 'rb')
            client.send(arrange(f.read()))
            f.close()
        client.close()
    except:
        None
sock.close()

 

* 새로운 기능

- 파일 다운로드 가능