【问题标题】:GET and POST between a UWP Application and an HTTP ServerUWP 应用程序和 HTTP 服务器之间的 GET 和 POST
【发布时间】:2022-02-05 19:06:14
【问题描述】:

我最近刚开始尝试在我的计算机上使用 Python 设置 HTTP 服务器,以尝试与我正在构建的 UWP 应用程序进行通信。我的总体目标是在线托管此服务器并将照片从 UWP 应用程序发送到 HTTP 服务器,然后在图像上运行 Python/C++ 脚本。一旦完成处理,我想将一些数据输出到文件中,然后将其发送回 UWP 应用程序。我是服务器和数据库的新手,所以我不太确定从这里去哪里。

正如我所提到的,我已经使用以下 Python 代码设置了一个非常基本的服务器:

from http.server import BaseHTTPRequestHandler, HTTPServer
import time

hostName = "localhost"
serverPort = 8080

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):


self.send_response(200)
    self.send_header("Content-type", "text/html")
    self.end_headers()
    self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
    if(self.path == "/test"):
        exec(open("test.py").read())

def do_POST(self):
    content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
    post_data = self.rfile.read(content_length) # <--- Gets the data itself

    self.send_response(200)
    self.send_header('Content-type', 'text/html')
    self.end_headers()
    self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))


if __name__ == "__main__":        
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print("Server started http://%s:%s" % (hostName, serverPort))

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        print("Server stopped.")
        webServer.server_close()

而且我能够成功地 GET 和 POST,但现在我不知道该怎么做。我是否需要设置一个数据库来存储我发布的任何数据?如果是这样,最好的方法是什么?

任何帮助将不胜感激!

