Skip to content

Commit

Permalink
Adds CONTENT_LENGTH & CONTENT_TYPE so that post requests work correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
tomdottom committed May 25, 2018
1 parent 36843c4 commit cc4015f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
21 changes: 21 additions & 0 deletions tests/test_curl.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from copy import deepcopy
import socket
import unittest
from uwsgi_tools.curl import cli
Expand All @@ -22,3 +23,23 @@ def test_file_socket(self):
def test_headers(self):
with server(callback=lambda x: self.assertIn(b'localhost', x)):
self.assertFalse(cli('127.0.0.1:3030', '-H', 'Host: localhost'))

def test_post(self):
requests = []

def request_sniper(x):
requests.append(deepcopy(x))

with server(callback=request_sniper):
self.assertFalse(cli(
'--method', 'POST',
'--header', 'Content-Type: application/json',
r'''--data=\'{"foo":"bar"}\'''',
'127.0.0.1',
'host.name/'))

self.assertIn(b'POST', requests[0])
# Magic number is the val_size + val
self.assertIn(b'CONTENT_LENGTH\x02\x0017', requests[0])
self.assertIn(b'CONTENT_TYPE', requests[0])
self.assertIn(b'application/json', requests[0])
21 changes: 16 additions & 5 deletions uwsgi_tools/curl.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ def ask_uwsgi(uwsgi_addr, var, body='', timeout=0, udp=False):
if timeout:
s.settimeout(timeout)

if body is None:
body = ''

s.connect(addr)
s.send(pack_uwsgi_vars(var) + body.encode('utf8'))
s.send(pack_uwsgi_vars(var) + body)
response = []
while 1:
data = s.recv(4096)
Expand All @@ -45,17 +42,31 @@ def curl(uwsgi_addr, url, method='GET', body='', timeout=0, headers=(),
else:
port = None

body = (body or '').encode('utf-8')

var = {
'SERVER_PROTOCOL': 'HTTP/1.1',
'PATH_INFO': parts_uri.path,
'REQUEST_METHOD': method.upper(),
'REQUEST_URI': uri,
'QUERY_STRING': parts_uri.query,
'HTTP_HOST': host,
'CONTENT_LENGTH': str(len(body)),
# Other varaibles seen in nginx's uwsgi_params file but not explicitly
# handled anywhere in this file
# https://github.com/nginx/nginx/blob/master/conf/uwsgi_params
# DOCUMENT_ROOT
# REQUEST_SCHEME
# HTTPS
# REMOTE_ADDR
# REMOTE_PORT
}

for header in headers or ():
key, _, value = header.partition(':')
var['HTTP_' + key.strip().upper()] = value.strip()
var['HTTP_' + key.strip().upper().replace('-', '_')] = value.strip()
if 'HTTP_CONTENT_TYPE' in var.keys():
var['CONTENT_TYPE'] = var['HTTP_CONTENT_TYPE']
var['SERVER_NAME'] = var['HTTP_HOST']
if port:
var['SERVER_PORT'] = str(port)
Expand Down
2 changes: 1 addition & 1 deletion uwsgi_tools/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def do(self):
env.pop('HTTP_REFERER', 0)

cl = env['CONTENT_LENGTH']
body = repr(self.rfile.read(int(cl))) if cl else ''
body = (repr(self.rfile.read(int(cl))) if cl else '').encode('utf-8')

resp = ask_uwsgi((self.server.uwsgi_addr, self.server.uwsgi_port),
var=env, body=body)
Expand Down

0 comments on commit cc4015f

Please sign in to comment.