views:

33

answers:

1

Hello,

I have been struggling for a couple hours now with serving jpg's with a python cgi site. For some reason the images always come out distorted.

Here is my code:

print('Content-type: image/jpg\n')
path = 'C:\\Users\\Admin\\Documents\\image.jpg'
print file(path, 'rb').read()

This post describes a nearly identical problem, however I am not using WSGI. I am using windows and apache and have played around with \r\n\r\n as well as print 'Content-type: image/jpg\r\n\r\n',. Similarly I have tried print file(path, 'rb').read(), thinking that a new line might be distorting the image somehow.

Any more troubleshooting ideas?

Thanks, Josh

ps. The site must remain a cgi site.

[edit] changed to print('Content-type: image/jpeg\n')

[edit] example image: alt text

+1  A: 

This article shows sending a file to CGI using C++. The program takes some care to convert stdout to binary:

int main()
{
#if _WIN32
    // Standard I/O is in text mode by default; since we intend
    // to send binary image data to standard output, we have to
    // set it to binary mode.
    // Error handling is tricky to say the least, so we have none.
    _fmode = _O_BINARY;
    if (_setmode(_fileno(stdin), _fmode) == -1) {}
    if (_setmode(_fileno(stdout), _fmode) == -1) {}
#endif

You could do this in python. Here is a Windows-specific solution:

import sys

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

Here is code specific to python 3.x:

The standard streams are in text mode by default. To write or read binary data to these, use the underlying binary buffer. For example, to write bytes to stdout, use sys.stdout.buffer.write(b'abc'). Using io.TextIOBase.detach() streams can be made binary by default. This function sets stdin and stdout to binary:

def make_streams_binary():
    sys.stdin = sys.stdin.detach()
    sys.stdout = sys.stdout.detach()

Later: I also think that you should be able to UU64-encode your jpeg and send it over the wire as text with an appropriate content-length and content-type, but I've never done HTTP at this level. You'd have to look it up.

hughdbrown