@@ -170,6 +170,28 @@ MsH3RequestClose(
170
170
delete (MsH3BiDirStream*)Handle ;
171
171
}
172
172
173
+ extern " C"
174
+ void
175
+ MSH3_CALL
176
+ MsH3RequestCompleteReceive (
177
+ MSH3_REQUEST* Handle ,
178
+ uint32_t Length
179
+ )
180
+ {
181
+ ((MsH3BiDirStream*)Handle )->CompleteReceive (Length);
182
+ }
183
+
184
+ extern " C"
185
+ void
186
+ MSH3_CALL
187
+ MsH3RequestSetReceiveEnabled (
188
+ MSH3_REQUEST* Handle ,
189
+ bool Enabled
190
+ )
191
+ {
192
+ ((MsH3BiDirStream*)Handle )->SetReceiveEnabled (Enabled);
193
+ }
194
+
173
195
extern " C"
174
196
bool
175
197
MSH3_CALL
@@ -801,10 +823,7 @@ MsH3BiDirStream::MsQuicCallback(
801
823
}
802
824
break ;
803
825
case QUIC_STREAM_EVENT_RECEIVE:
804
- for (uint32_t i = 0 ; i < Event->RECEIVE .BufferCount ; ++i) {
805
- Receive (Event->RECEIVE .Buffers + i);
806
- }
807
- break ;
826
+ return Receive (Event);
808
827
case QUIC_STREAM_EVENT_SEND_COMPLETE:
809
828
if (Event->SEND_COMPLETE .ClientContext ) {
810
829
auto AppSend = (MsH3AppSend*)Event->SEND_COMPLETE .ClientContext ;
@@ -830,71 +849,118 @@ MsH3BiDirStream::MsQuicCallback(
830
849
return QUIC_STATUS_SUCCESS;
831
850
}
832
851
833
- void
852
+ QUIC_STATUS
834
853
MsH3BiDirStream::Receive (
835
- _In_ const QUIC_BUFFER* Buffer
854
+ _Inout_ QUIC_STREAM_EVENT* Event
836
855
)
837
856
{
838
- uint32_t Offset = 0 ;
839
-
840
- do {
841
- if (CurFrameLengthLeft == 0 ) {
842
- if (BufferedHeadersLength == 0 ) {
843
- if (!MsH3VarIntDecode (Buffer->Length , Buffer->Buffer , &Offset, &CurFrameType) ||
844
- !MsH3VarIntDecode (Buffer->Length , Buffer->Buffer , &Offset, &CurFrameLength)) {
845
- BufferedHeadersLength = Buffer->Length - Offset;
846
- memcpy (BufferedHeaders, Buffer->Buffer + Offset, BufferedHeadersLength);
847
- return ;
848
- }
849
- } else {
850
- uint32_t ToCopy = sizeof (BufferedHeaders) - BufferedHeadersLength;
851
- if (ToCopy > Buffer->Length ) ToCopy = Buffer->Length ;
852
- memcpy (BufferedHeaders + BufferedHeadersLength, Buffer->Buffer , ToCopy);
853
- if (!MsH3VarIntDecode (BufferedHeadersLength+ToCopy, BufferedHeaders, &Offset, &CurFrameType) ||
854
- !MsH3VarIntDecode (BufferedHeadersLength+ToCopy, BufferedHeaders, &Offset, &CurFrameLength)) {
855
- BufferedHeadersLength += ToCopy;
856
- return ;
857
+ for (uint32_t i = 0 ; i < Event->RECEIVE .BufferCount ; ++i) {
858
+ const QUIC_BUFFER* Buffer = Event->RECEIVE .Buffers + i;
859
+ do {
860
+ if (CurFrameLengthLeft == 0 ) { // Not in the middle of reading frame payload
861
+ if (BufferedHeadersLength == 0 ) { // No partial frame header bufferred
862
+ if (!MsH3VarIntDecode (Buffer->Length , Buffer->Buffer , &CurRecvOffset, &CurFrameType) ||
863
+ !MsH3VarIntDecode (Buffer->Length , Buffer->Buffer , &CurRecvOffset, &CurFrameLength)) {
864
+ BufferedHeadersLength = Buffer->Length - CurRecvOffset;
865
+ memcpy (BufferedHeaders, Buffer->Buffer + CurRecvOffset, BufferedHeadersLength);
866
+ break ;
867
+ }
868
+ } else { // Partial frame header bufferred already
869
+ uint32_t ToCopy = sizeof (BufferedHeaders) - BufferedHeadersLength;
870
+ if (ToCopy > Buffer->Length ) ToCopy = Buffer->Length ;
871
+ memcpy (BufferedHeaders + BufferedHeadersLength, Buffer->Buffer , ToCopy);
872
+ if (!MsH3VarIntDecode (BufferedHeadersLength+ToCopy, BufferedHeaders, &CurRecvOffset, &CurFrameType) ||
873
+ !MsH3VarIntDecode (BufferedHeadersLength+ToCopy, BufferedHeaders, &CurRecvOffset, &CurFrameLength)) {
874
+ BufferedHeadersLength += ToCopy;
875
+ break ;
876
+ }
877
+ CurRecvOffset -= BufferedHeadersLength;
878
+ BufferedHeadersLength = 0 ;
857
879
}
858
- Offset -= BufferedHeadersLength;
859
- BufferedHeadersLength = 0 ;
880
+ CurFrameLengthLeft = CurFrameLength;
860
881
}
861
- CurFrameLengthLeft = CurFrameLength;
862
- }
863
882
864
- uint32_t AvailFrameLength;
865
- if (Offset + CurFrameLengthLeft > (uint64_t )Buffer->Length ) {
866
- AvailFrameLength = Buffer->Length - Offset ; // Rest of the buffer
867
- } else {
868
- AvailFrameLength = (uint32_t )CurFrameLengthLeft;
869
- }
883
+ uint32_t AvailFrameLength;
884
+ if (CurRecvOffset + CurFrameLengthLeft > (uint64_t )Buffer->Length ) {
885
+ AvailFrameLength = Buffer->Length - CurRecvOffset ; // Rest of the buffer
886
+ } else {
887
+ AvailFrameLength = (uint32_t )CurFrameLengthLeft;
888
+ }
870
889
871
- if (CurFrameType == H3FrameData) {
872
- Callbacks.DataReceived ((MSH3_REQUEST*)this , Context, AvailFrameLength, Buffer->Buffer + Offset);
873
- } else if (CurFrameType == H3FrameHeaders) {
874
- const uint8_t * Frame = Buffer->Buffer + Offset;
875
- if (CurFrameLengthLeft == CurFrameLength) {
876
- auto rhs =
877
- lsqpack_dec_header_in (
878
- &H3.Decoder , this , ID (), (size_t )CurFrameLength, &Frame,
879
- AvailFrameLength, nullptr , nullptr );
880
- if (rhs != LQRHS_DONE && rhs != LQRHS_NEED) {
881
- printf (" lsqpack_dec_header_in failure res=%u\n " , rhs);
890
+ if (CurFrameType == H3FrameData) {
891
+ uint32_t AppReceiveLength = AvailFrameLength;
892
+ ReceivePending = true ;
893
+ if (Callbacks.DataReceived ((MSH3_REQUEST*)this , Context, &AppReceiveLength, Buffer->Buffer + CurRecvOffset)) {
894
+ ReceivePending = false ; // Not pending receive
895
+ if (AppReceiveLength < AvailFrameLength) { // Partial receive case
896
+ CurFrameLengthLeft -= AppReceiveLength;
897
+ Event->RECEIVE .TotalBufferLength = CurRecvCompleteLength + CurRecvOffset + AppReceiveLength;
898
+ CurRecvCompleteLength = 0 ;
899
+ CurRecvOffset = 0 ;
900
+ return QUIC_STATUS_SUCCESS;
901
+ }
902
+ } else { // Receive pending (but may have been completed via API call already)
903
+ if (!ReceivePending) {
904
+ // TODO - Support continuing this receive since it was completed via the API call
905
+ }
906
+ return QUIC_STATUS_PENDING;
882
907
}
883
- } else { // Continued from a previous partial read
884
- auto rhs =
885
- lsqpack_dec_header_read (
886
- &H3.Decoder , this , &Frame, AvailFrameLength, nullptr ,
887
- nullptr );
888
- if (rhs != LQRHS_DONE && rhs != LQRHS_NEED) {
889
- printf (" lsqpack_dec_header_read failure res=%u\n " , rhs);
908
+ } else if (CurFrameType == H3FrameHeaders) {
909
+ const uint8_t * Frame = Buffer->Buffer + CurRecvOffset;
910
+ if (CurFrameLengthLeft == CurFrameLength) {
911
+ auto rhs =
912
+ lsqpack_dec_header_in (
913
+ &H3.Decoder , this , ID (), (size_t )CurFrameLength, &Frame,
914
+ AvailFrameLength, nullptr , nullptr );
915
+ if (rhs != LQRHS_DONE && rhs != LQRHS_NEED) {
916
+ printf (" lsqpack_dec_header_in failure res=%u\n " , rhs);
917
+ }
918
+ } else { // Continued from a previous partial read
919
+ auto rhs =
920
+ lsqpack_dec_header_read (
921
+ &H3.Decoder , this , &Frame, AvailFrameLength, nullptr ,
922
+ nullptr );
923
+ if (rhs != LQRHS_DONE && rhs != LQRHS_NEED) {
924
+ printf (" lsqpack_dec_header_read failure res=%u\n " , rhs);
925
+ }
890
926
}
891
927
}
892
- }
893
928
894
- CurFrameLengthLeft -= AvailFrameLength;
895
- Offset += AvailFrameLength;
929
+ CurFrameLengthLeft -= AvailFrameLength;
930
+ CurRecvOffset += AvailFrameLength;
931
+
932
+ } while (CurRecvOffset < Buffer->Length );
933
+
934
+ CurRecvCompleteLength += Buffer->Length ;
935
+ CurRecvOffset = 0 ;
936
+ }
896
937
897
- } while (Offset < Buffer->Length );
938
+ CurRecvCompleteLength = 0 ;
939
+
940
+ return QUIC_STATUS_SUCCESS;
941
+ }
942
+
943
+ void
944
+ MsH3BiDirStream::CompleteReceive (
945
+ _In_ uint32_t Length
946
+ )
947
+ {
948
+ if (ReceivePending) {
949
+ ReceivePending = false ;
950
+ CurFrameLengthLeft -= Length;
951
+ auto CompleteLength = CurRecvCompleteLength + CurRecvOffset + Length;
952
+ CurRecvCompleteLength = 0 ;
953
+ CurRecvOffset = 0 ;
954
+ (void )ReceiveComplete (CompleteLength);
955
+ }
956
+ }
957
+
958
+ void
959
+ MsH3BiDirStream::SetReceiveEnabled (
960
+ _In_ bool Enabled
961
+ )
962
+ {
963
+ (void )ReceiveSetEnabled (Enabled);
898
964
}
899
965
900
966
struct lsxpack_header *
0 commit comments