Skip to content

Commit

Permalink
Fix encoding and do escaping in authorize.net xml
Browse files Browse the repository at this point in the history
- Escapes &, <, and > except in extraOptions tags, which need to allow special
    characters
- Encodes string as UTF-8 before sending it over the wire
- Replaces xml entities in responses with the correct chars

This change should fix some of the 500 server errors people were getting when
they had unusual characters in their payment info.
  • Loading branch information
shlurbee committed Jul 6, 2012
1 parent 77ba2db commit 60004f2
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions r2/r2/lib/authorize/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
from r2.models import NotFound
from r2.models.bidding import CustomerID, PayID, ShippingAddress

from xml.sax.saxutils import escape

# list of the most common errors.
Errors = Storage(TESTMODE = "E00009",
TRANSACTION_FAIL = "E00027",
Expand All @@ -49,6 +51,9 @@ class AuthorizeNetException(Exception):
pass


# xml tags whose content shouldn't be escaped
_no_escape_list = ["extraOptions"]

class SimpleXMLObject(object):
"""
All API transactions are done with authorize.net using XML, so
Expand All @@ -74,6 +79,10 @@ def toXML(self):
def process(k, v):
if isinstance(v, SimpleXMLObject):
v = v.toXML()
elif v is not None:
v = unicode(v)
if k not in _no_escape_list:
v = escape(v) # escape &, <, and >
if v is not None:
content.append(self.simple_tag(k, v))

Expand Down Expand Up @@ -213,7 +222,7 @@ def make_request(self):
u = urlparse(g.authorizenetapi)
try:
conn = HTTPSConnection(u.hostname, u.port)
conn.request("POST", u.path, self.toXML(),
conn.request("POST", u.path, self.toXML().encode('utf-8'),
{"Content-type": "text/xml"})
res = conn.getresponse()
res = self.handle_response(res.read())
Expand All @@ -237,7 +246,9 @@ def _autoclose_handler(self, m):

def handle_response(self, res):
res = self._autoclose_re.sub(self._autoclose_handler, res)
res = BeautifulStoneSoup(res, markupMassage=False)
res = BeautifulStoneSoup(res,
markupMassage=False,
convertEntities=BeautifulStoneSoup.XML_ENTITIES)
if res.resultcode.contents[0] == u"Ok":
return self.process_response(res)
else:
Expand Down

0 comments on commit 60004f2

Please sign in to comment.