使用 python 脚本向带有 netcat 的服务器发送 GET 请求
Using python script to send GET request to a server with netcat
我是 运行ning Ubuntu 16.04,我正在尝试编写一个 python 脚本,在给定 [=66= 的情况下向指定的图像文件发出 GET 请求].例如,在下面的代码中:
host
是 www.google.com
port
是 80
u.path
是 /images/srpr/logo3w.png
proc = Popen(["netcat {} {}".format(host, port)], shell= True)
proc = Popen(["GET {} HTTP/1.1".format(u.path)], shell= True)
proc = Popen(["Host: {}".format(host)], shell= True)
proc = Popen(["Connection: close"], shell= True)
proc = Popen(["\n"], shell= True)
我的问题是我可以在终端中正常执行这些,但是当我尝试 运行 脚本时,它似乎在它需要之前将 GET
请求发送到 www.google.com
u.path
的规范。我知道这样做有两个原因。首先,就在服务器响应到来之前,我得到以下信息:
/bin/sh: 1: Host:: not found
/bin/sh: 1: Connection:: not found
其次,我知道图像数据的服务器响应是一堆丑陋的东西,在终端上被解释为奇怪的 Unicode 符号,但我显然得到了 www.google.com
HTML 文本在服务器响应上。
我想我可能需要让它等待 HTTP 请求,直到 netcat
STDIN 打开,但我不知道如何做。或者它只是完成了请求,因为它以某种方式发送了 \n
?我真的不知道。
编辑:看起来它实际上并没有向 www.google.com
发送请求。我将服务器响应保存为 .html
文件,它看起来像一个云端网站
EDIT2:经过更多的研究,问题似乎是因为 netcat 是交互式的,所以它 'deadlocks' 或类似的东西。我尝试使用 proc.communicate()
但由于我需要发送多行它不允许它看到 communicate
只允许将初始输入写入 STDIN
然后它发送 EOF
或类似的东西。这导致我尝试使用 proc.stdin.write
但这显然也已知会导致与使 Popen
命令对 STDIN
、[=35= 使用 subprocess.PIPE
有关的事情发生死锁],以及 STDERR
。它还要求将输入编码为 bytes-like
对象,我已经完成了,但是当我在最后发送 \r\n\r\n
以尝试关闭连接时,它什么也没做, STDOUT
只包含 b''
我理解为 bytes
形式的空字符串
对于遇到类似问题的任何人,这是我找到的解决方案:
#begin the interactive shell of netcat
proc = Popen(['netcat -q -1 {} {}'.format(host, port)], shell=True, stdout=PIPE, stdin=PIPE, stderr=PIPE)
#set file status flags on stdout to non-blocking reads
fcntl.fcntl(proc.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
#each time we write a diffrent line to the interactive shell
#we need to flush the buffer just to be safe
#credit to http://nigelarmstrong.me/2015/04/python-subprocess/
proc.stdin.write(str.encode('GET %s HTTP/1.1\n' %(path+filename)))
proc.stdin.flush()
proc.stdin.write(str.encode('Host: {}\n'.format(host)))
proc.stdin.flush()
proc.stdin.write(str.encode('Connection: close\n'))
proc.stdin.flush()
proc.stdin.write(str.encode('\r\n\r\n'))
proc.stdin.flush()
#give the server time to respond
proc.wait()
#store the server response (which is bytes-like)
#attempting to decode it results in error since we're recieving data as a mix of text/image
serv_response = proc.stdout.read()
我是 运行ning Ubuntu 16.04,我正在尝试编写一个 python 脚本,在给定 [=66= 的情况下向指定的图像文件发出 GET 请求].例如,在下面的代码中:
host
是 www.google.com
port
是 80
u.path
是 /images/srpr/logo3w.png
proc = Popen(["netcat {} {}".format(host, port)], shell= True)
proc = Popen(["GET {} HTTP/1.1".format(u.path)], shell= True)
proc = Popen(["Host: {}".format(host)], shell= True)
proc = Popen(["Connection: close"], shell= True)
proc = Popen(["\n"], shell= True)
我的问题是我可以在终端中正常执行这些,但是当我尝试 运行 脚本时,它似乎在它需要之前将 GET
请求发送到 www.google.com
u.path
的规范。我知道这样做有两个原因。首先,就在服务器响应到来之前,我得到以下信息:
/bin/sh: 1: Host:: not found
/bin/sh: 1: Connection:: not found
其次,我知道图像数据的服务器响应是一堆丑陋的东西,在终端上被解释为奇怪的 Unicode 符号,但我显然得到了 www.google.com
HTML 文本在服务器响应上。
我想我可能需要让它等待 HTTP 请求,直到 netcat
STDIN 打开,但我不知道如何做。或者它只是完成了请求,因为它以某种方式发送了 \n
?我真的不知道。
编辑:看起来它实际上并没有向 www.google.com
发送请求。我将服务器响应保存为 .html
文件,它看起来像一个云端网站
EDIT2:经过更多的研究,问题似乎是因为 netcat 是交互式的,所以它 'deadlocks' 或类似的东西。我尝试使用 proc.communicate()
但由于我需要发送多行它不允许它看到 communicate
只允许将初始输入写入 STDIN
然后它发送 EOF
或类似的东西。这导致我尝试使用 proc.stdin.write
但这显然也已知会导致与使 Popen
命令对 STDIN
、[=35= 使用 subprocess.PIPE
有关的事情发生死锁],以及 STDERR
。它还要求将输入编码为 bytes-like
对象,我已经完成了,但是当我在最后发送 \r\n\r\n
以尝试关闭连接时,它什么也没做, STDOUT
只包含 b''
我理解为 bytes
对于遇到类似问题的任何人,这是我找到的解决方案:
#begin the interactive shell of netcat
proc = Popen(['netcat -q -1 {} {}'.format(host, port)], shell=True, stdout=PIPE, stdin=PIPE, stderr=PIPE)
#set file status flags on stdout to non-blocking reads
fcntl.fcntl(proc.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
#each time we write a diffrent line to the interactive shell
#we need to flush the buffer just to be safe
#credit to http://nigelarmstrong.me/2015/04/python-subprocess/
proc.stdin.write(str.encode('GET %s HTTP/1.1\n' %(path+filename)))
proc.stdin.flush()
proc.stdin.write(str.encode('Host: {}\n'.format(host)))
proc.stdin.flush()
proc.stdin.write(str.encode('Connection: close\n'))
proc.stdin.flush()
proc.stdin.write(str.encode('\r\n\r\n'))
proc.stdin.flush()
#give the server time to respond
proc.wait()
#store the server response (which is bytes-like)
#attempting to decode it results in error since we're recieving data as a mix of text/image
serv_response = proc.stdout.read()