BaseHTTPRequestHandler delays server response after "Popen"ing a program that waits for user input? (getline, fgets, etc.)

gburdell1 at gmail.com gburdell1 at gmail.com
Thu Apr 16 22:52:06 CEST 2009


I'm trying to write a very simple HTTP client/server program where the
client uploads a file via PUT using pycurl, and the server accepts the
file, "POpen"s a program, sends back "HELLO" to the client, then
displays "good morning".

The problem is when the "POpen"ed C++ program (test1.cpp below) waits
for some user input (via "getline()"; same thing happens with gets(),
fgets()). In this case, the "good morning" message stills get printed
on the server side, but the client doesn't get back "HELLO."

If the server program is terminated (by pressing ctrl-c), or a long
time (a few minutes?) passes, the client receives the "HELLO".

If the "POpen" program does not wait for user input (test2.cpp below),
the client immediately receives HELLO as expected.

Could this have anything to do with the getline() somehow blocking the
server response, even though it is POpened as a separate thread? How
can I solve this problem?

George.


******************************************
server.py on server
******************************************
#!/usr/bin/python
from subprocess import Popen, PIPE, STDOUT
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
class Handler(BaseHTTPRequestHandler):
        #-------------------- HTTP Server Methods
--------------------------
        def do_PUT(self):
                #print self.headers
                length = int(self.headers.getheader('Content-Length'))
                print 'Received PUT command, file length %d' % length
                raw = self.rfile.read(length)
                serverObj = Popen('./test1', stdin=PIPE, stdout=PIPE,
stderr=STDOUT)    # Try replace test1 with test2
                while True:
                        line = serverObj.stdout.readline()
                        print line,
                        if line.startswith('TYPE SOMETHING'):
                                break
                self.wfile.write('HELLO!!!')
                print 'good morning'
server = HTTPServer(('', 58621), Handler)
server.serve_forever()

******************************************
test1.cpp on server:
******************************************
#include <iostream>
using namespace std;
int main()
{
        char string[256];
        cout << "This is a test program" << endl;
        cout << "TYPE SOMETHING" << endl;
        cin.getline (string,256);
        return 0;
}

******************************************
test2.cpp on server:
******************************************
#include <iostream>
using namespace std;
int main()
{
        cout << "This is a test program" << endl;
        cout << "TYPE SOMETHING" << endl;
        return 0;
}

******************************************
client.py on client:
******************************************
#!/usr/bin/python
import os, sys
import pycurl
url = 'xxxxxxxxxxx'
class textBuffer:
	def __init__(self):
		self.contents = ''
	def write(self, buf):
		self.contents = self.contents+buf
# Initialize rawFileUploader, which uploads raw file and requests s2t
rawFileUploader = pycurl.Curl()
rawFileUploader.setopt(pycurl.URL, url)
rawFileUploader.setopt(pycurl.UPLOAD, 1)
while 1:
	filename = raw_input('Enter filename (CTRL-C to quit)>')
	rawFile = open(filename,'rb')
	text = textBuffer()
	rawFileUploader.setopt(pycurl.READDATA, rawFile)
	rawFileUploader.setopt(pycurl.WRITEFUNCTION, text.write)
	rawFileUploader.setopt(pycurl.INFILESIZE, os.path.getsize(filename))
	rawFileUploader.perform()
	rawFile.close()
	print text.contents
rawFileUploader.close()




More information about the Python-list mailing list