Skip to content

Commit

Permalink
Create separate exception types for each status code (#46)
Browse files Browse the repository at this point in the history
* Create separate exception types for each status code

* Added test for missing _STATUS_CODE, fix up tox.ini
  • Loading branch information
jborean93 committed Aug 8, 2020
1 parent 5210bb0 commit 0ff8039
Show file tree
Hide file tree
Showing 13 changed files with 391 additions and 131 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Speed up logging statements for large messages like a read and write message
* Changed authentication dep to [pyspnego](https://github.com/jborean93/pyspnego) that handles all the authentication work
* Fixed up authentication against hosts that don't present the initial GSSAPI token like Azure File Storage
* Added specific exception types for every `NtStatus` value to make it easier to catch only specific exceptions
* Added `STATUS_SERVER_UNAVAILABLE` to the list of known exception codes


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export SMB_PORT=445
export SMB_SERVER=127.0.0.1
export SMB_SHARE=share

docker run -d -p $SMB_PORT:445 -v $(pwd)/build-scripts:/app -w /app -e SMB_USER=$SMB_USER -e SMB_PASSWORD=$SMB_PASSWORD -e SMB_SHARE=$SMB_SHARE centos:7 /bin/bash /app/setup_samba.sh;
docker run -d --privileged=true -p $SMB_PORT:445 -v $(pwd)/build-scripts:/app -w /app -e SMB_USER=$SMB_USER -e SMB_PASSWORD=$SMB_PASSWORD -e SMB_SHARE=$SMB_SHARE centos:7 /bin/bash /app/setup_samba.sh;
```


Expand Down
22 changes: 8 additions & 14 deletions smbclient/_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
)

from smbprotocol.exceptions import (
NtStatus,
NoMoreFiles,
PipeBroken,
SMBOSError,
SMBResponseException,
)
Expand Down Expand Up @@ -415,10 +416,8 @@ def readall(self):
while len(data) < remaining_bytes or self.FILE_TYPE == 'pipe':
try:
data_part = self.fd.read(self._offset, self._buffer_size)
except SMBResponseException as exc:
if exc.status == NtStatus.STATUS_PIPE_BROKEN:
break
raise
except PipeBroken:
break

data += data_part
if self.FILE_TYPE != 'pipe':
Expand All @@ -439,11 +438,8 @@ def readinto(self, b):

try:
file_bytes = self.fd.read(self._offset, len(b))
except SMBResponseException as exc:
if exc.status == NtStatus.STATUS_PIPE_BROKEN:
file_bytes = b""
else:
raise
except PipeBroken:
file_bytes = b""

b[:len(file_bytes)] = file_bytes

Expand Down Expand Up @@ -489,10 +485,8 @@ def query_directory(self, pattern, info_class):
while True:
try:
entries = self.fd.query_directory(pattern, info_class, flags=query_flags)
except SMBResponseException as exc:
if exc.status == NtStatus.STATUS_NO_MORE_FILES:
break
raise
except NoMoreFiles:
break

query_flags = 0 # Only the first request should have set SMB2_RESTART_SCANS
for entry in entries:
Expand Down
8 changes: 4 additions & 4 deletions smbclient/_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
)

from smbprotocol.exceptions import (
NoEASOnFile,
NoSuchFile,
NtStatus,
SMBOSError,
SMBResponseException,
Expand Down Expand Up @@ -230,10 +232,8 @@ def listdir(path, search_pattern="*", **kwargs):
raw_filenames = dir_fd.query_directory(search_pattern, FileInformationClass.FILE_NAMES_INFORMATION)
return list(e['file_name'].get_value().decode('utf-16-le') for e in raw_filenames if
e['file_name'].get_value().decode('utf-16-le') not in ['.', '..'])
except SMBResponseException as exc:
if exc.status == NtStatus.STATUS_NO_SUCH_FILE:
return []
raise
except NoSuchFile:
return []


def lstat(path, **kwargs):
Expand Down
20 changes: 10 additions & 10 deletions smbprotocol/change_notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
)

from smbprotocol.exceptions import (
SMBResponseException,
Cancelled,
NotifyEnumDir,
)

from smbprotocol.structure import (
Expand Down Expand Up @@ -281,17 +282,16 @@ def wait(self):
def _on_response(self):
try:
self.open.connection.receive(self._request)
except SMBResponseException as exc:
if exc.status == NtStatus.STATUS_CANCELLED:
self.is_cancelled = True
elif exc.status == NtStatus.STATUS_NOTIFY_ENUM_DIR:
# output_buffer_length was 0 so we only need to notify the caller that a change occurred, set an empty
# action list.
self._file_actions = []
else:
self._t_exc = exc

except Cancelled:
self.is_cancelled = True
except NotifyEnumDir:
# output_buffer_length was 0 so we only need to notify the caller that a change occurred, set an empty
# action list.
self._file_actions = []
except Exception as exc:
self._t_exc = exc

finally:
log.debug("Firing response event for %s change notify" % self.open.file_name)
self.response_event.set()
Loading

0 comments on commit 0ff8039

Please sign in to comment.