# Path: nudge/publisher.py
# class WSGIRequest(object):
# 
#     def __init__(self, req_dict):
#         # Should we use dictomatic here? (tiny slowdown)
#         # REVIEW: From the following items, it feels like we can remove the Dictomatic wrapper.
#         self.req = Dictomatic.wrap(req_dict)
#         self.start_time = time.time()
#         self.method = self.req.get('REQUEST_METHOD')
#         self.remote_ip = self.req.get('REMOTE_ADDR', self.req.get('HTTP_REMOTE_ADDR'))
#         self.body = self.req.get('wsgi.input').read()
#         self._buffer = ''
#         self.files = {}
# 
#     @lazyprop
#     def path(self):
#         return self.req['PATH_INFO']
# 
#     @lazyprop
#     def uri(self):
#         return '%s://%s%s' % (
#                 self.req['wsgi.url_scheme'],
#                 self.req['HTTP_HOST'],
#                 self.req['PATH_INFO']
#             )
# 
#     @lazyprop
#     def headers(self):
#         _headers = WSGIHeaders()
#         for k,v in self.req.iteritems():
#             if k.startswith('HTTP_'):
#                 _headers[k.replace('HTTP_', '').lower()] = v
#             elif k == 'CONTENT_TYPE':
#                 _headers['Content-Type'] = v
#         return _headers
# 
#     @lazyprop
#     def cookies(self):
#         ''' I am assuming it is valid to have multiple cookies with the same
#         name even though that seems silly.
# 
#         Also the individual cookies are split on the FIRST = so as to support
#         later = for unknown benefit.
# 
#         TODO - support/test with unicode?
#              - Maybe nuke the HTTP_COOKIE from regular headers?
#         '''
#         _cookies = {}
#         if 'HTTP_COOKIE' in self.req:
#             for cookie in self.req['HTTP_COOKIE'].split(';'):
#                 cookie = cookie.split('=')
#                 if len(cookie) < 2: # Empty values will still be >= 2
#                     continue
#                 if cookie[0] in _cookies:
#                     _cookies[cookie[0].strip()].append(
#                         '='.join(cookie[1:]).strip()
#                     )
#                 else:
#                     _cookies[cookie[0].strip()] = ['='.join(cookie[1:]).strip()]
#         return _cookies
# 
#     @lazyprop
#     def arguments(self):
#         _arguments = {}
#         _files = {}
#         try:
#             # First url decode
#             tmp = self.req.get('QUERY_STRING', '')
#             if tmp:
#                 # make sure to split before unquoting
#                 # to handle arg keys/values that contain & or =
#                 tmp = tmp.split('&')
#                 tmp = [a.split('=') for a in tmp]
#                 tmp = [map(urllib.unquote_plus, a) for a in tmp]
#                 # Consider making the unicode decoding type a Nudge option.
#                 tmp = [map(partial(unicode, encoding='utf-8'), a) for a in tmp]
#                 # Only keep args with k and v. f= will stay and be [u'f', u'']
#                 tmp = filter(lambda x: len(x) == 2, tmp)
#                 for k, v in tmp:
#                     if k in _arguments:
#                         _arguments[k].append(v)
#                     else:
#                         _arguments[k] = [v]
#         except (Exception), e:
#             _log.exception(
#                 "problem making arguments out of QUERY_STRING: %s",
#                 self.req['QUERY_STRING']
#             )
# 
#         if self.method in ('POST', 'PUT') and self.body:
#             content_type = self.headers.get("Content-Type", '')
#             # TODO make sure these come out as unicode
#             if content_type.startswith("application/x-www-form-urlencoded"):
#                 for name, values in cgi.parse_qs(self.body).iteritems():
#                     _arguments.setdefault(name, []).extend(values)
#             # multipart form
#             elif content_type.startswith("multipart/form-data"):
#                 try:
#                     fs = cgi.FieldStorage(
#                         fp=StringIO.StringIO(self.body),
#                         environ=self.req,
#                         keep_blank_values=1
#                     )
#                     for k in fs.keys():
#                         part = fs[k]
#                         if part.filename:
#                             _files[k] = part
#                         _arguments[k] = part.value
#                 except:
#                     _log.exception(
#                         "problem parsing multipart/form-data"
#                     )
#             # add any arguments from JSON body
#             elif content_type.startswith("application/json"):
#                 try:
#                     body = nudge.json.json_decode(self.body)
#                     if isinstance(body, types.DictType):
#                         _arguments = dict(_arguments, **body)
# 
#                 except (ValueError):
#                     raise HTTPException(400, "body is not JSON")
# 
#         self.files = _files
#         return _arguments
# 
#     def write(self, content):
#         self._buffer += content
# 
#     def request_time(self):
#         return time.time() - self.start_time