【问题讨论】:

    标签: python database server uwp


    【解决方案1】:

    不,您不需要数据库。

    使用以下代码设置基于套接字的安全 http 服务器。它对特定类型的 DOS 攻击具有一些基本保护,并允许您禁止特定地址访问您的服务。

    注意 cmets:它们解释了重要的代码部分。确保安全地配置您的服务器。不要依赖来自您的应用程序的数据。例如,攻击者可以创建恶意请求,看起来就像来自您的应用程序的正常请求。不要在 Response 结构中插入无效数据,否则您将收到 500 Internal Server Error 回复。

    这段代码没有依赖;它可以在任何操作系统上运行,因为它不使用特定于操作系统的 API。 (在 Python 3.9.0、Windows 10 上测试。)

    import socket
    import threading
    import ssl
    import time
    import tempfile
    import os
    hostname="localhost"    #hostName in your code
    port=8080               #serverPort in your code - default HTTP Port is 80
    banned_IPs=()           #Every IP in this list is denied access to your service
    
    #SSL-Specific settings
    SSLEnabled=False        #set to True if you got a valid SSL/TLS configuration for your server, and want to provide a secure version of the service
    SSLContext=None         #must be set if SSLEnabled - set to ssl.SSLContext with proper configuration - see documentation: https://docs.python.org/3/library/ssl.html
    SSLPort=None            #Port for the secure version of your service - must be set if SSLEnabled is True and may not hav the same value as port
    
    #These are some security limits - change them if necessary
    MaxIpConnections=1024   #Maximum Connections per IP address per minute - DDOS-Protection
    MaxHeaderSize=8192      #8 KB maximum Header Size - Protection against malicious clients trying to fill up device-memory
    MaxBodySize=1073741824  #1 GB maximum Payload Size - malicious clients may try 
    
    to overload memory with extremely large payloads
    
    #Internal variables:
    _clientRegister={}      #DDOS-Protection
    _max_blank_packets=128  #Detect wheter a socket has been closed
    
    #Configuration - I use IPv4 here - replace AF_INET by AF_INET6 for IPv6
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    if SSLEnabled:
        SSLSock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    def IO(request,response):
        """do something with the data here.
    As i don't know, what you want to do, I will do nothing here."""
        pass
    class Request(object):
        """A HTTP request"""
        method=None     #GET,POST,PUT,DELETE,...
        route=None      #path, /example,/foo/example,/,...
        body=None       #Filename of a File containing the request's Body, None if no body was present.
        proto="HTTP/1.1"#Protocol, either "HTTP/1.1" or "HTTP/1.0"
        headers={}      #Headers, having a structure like {key:[value[,value[,...]]],[key:[...][,...]]}
        ip=None         #I don't need to explain that
        localport=None  #The Locally used port, one of port, SSLPort
        secure=False    #wheter the request wa made over TLS/SSL
        remoteport=None #Client-Side port. Your'e probaly not gonna need it
        socket=None     #underlying socket. Your'e probaly not gonna need it
        def __init__(self,method,route,proto,headers,bodyfile,addr,lport,sock):
            self.method=method.decode("ascii")
            self.route=route.decode("ascii")
            self.proto=proto.decode("ascii")
            for i in headers:
                k=i
                self.headers[k.decode("ascii")]=[]
                for v in headers[i]:
                    self.headers[k.decode("ascii")].append(v.decode("ascii"))
            self.body=bodyfile
            self.ip=addr[0]
            self.port=addr[1]
            self.localport=lport
            self.secure=(self.localport==SSLPort)
            self.socket=sock
    class Response(object):
        """A HTTP Response"""
        status=200      #Statuscode
        statustext="OK" #Statustext
        proto="HTTP/1.1"#Protocol, either "HTTP/1.1" or "HTTP/1.0"
        headers={"Connection":["close"]}#Same structure as in Request
        body=None       #Filename for Responsebody, use tempfile.mktemp() for temporary file.
        socket=None     #underlying socket. Your'e probaly not gonna need it
    "Now some Internal functions - just ignore them"
    #Some binding + listening stuff
    sock.bind((hostname,port))
    sock.listen(32)
    if SSLEnabled:
        SSLSock.bind((hostname,SSLPort))
        SSLSock.listen(32)
    def checkIp(ip):
        if _clientRegister[ip][1]<=time.time():
            del _clientRegister[ip]
    def garbage_collector_thread():
        while True:
            try:
                for i in _clientRegister:
                    checkIp(i)
            except:
                pass
            time.sleep(30)#Garbage-Collection every half minute
    def client_thread(cli,addr):
        ip=addr[0]
        if ip in banned_IPs:
            cli.close()
            return
        if ip in _clientRegister:
            _clientRegister[ip][0]+=1
            if _clientRegister[ip][0]>MaxIpConnections:
                cli.close()
                return
        else:
            _clientRegister[ip]=[0,time.time()+60]
        if cli.getsockname()[1]==SSLPort:
            cli=SSLContext.wrap(cli,True)
        header=b""
        blank=0
        try:
            while not b"\r\n\r\n" in header:
                block=cli.recv(1024)
                if block==b"":
                    blank+=1
                else:
                    blank=0
                if blank>=_max_blank_packets:
                    cli.close()
                    return
                if len(header)>MaxHeaderSize:
                    cli.sendall(b"HTTP/1.1 431 Header Fields Too Large\r\nConnection: closed\r\n\r\n")
                    cli.close()
                    return
                header+=block
            header,body=header.split(b"\r\n\r\n",1)
            head={}
            status,*header=header.split(b"\r\n")
            for i in header:
                k,v=i.split(b": ",1)
                if k in header:
                    head[k].append(v)
                else:
                    head[k]=[v]
            method,route,proto=status.split(b" ",2)
            if b"Content-Length" in header:
                v=int(header[b"Content-Length"][0])
                if v>MaxBodySize:
                    cli.sendall(b"HTTP/1.1 413 Payload too large\r\nConnection: close\r\n\r\n")
                    cli.close()
                    return
                size=len(body)
                returnfile=tempfile.mktemp()
                f=open(returnfile,"wb")
                f.write(returnfile)
                while size<v:
                    block=cli.recv(1024)
                    if block==b"":
                        blank+=1
                    else:
                        blank=0
                    if blank>=_max_blank_packets:
                        cli.close()
                        f.close()
                        os.remove(returnfile)
                        return
                    size+=len(block)
                    f.write(block)
                f.close()
            elif body!=b"":
                cli.sendall(b"HTTP/1.1 411 Length Required\r\nConnection: close\r\n\r\n")
                cli.close()
                return
            else:
                returnfile=None
            request=Request(method,route,proto,head,returnfile,addr,cli.getsockname()[1],cli)
            response=Response()
            response.socket=cli
        except ConnectionError:
            cli.close()
            return
        except:
            try:
                cli.sendall(b"HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n")
            except:
                pass
            cli.close()
            return
        try:
            IO(request,response)
        except:
            try:
                cli.sendall(b"HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n")
                cli.close()
                return
            except:
                cli.close()
                return
        try:
            if response.body!=None:
                response.headers["Content-Length"]=[str(os.path.getsize(response.body))]
            r=b" ".join([response.proto.encode("ascii"),str(response.status).encode("ascii"),response.statustext.encode("ascii")])
            r+=b"\r\n"
            for i in response.headers:
                k=i
                for v in response.headers[k]:
                    r+=k.encode("ascii")+b": "+v.encode("ascii")+b"\r\n"
            r+=b"\r\n"
            cli.sendall(r)
            if response.body!=None:
                f=open(response.body,"rb")
                while True:
                    block=f.read(1024)
                    if block==b"":
                        break
                    cli.sendall(block)
                f.close()
            cli.close()
            return
        except:
            try:
                cli.sendall(b"HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n")
                cli.close()
                return
            except:
                cli.close()
                return
    def SSLAccept(sock):
        while True:
            cli,addr=sock.accept()
            threading.Thread(target=client_thread,args=(cli,addr)).start()
    if SSLEnabled:
        threading.Thread(target=SSLAccept,args=(SSLSock,)).start()
    threading.Thread(target=garbage_collector_thread).start()
    while True:
        cli,addr=sock.accept()
        threading.Thread(target=client_thread,args=(cli,addr)).start()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 2017-08-28
      • 2013-10-08
      • 2011-10-07
      • 2012-09-23
      • 2019-09-04
      • 1970-01-01
      相关资源
      最近更新 更多