}
return -1;
} else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_PING) {
- /* ping frames produce an immediate reply */
- buffer_reset(&ioc->ping_reply);
- qio_channel_websock_encode_buffer(
- ioc, &ioc->ping_reply, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
- &ioc->encinput);
+ /* ping frames produce an immediate reply, as long as we've not still
+ * got a previous pong queued, in which case we drop the new pong */
+ if (ioc->pong_remain == 0) {
+ qio_channel_websock_encode_buffer(
+ ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
+ &ioc->encinput);
+ ioc->pong_remain = ioc->encoutput.offset;
+ }
} /* pong frames are ignored */
if (payload_len) {
buffer_free(&ioc->encoutput);
buffer_free(&ioc->rawinput);
buffer_free(&ioc->rawoutput);
- buffer_free(&ioc->ping_reply);
object_unref(OBJECT(ioc->master));
if (ioc->io_tag) {
g_source_remove(ioc->io_tag);
ssize_t ret;
ssize_t done = 0;
- /* ping replies take priority over binary data */
- if (!ioc->ping_reply.offset) {
- qio_channel_websock_encode(ioc);
- } else if (!ioc->encoutput.offset) {
- buffer_move_empty(&ioc->encoutput, &ioc->ping_reply);
- }
+ qio_channel_websock_encode(ioc);
while (ioc->encoutput.offset > 0) {
ret = qio_channel_write(ioc->master,
}
buffer_advance(&ioc->encoutput, ret);
done += ret;
+ if (ioc->pong_remain < ret) {
+ ioc->pong_remain = 0;
+ } else {
+ ioc->pong_remain -= ret;
+ }
}
return done;
}
return;
}
- if (ioc->encoutput.offset || ioc->ping_reply.offset) {
+ if (ioc->encoutput.offset) {
cond |= G_IO_OUT;
}
if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER &&