我正在运行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 u.path规范之前将GET请求发送到www.google.com 。 我知道这是因为两个原因。 首先,就在服务器响应进来之前,我得到以下内容:
/bin/sh: 1: Host:: not found /bin/sh: 1: Connection:: not found
其次,我知道图像数据的服务器响应是一堆丑陋的东西,它被解释为终端上奇怪的Unicode符号,但我明显在服务器响应中获得了www.google.com HTML文本。
我想我可能需要等待直到netcat STDIN打开时才进行HTTP请求,但我不知道如何。 或者它可能只是完成了请求,因为它发送了\n某种程度上? 我真的不知道。
编辑:它似乎实际上不是将请求发送到www.google.com 。 我将服务器响应保存为.html文件,它看起来像一个云端站点
编辑2:经过更多的研究,似乎问题是,因为netcat是互动的,所以它“僵局”或类似的东西。 我试图使用proc.communicate()但由于我需要发送多行,它不允许它看到communicate只允许将初始输入写入STDIN ,然后它发送EOF或沿着这些行的东西。 这导致我尝试使用proc.stdin.write但显然也知道会导致与使Popen命令对STDIN , STDOUT和STDERR使用proc.stdin.write相关的事件造成死锁。 它还要求输入被编码为类似bytes-like对象,我已经完成但是当我发送\r\n\r\n结束时尝试关闭连接它没有做任何事情和STDOUT只是包含b'' ,我理解为bytes形式的空字符串
I'm running Ubuntu 16.04 and I'm trying to write a python script that makes a GET request to a specified image file given the url. As an example, in the code below:
host is www.google.com
port is 80
u.path is /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)My problem is that I can execute these normally in the terminal, but when I try to run the script it seems like sends the GET request to www.google.com before it takes the specification of u.path. I know it is doing this for two reasons. First, just before the server response comes in I get the following:
/bin/sh: 1: Host:: not found /bin/sh: 1: Connection:: not found
Second, I know that the server response of the image data is a bunch of ugly stuff interpreted as weird Unicode symbols on the terminal, but I'm clearly getting the www.google.com HTML text on the server response.
I was thinking I may need to make it wait to do the HTTP request until the netcat STDIN is open, but I don't know how. Or maybe it's just completing the request because it's sending a \n somehow? I really don't know.
EDIT: It seems like it actually isn't sending the request to www.google.com. I saved the server response as a .html file and it looks like a cloudfront website
EDIT2: After more research, it seems as if the problem is that since netcat is interactive and so it 'deadlocks' or something like that. I tried to use proc.communicate() but since I need to send multiple lines it doesn't allow it seeing as communicate only allows the initial input to be written to STDIN and then it sends EOF or something along those lines. This led me to trying to use proc.stdin.write but this is apparently also known to cause deadlock with something related to making the Popen commands use subprocess.PIPE for STDIN, STDOUT, and STDERR. It also requires the input to be encoded as a bytes-like object, which I have done but when I send \r\n\r\n at the end to try to close the connection it doesn't do anything and the STDOUT just contains b'' which I understand to be an empty string in the form of 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()For anyone that has a similar problem, here is the solution that I found:
#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()更多推荐
发布评论