django / django-contrib-comments

BSD 3-Clause "New" or "Revised" License
619 stars 197 forks source link

Error when saving comment invalid input syntax for type inet #93

Closed kwatog closed 8 years ago

kwatog commented 8 years ago

I'm running python 3.5 and django 1.9.7 on CentOS

Django Version: 1.9.7 Exception Type: DataError Exception Value:
invalid input syntax for type inet: "b''" LINE 3: ... '2016-06-28T13:54:40.057911+00:00'::timestamptz, E'b'''''::...

Temporarily, I commented out the auto population of flag_date om the save method of the model

    def save(self, *args, **kwargs):
        #if self.flag_date is None:
         #   self.flag_date = timezone.now()
        pass
        super(CommentFlag, self).save(*args, **kwargs)

and then it worked fine. But of course, flag_date is null.

claudep commented 8 years ago

Looking at the error, it seems the issue is with the ip_address field, not the flag_date field. But a complete traceback might help to diagnose. Are you on PostgreSQL?

kwatog commented 8 years ago

Yes, I'm on PostgreSQL. I'd like to point out that if I use runserver, it is working fine. But behind gunicorn, it's having this issue.

here's the full traceback.

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

The above exception (invalid input syntax for type inet: "b''"
LINE 1: ... '2016-06-29T01:49:20.676843+00:00'::timestamptz, E'b'''''::...
                                                             ^
) was the direct cause of the following exception:

File "/home/mkt/mktve/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/views/decorators/http.py" in inner
  42.             return func(request, *args, **kwargs)

File "/home/mkt/mktve/lib/python3.5/site-packages/django_comments/views/comments.py" in post_comment
  122.     comment.save()

File "/home/mkt/mktve/lib/python3.5/site-packages/django_comments/abstracts.py" in save
  95.         super(CommentAbstractModel, self).save(*args, **kwargs)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/base.py" in save
  708.                        force_update=force_update, update_fields=update_fields)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/base.py" in save_base
  736.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/base.py" in _save_table
  820.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/base.py" in _do_insert
  859.                                using=using, raw=raw)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/manager.py" in manager_method
  122.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/query.py" in _insert
  1039.         return query.get_compiler(using=using).execute_sql(return_id)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1060.                 cursor.execute(sql, params)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/utils.py" in __exit__
  95.                 six.reraise(dj_exc_type, dj_exc_value, traceback)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/utils/six.py" in reraise
  685.             raise value.with_traceback(tb)

File "/home/mkt/mktve/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

Exception Type: DataError at /comments/post/
Exception Value: invalid input syntax for type inet: "b''"
LINE 1: ... '2016-06-29T01:49:20.676843+00:00'::timestamptz, E'b'''''::...
                                                             ^
claudep commented 8 years ago

I identified the issue. The problem is that request.META['REMOTE_ADDR'] = b'' (binary empty string), while this should be a "normal" empty string. I'm not sure that's something we want to fix in django-contrib-comments. Maybe you can try to get support on the gunicorn side about this issue?

kwatog commented 8 years ago

okay, thanks! I'll just bring it up with gunicorn. closing the issue now.

kwatog commented 8 years ago

Sorry, had to re-open. I realized that request.META.get("REMOTE_ADDR", None) return blank specially if your app is running in wsgi server like gunicorn. We should try to get the value of HTTP_X_FORWARDED_FOR first and if there's none, then get REMOTE_ADDR.

Here's my fix.

views/comments.py original comment.ip_address = request.META.get("REMOTE_ADDR", None)

modified

    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR', None)

    comment.ip_address = ip
claudep commented 8 years ago

There is a potential security issue to this solution. See https://github.com/django/django/commit/d78cf61c992079a I think you should write your own middleware based on the code of that Django commit.

kwatog commented 8 years ago

thanks for the heads up. understood that x_forwarded_for can be spoof and should not be used for authentication.

at any rate, I'm closing this issue now.

claudep commented 8 years ago

To be clear, x_forwarded_for can be used, but only in specific setup when you are sure how it is populated (maybe your case).

ramezkabbani commented 7 years ago

What's the recommended workaround for this issue? I read through the gunicorn thread, they don't think patching this should be on them.

claudep commented 7 years ago

I just pushed a fix for that issue. Meanwhile, the workaround would be to have a custom middleware cleaning the request.META['REMOTE_ADDR'] from a b'' to ''.

grrodre commented 6 years ago

Hello everyone,

I have the same problem with gunicorn behind nginx. It seems that if bind gunicorn on a unix socket it has no IP and this error pops up. I solved it binding gunicornd to a TCP socket (http://127.0.0.1:8000).

Regards.Greg.