I am attempting to write a Python CGI script which will call sox (a sound processing program) using subprocess. However , after i get errors in the sox call, everything crashes and that i obtain a "malformed header" error from Apache.

The appropriate bits:

def downsample(in_file, in_location, sox, out_location):
  """ run sox """
...
  sox = shlex.split(sox)
  retcode = subprocess.check_call(sox)
  if not retcode == 0:
    print '<b>something went wrong in sox: returned error code ' +\
          retcode + ', but we are continuing anyway...</b>'
  """p = subprocess.Popen(sox)
  if p.stdout:
    print '<b>something happened in sox: returned ' +\
          p.stdout.read() + ', but we will keep going...</b>'
  if p.stderr:
    print '<b>something happened in sox: returned ' +\
          p.stderr.read() + ', but we will keep going...</b>'"""
...

def main():
  print "Content-Type: text/html\n\n"

...
    downsample(in_file, in_location, command, out_location)
...

if __name__ == '__main__':
  main()

I am using check_call to permit the cgi error handler to print the stack trace at this time (to prevent the 500 page), but I'd enjoy to trap the mistake, handle it myself, and keep the script. I attempted doing that by wrapping the check_get in touch with an attempt: except CalledProcessError: statement, but that simply brought towards the 500 page again. That part that's said out does not work with me, either.

And from /var/www/apache2/error_log:

Wed Apr 13 10:08:21 2011] [error] [client ::1] sox FAIL formats: can't open input file `/tmp/wavs/haha/f.wav': WAVE: RIFF header not found, referer: http://localhost/~Valkyrie_savage/
[Wed Apr 13 10:08:21 2011] [error] [client ::1] malformed header from script. Bad header=\x1f\x8b\b: downsample.py, referer: http://localhost/~Valkyrie_savage/

I can not realise why it appears to become running the sox command before the header prints. Or, if it's, how come it the header is malformed?

import subprocess
p = subprocess.Popen(cmd)  
   p.wait()  
   if p.returncode:  
      print "failed with code: %s" % str(p.returncode) 

You should use subprocess.check_call and catch the CalledProcessError exception.

try:
    retcode = subprocess.check_call(sox)
except CalledProcessError:
    print '<b>something went wrong in sox: returned error code ' +\
      retcode + ', but we are continuing anyway...</b>'

It may sound as if you are utilizing buffered output.

If that's the situation, the output in the command is printed before the HTTP headers, therefore the internet browser will get confused.

You are able to call sys.stdout.flush() before doing the machine call, to be certain all of the headers and html within the output buffer is really printed.

Hope this can help.