Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.2k
gh-65920: Implementsocket.sendfile
withTransmitFile
on Windows#112337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Changes from9 commits
490df91
f94935d
87c88fa
3f7259f
619ef22
19dde50
3dd3bc1
a4ce9df
77deb6e
47eb386
8bd91bb
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -55,6 +55,13 @@ | ||
import os, sys, io, selectors | ||
from enum import IntEnum, IntFlag | ||
try: | ||
import _overlapped | ||
import msvcrt | ||
except ImportError: | ||
_overlapped = None | ||
msvcrt = None | ||
try: | ||
import errno | ||
except ImportError: | ||
@@ -451,6 +458,39 @@ def _sendfile_use_send(self, file, offset=0, count=None): | ||
if total_sent > 0 and hasattr(file, 'seek'): | ||
file.seek(offset + total_sent) | ||
if _overlapped: | ||
aisk marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
def _sendfile_use_transmitfile(self, file, offset=0, count=None): | ||
self._check_sendfile_params(file, offset, count) | ||
timeout = self.gettimeout() | ||
if timeout == 0: | ||
raise ValueError("non-blocking sockets are not supported") | ||
ov = _overlapped.Overlapped() | ||
offset_low = offset & 0xffff_ffff | ||
offset_high = (offset >> 32) & 0xffff_ffff | ||
count = count or 0 | ||
try: | ||
fileno = file.fileno() | ||
except (AttributeError, io.UnsupportedOperation) as err: | ||
raise _GiveupOnSendfile(err) # not a regular file | ||
try: | ||
os.fstat(fileno) | ||
except OSError as err: | ||
raise _GiveupOnSendfile(err) # not a regular file | ||
ov.TransmitFile(self.fileno(), msvcrt.get_osfhandle(fileno), | ||
offset_low, offset_high, count, 0, 0) | ||
timeout_ms = _overlapped.INFINITE | ||
if timeout is not None: | ||
timeout_ms = int(timeout * 1000) | ||
try: | ||
sent = ov.getresultex(timeout_ms, False) | ||
except WindowsError as e: | ||
if e.winerror == 258: | ||
raise TimeoutError('timed out') | ||
raise | ||
if sent > 0 and hasattr(file, 'seek'): | ||
file.seek(offset + sent) | ||
return sent | ||
def _check_sendfile_params(self, file, offset, count): | ||
if 'b' not in getattr(file, 'mode', 'b'): | ||
raise ValueError("file should be opened in binary mode") | ||
@@ -483,6 +523,8 @@ def sendfile(self, file, offset=0, count=None): | ||
Non-blocking sockets are not supported. | ||
""" | ||
try: | ||
if sys.platform == "win32": | ||
return self._sendfile_use_transmitfile(file, offset, count) | ||
return self._sendfile_use_sendfile(file, offset, count) | ||
except _GiveupOnSendfile: | ||
return self._sendfile_use_send(file, offset, count) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Use :c:func:`!TransmitFile` on Windows to implement :func:`socket.sendfile`. |
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.