2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
4
use std:: collections:: VecDeque ;
5
+ use std:: fs:: File ;
5
6
use std:: io:: { Read , Write } ;
6
7
7
8
use crate :: common:: ascii:: { CR , CRLF_LEN , LF } ;
@@ -50,6 +51,9 @@ pub struct HttpConnection<T> {
50
51
/// A buffer containing the bytes of a response that is currently
51
52
/// being sent.
52
53
response_buffer : Option < Vec < u8 > > ,
54
+ /// The latest file that has been received and which must be associated
55
+ /// with the pending request.
56
+ file : Option < File > ,
53
57
}
54
58
55
59
impl < T : Read + Write + ScmSocket > HttpConnection < T > {
@@ -66,6 +70,7 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
66
70
parsed_requests : VecDeque :: new ( ) ,
67
71
response_queue : VecDeque :: new ( ) ,
68
72
response_buffer : None ,
73
+ file : None ,
69
74
}
70
75
}
71
76
@@ -107,8 +112,9 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
107
112
// the `parsed_requests` queue.
108
113
self . state = ConnectionState :: WaitingForRequestLine ;
109
114
self . body_bytes_to_be_read = 0 ;
110
- self . parsed_requests
111
- . push_back ( self . pending_request . take ( ) . unwrap ( ) ) ;
115
+ let mut pending_request = self . pending_request . take ( ) . unwrap ( ) ;
116
+ pending_request. file = self . file . take ( ) ;
117
+ self . parsed_requests . push_back ( pending_request) ;
112
118
}
113
119
} ;
114
120
}
@@ -127,11 +133,16 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
127
133
}
128
134
// Append new bytes to what we already have in the buffer.
129
135
// The slice access is safe, the index is checked above.
130
- let ( bytes_read, _ ) = self
136
+ let ( bytes_read, file ) = self
131
137
. stream
132
138
. recv_with_fd ( & mut self . buffer [ self . read_cursor ..] )
133
139
. map_err ( ConnectionError :: StreamReadError ) ?;
134
140
141
+ // Update the internal file that must be associated with the request.
142
+ if file. is_some ( ) {
143
+ self . file = file;
144
+ }
145
+
135
146
// If the read returned 0 then the client has closed the connection.
136
147
if bytes_read == 0 {
137
148
return Err ( ConnectionError :: ConnectionClosed ) ;
@@ -176,6 +187,7 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
176
187
. map_err ( ConnectionError :: ParseError ) ?,
177
188
headers : Headers :: default ( ) ,
178
189
body : None ,
190
+ file : None ,
179
191
} ) ;
180
192
self . state = ConnectionState :: WaitingForHeaders ;
181
193
Ok ( true )
@@ -517,6 +529,7 @@ mod tests {
517
529
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
518
530
headers : Headers :: new ( 26 , true , true ) ,
519
531
body : Some ( Body :: new ( b"this is not\n \r \n a json \n body" . to_vec ( ) ) ) ,
532
+ file : None ,
520
533
} ;
521
534
522
535
assert_eq ! ( request, expected_request) ;
@@ -553,6 +566,7 @@ mod tests {
553
566
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
554
567
headers : Headers :: new ( 26 , true , true ) ,
555
568
body : Some ( Body :: new ( b"this is not\n \r \n a json \n body" . to_vec ( ) ) ) ,
569
+ file : None ,
556
570
} ;
557
571
assert_eq ! ( request, expected_request) ;
558
572
}
@@ -586,6 +600,7 @@ mod tests {
586
600
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
587
601
headers : Headers :: new ( 26 , true , true ) ,
588
602
body : Some ( Body :: new ( b"this is not\n \r \n a json \n body" . to_vec ( ) ) ) ,
603
+ file : None ,
589
604
} ;
590
605
assert_eq ! ( request, expected_request) ;
591
606
}
@@ -650,6 +665,7 @@ mod tests {
650
665
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
651
666
headers : Headers :: new ( 1400 , true , true ) ,
652
667
body : Some ( Body :: new ( request_body) ) ,
668
+ file : None ,
653
669
} ;
654
670
655
671
assert_eq ! ( request, expected_request) ;
@@ -720,6 +736,7 @@ mod tests {
720
736
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
721
737
headers : Headers :: new ( 0 , true , true ) ,
722
738
body : None ,
739
+ file : None ,
723
740
} ;
724
741
assert_eq ! ( request, expected_request) ;
725
742
}
@@ -741,6 +758,7 @@ mod tests {
741
758
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
742
759
headers : Headers :: new ( 0 , false , false ) ,
743
760
body : None ,
761
+ file : None ,
744
762
} ;
745
763
assert_eq ! ( request, expected_request) ;
746
764
}
@@ -769,6 +787,7 @@ mod tests {
769
787
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
770
788
headers : Headers :: new ( 0 , false , false ) ,
771
789
body : None ,
790
+ file : None ,
772
791
} ;
773
792
assert_eq ! ( request, expected_request) ;
774
793
@@ -787,6 +806,7 @@ mod tests {
787
806
) ,
788
807
headers : Headers :: new ( 0 , false , false ) ,
789
808
body : None ,
809
+ file : None ,
790
810
} ;
791
811
assert_eq ! ( request, expected_request) ;
792
812
}
@@ -814,6 +834,7 @@ mod tests {
814
834
request_line : RequestLine :: new ( Method :: Patch , "http://localhost/home" , Version :: Http11 ) ,
815
835
headers : Headers :: new ( 26 , false , true ) ,
816
836
body : Some ( Body :: new ( b"this is not\n \r \n a json \n body" . to_vec ( ) ) ) ,
837
+ file : None ,
817
838
} ;
818
839
819
840
conn. try_read ( ) . unwrap ( ) ;
@@ -824,6 +845,7 @@ mod tests {
824
845
request_line : RequestLine :: new ( Method :: Put , "http://farhost/away" , Version :: Http11 ) ,
825
846
headers : Headers :: new ( 23 , false , false ) ,
826
847
body : Some ( Body :: new ( b"this is another request" . to_vec ( ) ) ) ,
848
+ file : None ,
827
849
} ;
828
850
assert_eq ! ( request_first, expected_request_first) ;
829
851
assert_eq ! ( request_second, expected_request_second) ;
@@ -1036,6 +1058,7 @@ mod tests {
1036
1058
request_line : RequestLine :: new ( Method :: Get , "http://foo/bar" , Version :: Http11 ) ,
1037
1059
headers : Headers :: new ( 0 , true , true ) ,
1038
1060
body : None ,
1061
+ file : None ,
1039
1062
} ) ;
1040
1063
assert_eq ! (
1041
1064
conn. parse_headers( & mut 0 , BUFFER_SIZE ) . unwrap_err( ) ,
@@ -1093,6 +1116,7 @@ mod tests {
1093
1116
request_line : RequestLine :: new ( Method :: Get , "http://foo/bar" , Version :: Http11 ) ,
1094
1117
headers : Headers :: new ( 0 , true , true ) ,
1095
1118
body : None ,
1119
+ file : None ,
1096
1120
} ) ;
1097
1121
conn. body_vec = vec ! [ 0xde , 0xad , 0xbe , 0xef ] ;
1098
1122
assert_eq ! (
0 commit comments