I was wondering is someone could help me figure out why I keep getting the error AssertionError: Header names/values must be of type str (got b'Content-type')
127.0.0.1 - - [26/Mar/2015 20:50:52] "GET /favicon.ico HTTP/1.1" 500 59. The code comes from "The Quick Python Book" from Manning publishing.
from wsgiref.simple_server import make_server
def message_wall_app(environ, start_response):
status = b'200 OK' # HTTP Status
headers = [(b'Content-type', b'text/html; charset=utf-8')]
start_response(status, headers)
# The returned object is going to be printed
return ["<h1>Message Wall</h1>"]
httpd = make_server('', 8000, message_wall_app)
print("Serving on port 8000...")
# Serve until process is killed
httpd.serve_forever()
Remove the b's from:
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/html; charset=utf-8')]
And add to return ["<h1>Message Wall</h1>"]. You read unicode/str and write bytes.
The old docs had a bug where the examples used b'200 OK' etc.. which is what the book may have been based on, there is an old bug report here. The current docs show the correct usage.
Once you do that you will see the output at http://localhost:8000/ and without error.
Related
interested in how to make a redirect in a simple WSGI app.
I try so:
def some_functions(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html'), ('Location', 'http://some_page')])
return []
But it doesn't work.
Must make a "return" without it not working, but that the return don't understand.
Tell me what I'm doing wrong?
You'll need to specify a 3xx HTTP response code. For example, you can use 302 Found to tell the client to visit the Location you provided.
Your code then becomes:
def some_functions(environ, start_response):
start_response('302 Found', [('Location', 'http://some_page')])
return []
You are right that you do need to return something. The return [] line works fine here, since there isn't a request body to be returned. Normally, a WSGI app should return a list of bytes, and technically [] is just an empty list of bytes.
On that note, you also don't need to provide a Content-Type, since there is no content being returned. The only thing needed to be sent to the client is the redirect information.
I am trying to find the dead URLS on a website I'm testing, but I am having some issues. I'm testing them by getting the reverse of the namespace:name with the appropriate args input and sending that to the code below. It is possible, but I do not think the issue lies in the reverse of the links as they match the url of the localhost. I thought the code below would work as it returns the links' status code as a 302 redirect.
def __init__(self, links):
self.client = Client()
self.links = links
def test_responses(self):
for l in self.links: # Where links are all the formatted links
response = self.client.get(l)
print response.status_code, l
However, the more I pry the more it seams that this is not the case. If I pass the arguments directly into the links that are correct, as tested in my localhost server test site then it still prints a 302, however on the site it is a 200
302 /contacts/organizations/show/123/ # Terminal output
[10/Feb/2016 10:23:10] "GET /contacts/people/show/123/ HTTP/1.1" 200 5039 # apache localhost output
Conversely, if I lead a page to a 404 on the localhost, it still shows up as a 302 in the code's output.
302 /contacts/organizations/show/10000/
[10/Feb/2016 10:25:32] "GET /contacts/people/show/10000/ HTTP/1.1" 404 846
Why is it not printing out the expected code? and what tips/tricks/ideas could I implement that would fix this issue?
Hi I'm trying to get an ajax response from a wsgi server behind nginx (if that matters). I think I'm having issues reading the request as it would seem the variable request_body_size is always 0; I get a return value of "No Request" in the alert box when I would like to see "test string".
I cant find many docs on this or examples of this working, so if anyone knows how to fix this I would be grateful.
I have this python code in the WSGI script:
import os, sys
from cgi import parse_qs
def application(environ, start_response):
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
context = {}
if request_body_size != 0:
request_body = environ['wsgi.input'].read(request_body_size)
output = parse_qs(request_body)
else:
output = "No request"
status = '200 OK'
response_headers = [('Content-type', 'text/html'),('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
and this is the js making the request (jquery):
function test_request()
{
var test_string = "test string";
$.ajax({
type: 'GET',
url:"/ajax",
data: test_string,
success:function(result){alert(result)}}
);
}
The ajax() method converts the 'data' value to a QUERY_STRING when the method is GET. Using POST should address the issue (or you can read environ['QUERY_STRING'])
I have one simple program of wsgi.
from wsgiref.simple_server import make_server
import time
def application(environ, start_response):
response_body = 'Hello World'
status = '200 OK'
response_headers = [('Content-Type', 'text/plain'),
('Content-Length', str(len(response_body)))]
start_response(status, response_headers)
if environ['PATH_INFO'] != '/favicon.ico':
print "Time :", int(time.time())
if int(time.time()) % 2:
print "Even"
time.sleep(10)
else:
print "Odd"
return [response_body]
httpd = make_server('localhost', 8000, application)
httpd.serve_forever()
So as per the code if the timestamp is Even then it will send response after 10 second. But if the timestamp is Odd then it will send response directly without sleep.
So my question is if i will send 2 request and if first request will send the request in Even mode then my second request will be serve after completing first one.
I check the solution and found that 'multiprocesscan solve this problem. I set the apache configuration withmultiprocess. Then I get the response forOddwithout completingEven` request.
I check how to set the multiprocess with make_server method of simple_server module. When I run the python /usr/lib64/python2.7/wsgiref/simple_server.py I get the output and last few lines are
wsgi.errors = <open file '<stderr>', mode 'w' at 0x7f22ba2a1270>
wsgi.file_wrapper = <class wsgiref.util.FileWrapper at 0x1647600>
wsgi.input = <socket._fileobject object at 0x1569cd0>
wsgi.multiprocess = False
wsgi.multithread = True
wsgi.run_once = False
wsgi.url_scheme = 'http'
wsgi.version = (1, 0)
So I was search how to set this make_server multiprocess so make_server can handle more then 1 request if any request is in progress.
Thx in advance.
If you're using Apache/mod_wsgi than you don't need the make_server/serve_forever stuff. Apache will handle that for you (as it is the web server). It will handle the processes and run the application callback function.
Make sure your Apache and mod_wsgi configuration allows multiprocess/multithread. Good reference is available here
Is it possible for CherryPy to redirect HTTP to HTTPS. Lets for example say the code below is http://example.com if someone visits via https://example.com I want them to be redirected to the plain HTTP URL (301 redirect maybe?) how do I accomplish this?
#!/usr/bin/env python
from pprint import pformat
from cherrypy import wsgiserver
def app(environ, start_response):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return [pformat(environ)]
server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 80), app)
try:
server.start()
except KeyboardInterrupt:
server.stop()
You can check the request.scheme if it is "https" then you can raise a redirect.
See https://github.com/cherrypy/cherrypy/blob/f185ecd005d7fdbafb0ed83b0e49f05ac76e43fd/cherrypy/_cprequest.py#L218
Andrew Cox's link is broken again, here's the updated link to it. I don't have enough points to comment on his answer, hence the new answer.
https://cherrypy.readthedocs.org/en/3.3.0/refman/_cprequest.html#cherrypy._cprequest.Request.scheme