import unittest
import StringIO
from nudge.publisher import WSGIRequest
        print req.headers
        assert req.headers['X-Forwarded-For'] == '10.0.10.123'
        assert req.headers.get('X-Forwarded-For') == '10.0.10.123', req.headers.get('X-Forwarded-For')


    def test_xff_header_eventlet(self):
        input = StringIO.StringIO()
        req = WSGIRequest({
            'REQUEST_METHOD':'POST',
            'REMOTE_ADDR':'127.0.0.1',
            'wsgi.input': input,
            'HTTP_X_FORWARDED_FOR':'10.0.10.123',
        })
        print req.headers
        assert req.headers['X-Forwarded-For'] == '10.0.10.123'
        assert req.headers.get('X-Forwarded-For') == '10.0.10.123', req.headers.get('X-Forwarded-For')

    def test_request_files(self):
        input = StringIO.StringIO('''
-----------------------------41184676334
Content-Disposition: form-data; name="caption"

Summer vacation
-----------------------------41184676334
Content-Disposition: form-data; name="upload"; filename="extra_data.txt"
Content-Type: text/plain

Some more data about my vacation
-----------------------------41184676334--
''')

# Path: nudge/publisher.py
# class WSGIRequest(object):
# 
#     def __init__(self, req_dict):
#         # Should we use dictomatic here? (tiny slowdown)
#         # REVIEW: From the following items, it feels like we can remove the Dictomatic wrapper.
#         self.req = Dictomatic.wrap(req_dict)
#         self.start_time = time.time()
#         self.method = self.req.get('REQUEST_METHOD')
#         self.remote_ip = self.req.get('REMOTE_ADDR', self.req.get('HTTP_REMOTE_ADDR'))
#         self.body = self.req.get('wsgi.input').read()
#         self._buffer = ''
#         self.files = {}
# 
#     @lazyprop
#     def path(self):
#         return self.req['PATH_INFO']
# 
#     @lazyprop
#     def uri(self):
#         return '%s://%s%s' % (
#                 self.req['wsgi.url_scheme'],
#                 self.req['HTTP_HOST'],
#                 self.req['PATH_INFO']
#             )
# 
#     @lazyprop
#     def headers(self):
#         _headers = WSGIHeaders()
#         for k,v in self.req.iteritems():
#             if k.startswith('HTTP_'):
#                 _headers[k.replace('HTTP_', '').lower()] = v
#             elif k == 'CONTENT_TYPE':
#                 _headers['Content-Type'] = v
#         return _headers
# 
#     @lazyprop
#     def cookies(self):
#         ''' I am assuming it is valid to have multiple cookies with the same
#         name even though that seems silly.
# 
#         Also the individual cookies are split on the FIRST = so as to support
#         later = for unknown benefit.
# 
#         TODO - support/test with unicode?
#              - Maybe nuke the HTTP_COOKIE from regular headers?
#         '''
#         _cookies = {}
#         if 'HTTP_COOKIE' in self.req:
#             for cookie in self.req['HTTP_COOKIE'].split(';'):
#                 cookie = cookie.split('=')
#                 if len(cookie) < 2: # Empty values will still be >= 2
#                     continue
#                 if cookie[0] in _cookies:
#                     _cookies[cookie[0].strip()].append(
#                         '='.join(cookie[1:]).strip()
#                     )
#                 else:
#                     _cookies[cookie[0].strip()] = ['='.join(cookie[1:]).strip()]
#         return _cookies
# 
#     @lazyprop
#     def arguments(self):
#         _arguments = {}
#         _files = {}
#         try:
#             # First url decode
#             tmp = self.req.get('QUERY_STRING', '')
#             if tmp:
#                 # make sure to split before unquoting
#                 # to handle arg keys/values that contain & or =
#                 tmp = tmp.split('&')
#                 tmp = [a.split('=') for a in tmp]
#                 tmp = [map(urllib.unquote_plus, a) for a in tmp]
#                 # Consider making the unicode decoding type a Nudge option.
#                 tmp = [map(partial(unicode, encoding='utf-8'), a) for a in tmp]
#                 # Only keep args with k and v. f= will stay and be [u'f', u'']
#                 tmp = filter(lambda x: len(x) == 2, tmp)
#                 for k, v in tmp:
#                     if k in _arguments:
#                         _arguments[k].append(v)
#                     else:
#                         _arguments[k] = [v]
#         except (Exception), e:
#             _log.exception(
#                 "problem making arguments out of QUERY_STRING: %s",
#                 self.req['QUERY_STRING']
#             )
# 
#         if self.method in ('POST', 'PUT') and self.body:
#             content_type = self.headers.get("Content-Type", '')
#             # TODO make sure these come out as unicode
#             if content_type.startswith("application/x-www-form-urlencoded"):
#                 for name, values in cgi.parse_qs(self.body).iteritems():
#                     _arguments.setdefault(name, []).extend(values)
#             # multipart form
#             elif content_type.startswith("multipart/form-data"):
#                 try:
#                     fs = cgi.FieldStorage(
#                         fp=StringIO.StringIO(self.body),
#                         environ=self.req,
#                         keep_blank_values=1
#                     )
#                     for k in fs.keys():
#                         part = fs[k]
#                         if part.filename:
#                             _files[k] = part
#                         _arguments[k] = part.value
#                 except:
#                     _log.exception(
#                         "problem parsing multipart/form-data"
#                     )
#             # add any arguments from JSON body
#             elif content_type.startswith("application/json"):
#                 try:
#                     body = nudge.json.json_decode(self.body)
#                     if isinstance(body, types.DictType):
#                         _arguments = dict(_arguments, **body)
# 
#                 except (ValueError):
#                     raise HTTPException(400, "body is not JSON")
# 
#         self.files = _files
#         return _arguments
# 
#     def write(self, content):
#         self._buffer += content
# 
#     def request_time(self):
#         return time.time() - self.start_time


# Path: tests/test_wsgirequest.py
import unittest
import StringIO
from nudge.publisher import WSGIRequest

        print req.headers
        assert req.headers['X-Forwarded-For'] == '10.0.10.123'
        assert req.headers.get('X-Forwarded-For') == '10.0.10.123', req.headers.get('X-Forwarded-For')


    def test_xff_header_eventlet(self):
        input = StringIO.StringIO()
        req = WSGIRequest({
            'REQUEST_METHOD':'POST',
            'REMOTE_ADDR':'127.0.0.1',
            'wsgi.input': input,
            'HTTP_X_FORWARDED_FOR':'10.0.10.123',
        })
        print req.headers
        assert req.headers['X-Forwarded-For'] == '10.0.10.123'
        assert req.headers.get('X-Forwarded-For') == '10.0.10.123', req.headers.get('X-Forwarded-For')

    def test_request_files(self):
        input = StringIO.StringIO('''
-----------------------------41184676334
Content-Disposition: form-data; name="caption"

Summer vacation
-----------------------------41184676334
Content-Disposition: form-data; name="upload"; filename="extra_data.txt"
Content-Type: text/plain

Some more data about my vacation
-----------------------------41184676334--
''')

        request = WSGIRequest({