mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 08:26:56 +00:00
Add optional error descriptions to drop errors as well
This commit is contained in:
parent
21d8b2bcc0
commit
a0da884c6a
3 changed files with 64 additions and 62 deletions
96
kitty/dnd.c
96
kitty/dnd.c
|
|
@ -632,17 +632,19 @@ drop_append_request_keys(Window *w, char *buf, size_t bufsize) {
|
|||
}
|
||||
|
||||
static void
|
||||
drop_send_error(Window *w, int error_code) {
|
||||
char buf[128];
|
||||
const char *e = get_errno_name(error_code);
|
||||
drop_send_error(Window *w, int error_code, const char *desc) {
|
||||
char buf[128], details_buf[1024];
|
||||
int n;
|
||||
if (desc && desc[0]) n = snprintf(details_buf, sizeof(details_buf), "%s:%s", get_errno_name(error_code), desc);
|
||||
else n = snprintf(details_buf, sizeof(details_buf), "%s:%s", get_errno_name(error_code), desc);
|
||||
int header_size = snprintf(buf, sizeof(buf), "\x1b]%d;t=R", DND_CODE);
|
||||
header_size += drop_append_request_keys(w, buf + header_size, sizeof(buf) - header_size);
|
||||
queue_payload_to_child(w->id, w->drop.client_id, &w->drop.pending, buf, header_size, e, strlen(e), false);
|
||||
queue_payload_to_child(w->id, w->drop.client_id, &w->drop.pending, buf, header_size, details_buf, n, false);
|
||||
}
|
||||
|
||||
void
|
||||
drop_send_einval(Window *w) {
|
||||
drop_send_error(w, EINVAL);
|
||||
drop_send_einval(Window *w, const char *desc) {
|
||||
drop_send_error(w, EINVAL, desc);
|
||||
}
|
||||
|
||||
/* Returns true if the request completed synchronously (error, no-op),
|
||||
|
|
@ -654,7 +656,7 @@ do_drop_request_data(Window *w, int32_t idx) {
|
|||
if (!osw) return true;
|
||||
/* idx is 1-based */
|
||||
if (idx < 1 || !w->drop.offerred_mimes || (size_t)idx > w->drop.num_offerred_mimes) {
|
||||
drop_send_error(w, ENOENT);
|
||||
drop_send_error(w, ENOENT, "drop data request index out of bounds");
|
||||
return true;
|
||||
}
|
||||
const char *mime = w->drop.offerred_mimes[idx - 1];
|
||||
|
|
@ -666,7 +668,7 @@ do_drop_request_data(Window *w, int32_t idx) {
|
|||
void
|
||||
drop_dispatch_data(Window *w, const char *mime, const char *data, ssize_t sz) {
|
||||
if (sz < 0) {
|
||||
drop_send_error(w, -sz);
|
||||
drop_send_error(w, -sz, "drop data request failed to read data");
|
||||
drop_pop_request(w);
|
||||
drop_process_queue(w);
|
||||
} else {
|
||||
|
|
@ -767,7 +769,7 @@ file_send_timer_callback(id_type timer_id UNUSED, void *x) {
|
|||
w->drop.file_send_timer = 0;
|
||||
if (monotonic() - w->drop.last_file_send_at > s_to_monotonic_t(FILE_SEND_TIMEOUT_SECONDS)) {
|
||||
drop_close_file_fd(w);
|
||||
drop_send_error(w, EIO);
|
||||
drop_send_error(w, EIO, "timed out waiting for child to read file data");
|
||||
drop_pop_request(w);
|
||||
drop_process_queue(w);
|
||||
return;
|
||||
|
|
@ -795,7 +797,7 @@ drop_send_file_chunks(Window *w) {
|
|||
return;
|
||||
}
|
||||
drop_close_file_fd(w);
|
||||
drop_send_error(w, EIO);
|
||||
drop_send_error(w, EIO, "failed ot read from drop data file");
|
||||
drop_pop_request(w);
|
||||
drop_process_queue(w);
|
||||
return;
|
||||
|
|
@ -814,7 +816,7 @@ drop_send_file_chunks(Window *w) {
|
|||
/* Partial send: rewind file pointer and retry via timer */
|
||||
if (lseek(w->drop.file_fd_plus_one - 1, -(off_t)(((size_t)n) - sent), SEEK_CUR) < 0) {
|
||||
drop_close_file_fd(w);
|
||||
drop_send_error(w, EIO);
|
||||
drop_send_error(w, EIO, "failed to seek() on drop data file");
|
||||
drop_pop_request(w);
|
||||
drop_process_queue(w);
|
||||
return;
|
||||
|
|
@ -835,23 +837,23 @@ drop_send_file_data(Window *w, const char *path) {
|
|||
int fd = safe_open(path, O_RDONLY | O_CLOEXEC | O_NONBLOCK, 0);
|
||||
if (fd < 0) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM); break;
|
||||
default: drop_send_error(w, EIO); break;
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT, "drop data file does not exist"); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM, "opening drop data file permission denied"); break;
|
||||
default: drop_send_error(w, EIO, "failed to open drop data file"); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) < 0) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM); break;
|
||||
default: drop_send_error(w, EIO); break;
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT, "failed to stat drop data file"); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM, "failed to stat drop data file"); break;
|
||||
default: drop_send_error(w, EIO, "failed to stat drop data file"); break;
|
||||
}
|
||||
safe_close(fd, __FILE__, __LINE__);
|
||||
return true;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)) { drop_send_error(w, EINVAL); safe_close(fd, __FILE__, __LINE__); return true; }
|
||||
if (!S_ISREG(st.st_mode)) { drop_send_error(w, EINVAL, "drop data file is not a regular file"); safe_close(fd, __FILE__, __LINE__); return true; }
|
||||
w->drop.file_fd_plus_one = fd + 1;
|
||||
w->drop.last_file_send_at = monotonic();
|
||||
drop_send_file_chunks(w);
|
||||
|
|
@ -891,9 +893,9 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
DIR *dir = opendir(path);
|
||||
if (!dir) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM); break;
|
||||
default: drop_send_error(w, EIO); break;
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT, "drop data dir does not exist"); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM, "drop data dir permission denied"); break;
|
||||
default: drop_send_error(w, EIO, "drop data dir opening failed"); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -901,7 +903,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
/* Build null-separated payload: entry1\0entry2\0... */
|
||||
size_t payload_cap = 4096, payload_sz = 0;
|
||||
char *payload = malloc(payload_cap);
|
||||
if (!payload) { closedir(dir); drop_send_error(w, EIO); return; }
|
||||
if (!payload) { closedir(dir); drop_send_error(w, ENOMEM, "out of memory reading drop data dir"); return; }
|
||||
|
||||
#define APPEND(s, n) do { \
|
||||
size_t _n = (size_t)(n); \
|
||||
|
|
@ -909,7 +911,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
if (_need > payload_cap) { \
|
||||
while (payload_cap < _need) payload_cap *= 2; \
|
||||
char *_np = realloc(payload, payload_cap); \
|
||||
if (!_np) { free(payload); closedir(dir); drop_send_error(w, EIO); return; } \
|
||||
if (!_np) { free(payload); closedir(dir); drop_send_error(w, ENOMEM, "out of memory reading drop data dir"); return; } \
|
||||
payload = _np; \
|
||||
} \
|
||||
memcpy(payload + payload_sz, (s), _n); \
|
||||
|
|
@ -920,7 +922,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
/* Collect directory entries */
|
||||
size_t ents_cap = 16, ents_num = 0;
|
||||
char **ents = malloc(sizeof(char *) * ents_cap);
|
||||
if (!ents) { free(payload); closedir(dir); drop_send_error(w, EIO); return; }
|
||||
if (!ents) { free(payload); closedir(dir); drop_send_error(w, ENOMEM, "out of memory reading directory contents"); return; }
|
||||
|
||||
struct dirent *de;
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
|
|
@ -946,7 +948,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
if (!ne) {
|
||||
for (size_t i = 0; i < ents_num; i++) free(ents[i]);
|
||||
free(ents); free(payload); closedir(dir);
|
||||
drop_send_error(w, EIO); return;
|
||||
drop_send_error(w, ENOMEM, "out of memory reading drop data dir"); return;
|
||||
}
|
||||
ents = ne;
|
||||
}
|
||||
|
|
@ -954,7 +956,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
if (!ents[ents_num]) {
|
||||
for (size_t i = 0; i < ents_num; i++) free(ents[i]);
|
||||
free(ents); free(payload); closedir(dir);
|
||||
drop_send_error(w, EIO); return;
|
||||
drop_send_error(w, ENOMEM, "out of memory reading drop data dir"); return;
|
||||
}
|
||||
ents_num++;
|
||||
|
||||
|
|
@ -989,7 +991,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
|||
static void
|
||||
drop_send_symlink(Window *w, const char *path) {
|
||||
char target[PATH_MAX]; ssize_t tgtsz;
|
||||
if ((tgtsz = readlink(path, target, sizeof(target)-1)) < 0) { drop_send_error(w, EIO); return; }
|
||||
if ((tgtsz = readlink(path, target, sizeof(target)-1)) < 0) { drop_send_error(w, EIO, "failed to read symlink for drop data"); return; }
|
||||
char hdr[128];
|
||||
int hdr_sz = snprintf(hdr, sizeof(hdr), "\x1b]%d;t=r", DND_CODE);
|
||||
hdr_sz += drop_append_request_keys(w, hdr + hdr_sz, sizeof(hdr) - hdr_sz);
|
||||
|
|
@ -1003,20 +1005,20 @@ drop_send_symlink(Window *w, const char *path) {
|
|||
static bool
|
||||
do_drop_request_uri_data(Window *w, int32_t mime_idx, int32_t file_idx) {
|
||||
if (!w->drop.uri_list || !w->drop.uri_list_sz) {
|
||||
drop_send_error(w, EINVAL); return true;
|
||||
drop_send_error(w, EINVAL, "drop data uri list empty"); return true;
|
||||
}
|
||||
if (global_state.drag_source.from_window == w->id && w->drag_source.state != DRAG_SOURCE_NONE) {
|
||||
drop_send_error(w, EPERM); return true;
|
||||
drop_send_error(w, EPERM, "cannot drop into self window"); return true;
|
||||
}
|
||||
|
||||
/* Verify mime_idx (1-based) points to text/uri-list */
|
||||
if (mime_idx < 1 || !w->drop.offerred_mimes || (size_t)mime_idx > w->drop.num_offerred_mimes ||
|
||||
strcmp(w->drop.offerred_mimes[mime_idx - 1], "text/uri-list") != 0) {
|
||||
drop_send_error(w, EINVAL); return true;
|
||||
drop_send_error(w, EINVAL, "drop data mime index out of bounds"); return true;
|
||||
}
|
||||
|
||||
/* file_idx is 1-based, convert to 0-based for get_nth_file_url */
|
||||
if (file_idx < 1) { drop_send_error(w, EINVAL); return true; }
|
||||
if (file_idx < 1) { drop_send_error(w, EINVAL, "drop data file url index out of bounds"); return true; }
|
||||
int file_n = file_idx - 1;
|
||||
|
||||
RAII_ALLOC(char, path, NULL);
|
||||
|
|
@ -1029,9 +1031,9 @@ do_drop_request_uri_data(Window *w, int32_t mime_idx, int32_t file_idx) {
|
|||
struct stat st;
|
||||
if (lstat(path, &st) < 0) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM); break;
|
||||
default: drop_send_error(w, EIO); break;
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT, "drop data file does not exist"); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM, "permission denied for stat() on drop data file"); break;
|
||||
default: drop_send_error(w, EIO, "stat() on drop data file failed"); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1044,7 +1046,7 @@ do_drop_request_uri_data(Window *w, int32_t mime_idx, int32_t file_idx) {
|
|||
} else if (S_ISLNK(st.st_mode)) {
|
||||
drop_send_symlink(w, path);
|
||||
} else {
|
||||
drop_send_error(w, EINVAL);
|
||||
drop_send_error(w, EINVAL, "drop data file is neother a regular file, directory or symlink");
|
||||
}
|
||||
return sync;
|
||||
}
|
||||
|
|
@ -1055,10 +1057,10 @@ do_drop_request_uri_data(Window *w, int32_t mime_idx, int32_t file_idx) {
|
|||
* Returns true if completed synchronously, false if async file I/O started. */
|
||||
static bool
|
||||
do_drop_handle_dir_request(Window *w, uint32_t handle_id, int32_t entry_num) {
|
||||
if (!handle_id) { drop_send_error(w, EINVAL); return true; }
|
||||
if (!handle_id) { drop_send_error(w, EINVAL, "no parent directory handle specified"); return true; }
|
||||
|
||||
DirHandle *h = drop_find_dir_handle(w, handle_id);
|
||||
if (!h) { drop_send_error(w, EINVAL); return true; }
|
||||
if (!h) { drop_send_error(w, EINVAL, "parent directory handle not found"); return true; }
|
||||
|
||||
if (entry_num == 0) {
|
||||
/* Close the handle */
|
||||
|
|
@ -1070,19 +1072,19 @@ do_drop_handle_dir_request(Window *w, uint32_t handle_id, int32_t entry_num) {
|
|||
|
||||
/* Read the entry at 1-based index */
|
||||
size_t eidx = (size_t)(entry_num - 1);
|
||||
if (eidx >= h->num_entries) { drop_send_error(w, ENOENT); return true; }
|
||||
if (eidx >= h->num_entries) { drop_send_error(w, EINVAL, "entry index out of bounds for parent directory"); return true; }
|
||||
|
||||
char full[PATH_MAX];
|
||||
if (snprintf(full, sizeof(full), "%s/%s", h->path, h->entries[eidx]) >= (int)sizeof(full)) {
|
||||
drop_send_error(w, EIO); return true;
|
||||
drop_send_error(w, EIO, "drop data file path too long"); return true;
|
||||
}
|
||||
|
||||
struct stat lst;
|
||||
if (lstat(full, &lst) < 0) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: case ELOOP: drop_send_error(w, ENOENT); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM); break;
|
||||
default: drop_send_error(w, EIO); break;
|
||||
case ENOENT: case ENOTDIR: case ELOOP: drop_send_error(w, ENOENT, "drop data entry does not exist"); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM, "parmission denied while trying to stat() drop data entry"); break;
|
||||
default: drop_send_error(w, EIO, "stt() failed on drop data entry"); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1093,9 +1095,9 @@ do_drop_handle_dir_request(Window *w, uint32_t handle_id, int32_t entry_num) {
|
|||
ssize_t tlen = readlink(full, target, sizeof(target) - 1);
|
||||
if (tlen < 0) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM); break;
|
||||
default: drop_send_error(w, EIO); break;
|
||||
case ENOENT: case ENOTDIR: drop_send_error(w, ENOENT, "readlink() failed on drop data entry"); break;
|
||||
case EACCES: case EPERM: drop_send_error(w, EPERM, "readlink() failed on drop data entry"); break;
|
||||
default: drop_send_error(w, EIO, "readlink() failed on drop data entry"); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1115,7 +1117,7 @@ do_drop_handle_dir_request(Window *w, uint32_t handle_id, int32_t entry_num) {
|
|||
} else if (S_ISREG(lst.st_mode)) {
|
||||
return drop_send_file_data(w, full);
|
||||
} else {
|
||||
drop_send_error(w, EINVAL);
|
||||
drop_send_error(w, EINVAL, "drop data entry is neither a regular file nor a directory");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1204,7 +1206,7 @@ drop_enqueue_request(Window *w, int32_t cell_x, int32_t cell_y, int32_t pixel_y,
|
|||
w->drop.current_request_x = cell_x;
|
||||
w->drop.current_request_y = cell_y;
|
||||
w->drop.current_request_Y = pixel_y;
|
||||
drop_send_error(w, EMFILE);
|
||||
drop_send_error(w, EMFILE, "too many drop data requests");
|
||||
w->drop.current_request_x = saved_x;
|
||||
w->drop.current_request_y = saved_y;
|
||||
w->drop.current_request_Y = saved_Y;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ void drop_register_machine_id(Window *w, const uint8_t *machine_id, size_t sz);
|
|||
void drop_move_on_child(Window *w, const char **mimes, size_t num_mimes, bool is_drop);
|
||||
void drop_left_child(Window *w);
|
||||
void drop_free_data(Window *w);
|
||||
void drop_send_einval(Window *w);
|
||||
void drop_send_einval(Window *w, const char *desc);
|
||||
void drop_handle_dir_request(Window *w, uint32_t handle_id, int32_t entry_num);
|
||||
void drop_enqueue_request(Window *w, int32_t cell_x, int32_t cell_y, int32_t pixel_y, uint32_t operation);
|
||||
void drop_set_status(Window *w, int operation, const char *payload, size_t payload_sz, bool more);
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'ENOENT')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'ENOENT')
|
||||
|
||||
def test_data_error_propagation(self) -> None:
|
||||
"""When data retrieval fails the client receives a t=R error code."""
|
||||
|
|
@ -541,7 +541,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'EIO')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EIO')
|
||||
|
||||
def test_data_eperm_error(self) -> None:
|
||||
"""EPERM error is correctly forwarded to the client."""
|
||||
|
|
@ -556,7 +556,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'EPERM')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EPERM')
|
||||
|
||||
def test_large_data_chunking(self) -> None:
|
||||
"""Data larger than the chunk limit is sent in multiple base64 chunks."""
|
||||
|
|
@ -764,7 +764,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.assertIn(events[0]['payload'].strip(), [b'ENOENT', b'EPERM'])
|
||||
self.assertIn(events[0]['payload'].strip().partition(b':')[0], [b'ENOENT', b'EPERM'])
|
||||
|
||||
def test_uri_file_transfer_out_of_bounds(self) -> None:
|
||||
"""URI file request with an index beyond the URI list returns ENOENT."""
|
||||
|
|
@ -801,7 +801,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'EINVAL')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EINVAL')
|
||||
finally:
|
||||
os.unlink(fpath)
|
||||
|
||||
|
|
@ -814,7 +814,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'EINVAL')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EINVAL')
|
||||
|
||||
def test_uri_broken_symlink_returns_symlink_target(self) -> None:
|
||||
"""A broken symlink in the URI list is transmitted as a symlink (X=1) with the target."""
|
||||
|
|
@ -1083,7 +1083,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'EINVAL')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EINVAL')
|
||||
|
||||
def test_dir_entry_out_of_bounds_returns_enoent(self) -> None:
|
||||
"""Reading a directory entry with an out-of-range index returns ENOENT."""
|
||||
|
|
@ -1105,7 +1105,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = self._get_events(cap)
|
||||
self.assertEqual(len(events), 1)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['payload'].strip(), b'ENOENT')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EINVAL')
|
||||
|
||||
def test_dir_no_unique_identifier(self) -> None:
|
||||
"""Directory listings should not contain a unique identifier prefix."""
|
||||
|
|
@ -2014,7 +2014,7 @@ class TestDnDProtocol(BaseTest):
|
|||
self.assertEqual(len(events), 1, events)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['meta'].get('x'), '99')
|
||||
self.ae(events[0]['payload'].strip(), b'ENOENT')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'ENOENT')
|
||||
|
||||
def test_x_key_in_error_for_io_failure(self) -> None:
|
||||
"""x= key is echoed in I/O error responses."""
|
||||
|
|
@ -2030,7 +2030,7 @@ class TestDnDProtocol(BaseTest):
|
|||
self.assertEqual(len(events), 1)
|
||||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['meta'].get('x'), '1')
|
||||
self.ae(events[0]['payload'].strip(), b'EIO')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EIO')
|
||||
|
||||
def test_fifo_order_with_different_indices(self) -> None:
|
||||
"""Multiple requests with different x= values are served in FIFO order."""
|
||||
|
|
@ -2080,7 +2080,7 @@ class TestDnDProtocol(BaseTest):
|
|||
err_events = [e for e in events if e['type'] == 'R']
|
||||
self.assertEqual(len(err_events), 1, events)
|
||||
self.ae(err_events[0]['meta'].get('x'), '99')
|
||||
self.ae(err_events[0]['payload'].strip(), b'ENOENT')
|
||||
self.ae(err_events[0]['payload'].strip().partition(b':')[0], b'ENOENT')
|
||||
|
||||
# Now serve request for index 1
|
||||
dnd_test_fake_drop_data(cap.window_id, 'text/plain', b'second request data')
|
||||
|
|
@ -2117,7 +2117,7 @@ class TestDnDProtocol(BaseTest):
|
|||
events = parse_escape_codes(raw)
|
||||
err_events = [e for e in events if e['type'] == 'R']
|
||||
self.assertTrue(err_events, 'expected EMFILE error')
|
||||
self.ae(err_events[0]['payload'].strip(), b'EMFILE')
|
||||
self.ae(err_events[0]['payload'].strip().partition(b':')[0], b'EMFILE')
|
||||
|
||||
def test_xy_keys_in_uri_file_response(self) -> None:
|
||||
"""x= and y= keys are echoed in URI file data responses."""
|
||||
|
|
@ -2241,7 +2241,7 @@ class TestDnDProtocol(BaseTest):
|
|||
self.ae(events[0]['type'], 'R')
|
||||
self.ae(events[0]['meta'].get('x'), '999')
|
||||
self.ae(events[0]['meta'].get('Y'), str(handle_id))
|
||||
self.ae(events[0]['payload'].strip(), b'ENOENT')
|
||||
self.ae(events[0]['payload'].strip().partition(b':')[0], b'EINVAL')
|
||||
|
||||
def test_mixed_request_types_processed_in_order(self) -> None:
|
||||
"""Mixed MIME data and URI file requests are processed in FIFO order."""
|
||||
|
|
@ -2297,7 +2297,7 @@ class TestDnDProtocol(BaseTest):
|
|||
self.ae(err_events[1]['meta'].get('x'), '20')
|
||||
self.ae(err_events[2]['meta'].get('x'), '30')
|
||||
for ev in err_events:
|
||||
self.ae(ev['payload'].strip(), b'ENOENT')
|
||||
self.ae(ev['payload'].strip().partition(b':')[0], b'ENOENT')
|
||||
|
||||
def test_no_r_key_in_responses(self) -> None:
|
||||
"""Responses must not contain the old r= key."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue