简体   繁体   中英

Return response code python HTTP header

I have python server serving cgi scripts,

I want to add status code to my response. I did,

try:
     cgi = CGI()     
     output = cgi.fire()
     print 'Content-Type text/json'
     print 'Status:200 success'
     print
     print json.dumps(output)     
 except:
     print 'Content-Type: text/json'
     print 'Status: 403 Forbidden'
     print
     print json.dumps({'msg':'error'})

But when I request the this script via dojo xhr request, I get 200 request status. Why is so?

Header

Request URL:http://192.168.2.72:8080/cgi-bin/cgi.py
Request Method:POST
Status Code:200 Script output follows 
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:125
Content-Type:application/x-www-form-urlencoded
Host:192.168.2.72:7999
Origin:http://192.168.2.72:7999
Pragma:no-cache
Referer:http://192.168.2.72:7999/home.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22
X-Requested-With:XMLHttpRequest
Form Dataview sourceview URL encoded    
Response Headersview source
Content-Type:text/json
Date:Fri, 08 Aug 2014 05:16:29 GMT
Server:SimpleHTTP/0.6 Python/2.7.3
Status:403 Forbidden 

Any inputs?

what I already have tried:

result.ioArgs.xhr.getAllResponseHeaders() // returns string
ioargs.xhr.status // returns the request status.

If json.dumps(output) raises an exception, you will have already printed your headers including status code (generally would be spelled as Status: 200 OK ) and a blank line to end the header section of the HTTP response.

Then, the except block will print a second set of headers, but those are actually considered part of the body of the response at that point because printing an empty line ended the headers. See the HTTP message spec.

The solution is to wait until you know what your output is going to be to print any headers.

-more-

json.dumps can raise exceptions if you give it input that is not serializable. And given that cgi.fire() appears to be a method of some custom CGI object (builtin cgi module doesn't have that method) it could be returning anything.

To debug you need to log what exception is being raised, preferably with traceback. The bare except: block you have will catch all errors and then do nothing with them, so you don't know what's going on, nor does anyone looking at the question. You might also need to log the value of output .

To complement what Jason S says I reproduced exactly in his answer I reproduced the exactly same failure with a non json serializable object (in this example a md5 hash) and have the same behaviour than original poster a 200 return code

#!/usr/bin/env python

import json
import traceback
class CGI:
     def fire(self):
          import md5
          return md5.md5()
try:
     cgi = CGI()     

     output = cgi.fire()
     print 'Content-Type text/json'
     print 'Status:200 success'
     print
     print json.dumps(output)     
except:
     traceback.print_exc()
     print 'Content-Type: text/json'
     print 'Status: 403 Forbidden'
     print
     print json.dumps({'msg':'error'})

interacting with the server

$ socat - TCP4:localhost:8000 

input

GET /cgi-bin/test.py HTTP/1.0

output

HTTP/1.0 200 Script output follows
Server: SimpleHTTP/0.6 Python/3.4.0
Date: Sun, 17 Aug 2014 16:16:19 GMT
Content-Type text/json
Status:200 success

Content-Type: text/json
Status: 403 Forbidden

{"msg": "error"}

traceback:

127.0.0.1 - - [17/Aug/2014 18:16:19] "GET /cgi-bin/test.py HTTP/1.0" 200 -
Traceback (most recent call last):
  File "/home/xcombelle/dev/test/cgi-bin/test.py", line 16, in <module>
    print json.dumps(output)
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 263, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 177, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <md5 HASH object @ 0x7fcb090d0a30> is not JSON serializable

just do json.dumps() to a string before outputting your headers and you should be fine no?

that will protect you from setting headers and then getting an exception as exception in print is unlikely

It looks to me like you are setting a Status: header field but you want to set Status-Code: .

Does your script really write Status Code:200 Script output follows as a header field?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM