diff --git a/webrtc-jni/src/main/cpp/src/JNI_RTCDataChannel.cpp b/webrtc-jni/src/main/cpp/src/JNI_RTCDataChannel.cpp index 4afc434c..341f3638 100644 --- a/webrtc-jni/src/main/cpp/src/JNI_RTCDataChannel.cpp +++ b/webrtc-jni/src/main/cpp/src/JNI_RTCDataChannel.cpp @@ -19,6 +19,7 @@ #include "JavaEnums.h" #include "JavaError.h" #include "JavaRef.h" +#include "JavaRuntimeException.h" #include "JavaString.h" #include "JavaUtils.h" @@ -174,7 +175,9 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_RTCDataChannel_sendDirectBuffer webrtc::CopyOnWriteBuffer data(address, static_cast(bufferLength)); - channel->Send(webrtc::DataBuffer(data, static_cast(isBinary))); + if (!channel->Send(webrtc::DataBuffer(data, static_cast(isBinary)))) { + env->Throw(jni::JavaRuntimeException(env, "Data channel rejected the send")); + } } else { env->Throw(jni::JavaError(env, "Non-direct buffer provided")); @@ -195,7 +198,9 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_RTCDataChannel_sendByteArrayBuffer env->ReleaseByteArrayElements(jBufferArray, arrayPtr, JNI_ABORT); try { - channel->Send(webrtc::DataBuffer(data, static_cast(isBinary))); + if (!channel->Send(webrtc::DataBuffer(data, static_cast(isBinary)))) { + env->Throw(jni::JavaRuntimeException(env, "Data channel rejected the send")); + } } catch (...) { ThrowCxxJavaException(env); diff --git a/webrtc/src/main/java/dev/onvoid/webrtc/RTCDataChannel.java b/webrtc/src/main/java/dev/onvoid/webrtc/RTCDataChannel.java index 01ed68fd..7d2a0407 100644 --- a/webrtc/src/main/java/dev/onvoid/webrtc/RTCDataChannel.java +++ b/webrtc/src/main/java/dev/onvoid/webrtc/RTCDataChannel.java @@ -150,8 +150,8 @@ private RTCDataChannel() { * * @param buffer The buffer to be queued for transmission. * - * @throws Exception If queuing data is not possible because not enough - * buffer space is available. + * @throws Exception If the native channel rejects the send, for example + * because it is not open or its send buffer is full. */ public void send(RTCDataChannelBuffer buffer) throws Exception { ByteBuffer data = buffer.data; diff --git a/webrtc/src/test/java/dev/onvoid/webrtc/RTCDataChannelSendRejectionTests.java b/webrtc/src/test/java/dev/onvoid/webrtc/RTCDataChannelSendRejectionTests.java new file mode 100644 index 00000000..1584c6de --- /dev/null +++ b/webrtc/src/test/java/dev/onvoid/webrtc/RTCDataChannelSendRejectionTests.java @@ -0,0 +1,52 @@ +package dev.onvoid.webrtc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.nio.ByteBuffer; + +import org.junit.jupiter.api.Test; + +class RTCDataChannelSendRejectionTests extends TestBase { + + @Test + void rejectsHeapBufferBeforeOpen() { + assertRejected(ByteBuffer.allocate(8), false); + } + + @Test + void rejectsDirectBufferBeforeOpen() { + assertRejected(ByteBuffer.allocateDirect(8), false); + } + + @Test + void rejectsHeapBufferAfterClose() { + assertRejected(ByteBuffer.allocate(8), true); + } + + @Test + void rejectsDirectBufferAfterClose() { + assertRejected(ByteBuffer.allocateDirect(8), true); + } + + private void assertRejected(ByteBuffer data, boolean closed) { + RTCPeerConnection peer = factory.createPeerConnection( + new RTCConfiguration(), candidate -> { }); + RTCDataChannel channel = peer.createDataChannel("send", new RTCDataChannelInit()); + + try { + if (closed) { + channel.close(); + } + assertEquals(closed ? RTCDataChannelState.CLOSED : RTCDataChannelState.CONNECTING, + channel.getState()); + RuntimeException error = assertThrows(RuntimeException.class, + () -> channel.send(new RTCDataChannelBuffer(data, true))); + assertEquals("Data channel rejected the send", error.getMessage()); + } + finally { + peer.close(); + channel.dispose(); + } + } +}