> Hi;
> I have the following archaic code that worked just fine for another
> site. It
> is called with the following url:
>
> http://13gems.com/stxresort/cart/getpic1.py?id=1&x=1
>
> #!/usr/local/bin/python
> import cgitb; cgitb.enable()
> import MySQLdb
> import cgi
> import sys,os
> sys.path.append(os.getcwd())
> from login import login
> user, passwd, db, host = login()
> form = cgi.FieldStorage()
> picid = int(form['id'].value)
> x = int(form['x'].value)
> pics = {1:'pic1',2:'pic2',3:'pic3',4:'pic4',5:'pic5',6:'pic6'}
> pic = pics[x]
> print 'Content-Type: text/html'
^^^ I believe this is the problem line. It's telling the browser to expect
HTML, not an image. Remove this, and the later Content-Type header that's
being printed ("Content-Type: image/jpeg") should take effect.
--
Rami Chowdhury
"Never attribute to malice that which can be attributed to stupidity" --
Hanlon's Razor
408-597-7068 (US) / 07875-841-046 (UK) / 0189-245544 (BD)
> I remember going round and round on this issue before until I finally
> got it
> right. I haven't changed the code. It worked before. I just tried your
> update and it gave me the same result :( Any other ideas?
> TIA,
> V
>
I'm afraid changing the 'Content-type' header to be correct (which it's
still not, by the way; you need to be printing '\r\n\r\n' after the
content-type, to signal the end of the headers) is all I can think of.
Apart from that, could it be a browser issue? When I went to the URL you
provided in your first email, for instance, my browser (Opera 9.6 on
Windows Vista) was expecting an image, as was Firefox 3.1 (again on
Windows). However, neither seem to read valid data for the image, and both
report it as 0x0.
Could you give us more information on what has changed? Have you upgraded
the version of Python on the server? Have you changed the webserver
serving your scripts? Have you changed the back-end database at all?
> The code in question is generated automatically from another script. I
> took
> your idea of the \r\n\r\n and added triple quoting and now it prints out
> this:
>
> #!/usr/local/bin/python
> import cgitb; cgitb.enable()
> import MySQLdb
> import cgi
> import sys,os
> sys.path.append(os.getcwd())
> from login import login
> user, passwd, db, host = login()
> form = cgi.FieldStorage()
> picid = int(form['id'].value)
> x = int(form['x'].value)
> pics = {1:'pic1',2:'pic2',3:'pic3',4:'pic4',5:'pic5',6:'pic6'}
> pic = pics[x]
> print '''Content-Type: text/html
>
> '''
> db = MySQLdb.connect(host=host, user=user, passwd=passwd, db=db)
> cursor= db.cursor()
> sql = "select " + pic + " from products where id='" + str(picid) + "';"
> cursor.execute(sql)
> content = cursor.fetchall()[0][0].tostring()
> cursor.close()
> print '''Content-Type: image/jpeg
>
> '''
> print
> print content
>
>
> To answer your questions, I have no idea what eNom has done to their
> servers, which is where the other site was hosted (never went live), but
> am
> in the process of building on DreamHost, who seems to be a FAR better
> service than eNom, whom I actually had to report to the BBB and they
> never
> fixed or acknowledged very obvious problems. At any rate, the above code
> gets the browser to print out all the binary "garbage" that should
> translate
> into an image (you can look:
> http://13gems.com/stxresort/cart/getpic1.py?id=1&x=1 ). Any more ideas
> would
> be helpful.
Going to that URL, my browser now tries to render an HTML page, and I can
now see the 'Content-Type: image/jpeg' string being printed into the HTML
source. Have you tried removing the 'Content-Type: text/html' header, with
the new triple-quoted syntax?
> The code in question is generated automatically from another script. I
> took
> your idea of the \r\n\r\n and added triple quoting and now it prints out
> this:
That's still wrong. The output should be:
- a line containing Content-Type: image/jpeg
- a blank line (no more!)
- the actual image data
A Content-Type of text/html is just *wrong* for an image...
--
Gabriel Genellina
> I took out the line in question (with text/html). Now it prints to screen
> the url. It did that before. Strange. Any other ideas?
> TIA,
> V
Looking at the output, it seems the reason for this (for me) is that
Firefox can't find the image or any alt text for it, so it's just using
the image URL. Are you certain the image data (i.e. the 'content' string)
is correct, and being encoded correctly in the output?
>
> On Tue, Oct 6, 2009 at 3:40 PM, Rami Chowdhury
> <rami.ch...@gmail.com>wrote:
>
>> On Tue, 06 Oct 2009 13:26:19 -0700, Victor Subervi <
>> victor...@gmail.com> wrote:
>>
>> The code in question is generated automatically from another script. I
>>> took
>>> your idea of the \r\n\r\n and added triple quoting and now it prints
>>> out
>>> this:
>>>
> Yes it is. I have had it print to screen already, and there is data in
> the
> database.
> V
If you're confident that the data is correct and hasn't been corrupted,
then I'm afraid I'm out of ideas. Perhaps you could try transmitting it as
base64, which might make it more robust in transmission and easier to
decode and find errors locally? You'd just need to change the end of your
script to read:
print '''Content-Type: image/jpeg
Content-Encoding: base64
'''
print
print content.encode('base64')
HTH,
Rami
>
> On Wed, Oct 7, 2009 at 10:03 AM, Rami Chowdhury
> Well, since the code is automatically generated, it printed this:
>
> #!/usr/local/bin/python
> import cgitb; cgitb.enable()
> import MySQLdb
> import cgi
> import sys,os
> sys.path.append(os.getcwd())
> from login import login
> user, passwd, db, host = login()
> form = cgi.FieldStorage()
> picid = int(form['id'].value)
> x = int(form['x'].value)
> pics = {1:'pic1',2:'pic2',3:'pic3',4:'pic4',5:'pic5',6:'pic6'}
> pic = pics[x]
> db = MySQLdb.connect(host=host, user=user, passwd=passwd, db=db)
> cursor= db.cursor()
> sql = "select " + pic + " from products where id='" + str(picid) + "';"
> cursor.execute(sql)
> content = cursor.fetchall()[0][0].tostring()
> cursor.close()
> print '''Content-Type: image/jpeg
>
> '''
> Content-Encoding: base64
> print
> print content.encode('base64')
>
> which threw this error:
>
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: Traceback (most recent call last):
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: File
> "/usr/lib64/python2.4/site-packages/mod_python/apache.py", line 299, in
> HandlerDispatch\n result = object(req)
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: File
> "/usr/lib64/python2.4/site-packages/mod_python/cgihandler.py", line 96,
> in
> handler\n imp.load_module(module_name, fd, path, desc)
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: File "/var/www/vhosts/
> 13gems.com/httpdocs/stxresort/cart/getpic1.py", line 24
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: Content-Encoding: base64
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: ^
> [Wed Oct 07 10:47:42 2009] [error] [client 66.248.168.98] PythonHandler
> mod_python.cgihandler: SyntaxError: invalid syntax
>
> Ideas? TIA,
> V
>
I'm sorry, I don't understand how the code is being auto-generated? Is
there no way to place the 'Content-Encoding' header inside the
triple-quoted string, where it should go?
> My misunderstanding. Here's the new code:
>
> print '''Content-Type: image/jpeg
>
>
> Content-Encoding: base64
> '''
Ah, sorry, I wasn't clear -- Content-Encoding is a header, and needs to go
with Content-Type, before the newlines. So
print '''Content-Type: image/jpeg
Content-Encoding: base64
'''
HTH,
Rami
>
>
> On Wed, Oct 7, 2009 at 12:56 PM, Rami Chowdhury
> <rami.ch...@gmail.com>wrote:
>
> print '''Content-Type: image/jpeg
>
> '''
> print
> print content
On Wed, Oct 7, 2009 at 9:51 AM, Gabriel Genellina <gagsl-
p...@yahoo.com.ar>wrote:
> That's still wrong. The output should be:
>
> - a line containing Content-Type: image/jpeg
> - a blank line (no more!)
^^^^^^^^^^^^^^^^^^^^^^^^^
> - the actual image data
--
Gabriel Genellina
You have a spurious blank line between those header lines.
HTH,
--
Carsten Haese
http://informixdb.sourceforge.net
> I did that. In fact, just to make things easier, I wrote out exactly
> what is
> supposed to be rendered, as below:
>
> #!/usr/local/bin/python
> import cgitb; cgitb.enable()
> import MySQLdb
> import cgi
> import sys,os
> sys.path.append(os.getcwd())
> from login import login
> user, passwd, db, host = login()
> form = cgi.FieldStorage()
> db = MySQLdb.connect(host, user, passwd, db)
> cursor= db.cursor()
> sql = "select pic1 from products where id='1';"
> cursor.execute(sql)
> content = cursor.fetchall()[0][0].tostring()
> cursor.close()
> print '''Content-Type: image/jpeg''' # Only print one line
>
> Content-Encoding: base64
> '''
> print
> print content.encode('base64')
>
Just to reiterate what Gabriel and Carsten have pointed out, I'd suggest
changing the last few lines of the script, as the comments below indicate:
print '''Content-Type: image/jpeg''' # One header line
print '''Content-Encoding: base64''' # Another header line. Note *no*
blank line between them
print # Blank line signals the end of the headers
print content.encode(base64) # Base64-encoded content comes *after*
the blank line
If you include extra blank lines after the headers, the browser will
misunderstand where the binary image data begins, and so will see a
malformed JPEG.
If this doesn't work, I suggest changing the content-type header to
text/plain and trying to manually decode and check the image data to
ensure it's valid.
>
> On Wed, Oct 7, 2009 at 2:47 PM, Gabriel Genellina
> <gags...@yahoo.com.ar>wrote:
>> --
>> http://mail.python.org/mailman/listinfo/python-list
> print 'Content-Type: image/jpeg'
> print 'Content-Encoding: base64'
> print
> print content.encode('base64')
>
> I did change it to text/plain, but I don't know how I'm supposed to
> manually
> decode it. Yes, it printed out a bunch of crap to the screen. I've gotten
> that far before, and once I read "Adobe" something, so yes, it's an
> image.
> TIA,
> V
>
Hopefully the 'crap' you're getting is the base64-encoded representation
of your binary image -- you should be able to use Python to decode that,
and then use any image viewer to verify that the JPEG is sound.
Can you remind us of the URL where that code (with the text/plain content
type) is running?
> On Wed, Oct 7, 2009 at 3:52 PM, Rami Chowdhury
> <rami.ch...@gmail.com>wrote:
>
> http://13gems.com/stxresort/cart/getpic1.py?id=1&x=1
>
> On Wed, Oct 7, 2009 at 4:11 PM, Rami Chowdhury
> <rami.ch...@gmail.com>wrote:
>
>> On Wed, 07 Oct 2009 14:05:25 -0700, Victor Subervi <
>> victor...@gmail.com> wrote:
>>
>> print 'Content-Type: image/jpeg'
>>> print 'Content-Encoding: base64'
>>> print
>>> print content.encode('base64')
Are you sure this is your actual code?
py> import urllib
py> data =
urllib.urlopen("http://13gems.com/stxresort/cart/getpic1.py?id=1&x=1").read()
py> data[:30]
'Content-Encoding: base64\n\n\n/9j'
py> data[-30:]
'XdjTJvaaF5fvfMVgbUM+gatZXFzb\n\n'
1) The Content-Encoding line is taken as part of the response entity (the
picture data), but should be part of the header. I bet you have a blank
line after Content-Type.
2) Note the \n\n at the end
py> data = data[27:-2]
py> decoded = data.decode("base64")
py> open("test.jpg","wb").write(decoded)
I tried to open test.jpg, but it's corrupt.
py> len(decoded)
65535
py> decoded[:30]
'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x02\x01\x00H\x00H\x00\x00\xff\xe1
\xadExif\x00\x00'
Very suspicious file size... Looks like a jpeg image that was truncated at
that size. See whether it is already corrupt in the database and repair it
(you're using a data type large enough to hold the image, aren't you?)
After fixing the database, you can omit the unnecesary base64 encoding;
anyway I'd add a Content-Length header to avoid that spurious \n at the
end.
--
Gabriel Genellina