我正在运行Ubuntu 16.04并且我正在尝试编写一个python脚本,该脚本在给定url的情况下向指定的图像文件发出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文本。 / p>
我想我可能需要让它等待HTTP请求,直到netcat
STDIN打开,但我不知道如何。或者它可能只是完成请求,因为它以某种方式发送\n
?我真的不知道。
编辑:好像它实际上没有将请求发送给www.google.com
。我将服务器响应保存为.html
文件,它看起来像一个云端网站
EDIT2:经过更多的研究,似乎问题是因为netcat是交互式的,所以它“死锁”或类似的东西。我尝试使用proc.communicate()
,但由于我需要发送多行,因此不允许它看到communicate
只允许将初始输入写入STDIN
,然后发送{{ 1}}或沿着这些方向的东西。这导致我尝试使用EOF
,但这显然也会导致与proc.stdin.write
命令使用Popen
subprocess.PIPE
STDIN
相关的问题导致死锁,{{1} }和STDOUT
。它还要求输入被编码为STDERR
对象,我已经完成但是当我在末尾发送bytes-like
以尝试关闭连接时它不会执行任何操作而{{1只包含\r\n\r\n
,我理解为STDOUT
答案 0 :(得分:0)
对于有类似问题的人,我找到了解决方案:
#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()