diff --git a/.circleci/config.yml b/.circleci/config.yml index d7d80ca..65a3521 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,6 +3,7 @@ workflows: version: 2 test: jobs: + - test-3.10 - test-3.9 - test-3.8 - test-3.7 @@ -13,9 +14,9 @@ workflows: - test-pypy3 - test-pypy2 jobs: - test-3.9: &test-template + test-3.10: &test-template docker: - - image: python:3.9 # We run one test in non-alpine environment, just in case + - image: python:3.10 # We run one test in non-alpine environment, just in case working_directory: ~/work steps: - checkout @@ -36,6 +37,10 @@ jobs: command: | . venv/bin/activate pytest -v + test-3.9: + <<: *test-template + docker: + - image: python:3.9-alpine test-3.8: <<: *test-template docker: diff --git a/setup.py b/setup.py index eb6371f..51f188d 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name='smpplib', version='2.2.1', - url='https://github.com/podshumok/python-smpplib', + url='https://github.com/python-smpplib/python-smpplib', description='SMPP library for python', packages=find_packages(), install_requires=['six'], diff --git a/smpplib/client.py b/smpplib/client.py index bb44b04..ebad492 100644 --- a/smpplib/client.py +++ b/smpplib/client.py @@ -207,39 +207,43 @@ def send_pdu(self, p): )) self.logger.debug('Sending %s PDU', p.command) - generated = p.generate() - self.logger.debug('>>%s (%d bytes)', binascii.b2a_hex(generated), len(generated)) - sent = 0 + try: + self._socket.sendall(generated) + except socket.error as e: + self.logger.warning(e) + raise exceptions.ConnectionError() + + return True - while sent < len(generated): + def _recv_exact(self, exact_size): + """ + Keep reading from self._socket until exact_size bytes have been read + """ + parts = [] + received = 0 + while received < exact_size: try: - sent_last = self._socket.send(generated[sent:]) + part = self._socket.recv(exact_size - received) + except socket.timeout: + raise except socket.error as e: self.logger.warning(e) raise exceptions.ConnectionError() - if sent_last == 0: + if not part: raise exceptions.ConnectionError() - sent += sent_last - - return True + received += len(part) + parts.append(part) + return b"".join(parts) def read_pdu(self): """Read PDU from the SMSC""" self.logger.debug('Waiting for PDU...') - try: - raw_len = self._socket.recv(4) - except socket.timeout: - raise - except socket.error as e: - self.logger.warning(e) - raise exceptions.ConnectionError() - if not raw_len: - raise exceptions.ConnectionError() + raw_len = self._recv_exact(4) try: length = struct.unpack('>L', raw_len)[0] @@ -247,18 +251,7 @@ def read_pdu(self): self.logger.warning('Receive broken pdu... %s', repr(raw_len)) raise exceptions.PDUError('Broken PDU') - raw_pdu = raw_len - while len(raw_pdu) < length: - try: - raw_pdu_part = self._socket.recv(length - len(raw_pdu)) - except socket.timeout: - raise - except socket.error as e: - self.logger.warning(e) - raise exceptions.ConnectionError() - if not raw_pdu: - raise exceptions.ConnectionError() - raw_pdu += raw_pdu_part + raw_pdu = raw_len + self._recv_exact(length - 4) self.logger.debug('<<%s (%d bytes)', binascii.b2a_hex(raw_pdu), len(raw_pdu)) diff --git a/smpplib/command.py b/smpplib/command.py index b19b0c6..bde5840 100644 --- a/smpplib/command.py +++ b/smpplib/command.py @@ -410,7 +410,7 @@ class BindTransmitter(Command): ) def __init__(self, command, **kwargs): - super(BindTransmitter, self).__init__(command, need_sequence=False, **kwargs) + super(BindTransmitter, self).__init__(command, **kwargs) self._set_vars(**(dict.fromkeys(self.params))) self.interface_version = consts.SMPP_VERSION_34 @@ -817,7 +817,7 @@ class DeliverSM(SubmitSM): ) def __init__(self, command, **kwargs): - super(DeliverSM, self).__init__(command, need_sequence=False, **kwargs) + super(DeliverSM, self).__init__(command, **kwargs) self._set_vars(**(dict.fromkeys(self.params))) @@ -900,7 +900,7 @@ class Unbind(Command): params_order = () def __init__(self, command, **kwargs): - super(Unbind, self).__init__(command, need_sequence=False, **kwargs) + super(Unbind, self).__init__(command, **kwargs) class UnbindResp(Command): @@ -919,7 +919,7 @@ class EnquireLink(Command): params_order = () def __init__(self, command, **kwargs): - super(EnquireLink, self).__init__(command, need_sequence=False, **kwargs) + super(EnquireLink, self).__init__(command, **kwargs) class EnquireLinkResp(Command): diff --git a/smpplib/tests/test_command.py b/smpplib/tests/test_command.py index a0e2433..0c47891 100644 --- a/smpplib/tests/test_command.py +++ b/smpplib/tests/test_command.py @@ -1,11 +1,13 @@ from smpplib import consts, exceptions +from smpplib.client import Client from smpplib.command import DeliverSM import pytest def test_parse_deliver_sm(): - pdu = DeliverSM('deliver_sm') + client = Client("localhost", 5679) + pdu = DeliverSM('deliver_sm', client=client) pdu.parse( b"\x00\x00\x00\xcb\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00" b"\x01\x0131600000000\x00\x05\x00XXX YYYY\x00\x04\x00\x00\x00\x00\x00" @@ -26,7 +28,8 @@ def test_parse_deliver_sm(): def test_unrecognised_optional_parameters(): - pdu = DeliverSM("deliver_sm", allow_unknown_opt_params=True) + client = Client("localhost", 5679) + pdu = DeliverSM("deliver_sm", client=client, allow_unknown_opt_params=True) pdu.parse(b'\x00\x00\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00/p\xc6' b'\x9a\x00\x00\x0022549909028\x00\x01\x00\x00\x04\x00\x00' b'\x00\x00\x00\x00\x00\x00iid:795920026 sub:001 dlvrd:001 ' @@ -37,7 +40,7 @@ def test_unrecognised_optional_parameters(): # This is only to avoid a breaking change, at some point the other behaviour # should become the default. with pytest.raises(exceptions.UnknownCommandError): - pdu2 = DeliverSM("deliver_sm") + pdu2 = DeliverSM("deliver_sm", client=client) pdu2.parse(b'\x00\x00\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00/p\xc6' b'\x9a\x00\x00\x0022549909028\x00\x01\x00\x00\x04\x00\x00' b'\x00\x00\x00\x00\x00\x00iid:795920026 sub:001 dlvrd:001 '