@@ -82,3 +82,122 @@ async fn test_reqwest() -> Result<(), reqwest::Error> {
8282
8383 Ok ( ( ) )
8484}
85+
86+ use std:: io:: Write ;
87+ use http_body_util:: BodyExt ;
88+
89+ async fn test_hyper_http ( case : i64 ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
90+ // using http + hyper libs to fetch a web page
91+ let address = "example.com:80" ;
92+ let url = "http://example.com/" ;
93+
94+ // create the connection
95+ println ! ( "connecting to {}..." , address) ;
96+ let stream = tokio:: net:: TcpStream :: connect ( address) . await ?;
97+ let io = hyper_util:: rt:: TokioIo :: new ( stream) ;
98+ let ( mut sender, conn) = hyper:: client:: conn:: http1:: handshake ( io) . await ?;
99+
100+ // drive the HTTP connection
101+ tokio:: task:: spawn ( async move {
102+ conn. await . expect ( "connection failed" ) ;
103+ } ) ;
104+
105+ // make the request
106+ println ! ( "sending request..." ) ;
107+ let request = http:: Request :: builder ( ) . uri ( url) . body ( String :: from ( "" ) ) ?;
108+ let mut response = sender. send_request ( request) . await ?; // $ MISSING: Alert[rust/summary/taint-sources]
109+ sink ( & response) ; // $ MISSING: hasTaintFlow
110+
111+ if !response. status ( ) . is_success ( ) {
112+ return Err ( "request failed" . into ( ) )
113+ }
114+
115+ match case {
116+ 1 => {
117+ sink ( response. body ( ) ) ; // $ MISSING: hasTaintFlow
118+ sink ( response. body_mut ( ) ) ; // $ MISSING: hasTaintFlow
119+
120+ let body = response. into_body ( ) ;
121+ sink ( & body) ; // $ MISSING: hasTaintFlow
122+
123+ println ! ( "awaiting response..." ) ;
124+ let data = body. collect ( ) . await ?;
125+ sink ( & data) ; // $ MISSING: hasTaintFlow
126+
127+ let bytes = data. to_bytes ( ) ;
128+ println ! ( "bytes = {:?}" , & bytes) ;
129+ sink ( bytes) ; // $ MISSING: hasTaintFlow
130+ }
131+ 2 => {
132+ println ! ( "streaming response..." ) ;
133+ while let Some ( frame) = response. frame ( ) . await {
134+ if let Some ( data) = frame?. data_ref ( ) {
135+ std:: io:: stdout ( ) . write_all ( data) ;
136+
137+ sink ( data) ; // $ MISSING: hasTaintFlow
138+ sink ( data[ 0 ] ) ; // $ MISSING: hasTaintFlow
139+ for byte in data {
140+ sink ( byte) ; // $ MISSING: hasTaintFlow
141+ }
142+ }
143+ }
144+ }
145+ 3 => {
146+ let headers = response. headers ( ) ;
147+
148+ if headers. contains_key ( http:: header:: CONTENT_TYPE ) {
149+ println ! ( "CONTENT_TYPE = {}" , response. headers( ) [ http:: header:: CONTENT_TYPE ] . to_str( ) . unwrap( ) ) ;
150+ sink ( & headers[ http:: header:: CONTENT_TYPE ] ) ; // $ MISSING: hasTaintFlow
151+ sink ( headers[ http:: header:: CONTENT_TYPE ] . to_str ( ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
152+ sink ( headers[ http:: header:: CONTENT_TYPE ] . as_bytes ( ) ) ; // $ MISSING: hasTaintFlow
153+ sink ( headers. get ( http:: header:: CONTENT_TYPE ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
154+ }
155+
156+ if headers. contains_key ( "Content-type" ) {
157+ println ! ( "Content-type = {}" , response. headers( ) . get( "Content-type" ) . unwrap( ) . to_str( ) . unwrap( ) ) ;
158+ sink ( headers. get ( "Content-type" ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
159+ sink ( headers. get ( "Content-type" ) . unwrap ( ) . to_str ( ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
160+ sink ( headers. get ( "Content-type" ) . unwrap ( ) . as_bytes ( ) ) ; // $ MISSING: hasTaintFlow
161+ sink ( & headers[ "Content-type" ] ) ; // $ MISSING: hasTaintFlow
162+ }
163+
164+ if headers. contains_key ( http:: header:: COOKIE ) {
165+ sink ( response. headers ( ) . get ( http:: header:: COOKIE ) ) ; // $ MISSING: hasTaintFlow
166+ for cookie in headers. get_all ( http:: header:: COOKIE ) {
167+ println ! ( "cookie = {}" , cookie. to_str( ) . unwrap( ) ) ;
168+ sink ( cookie) ; // $ MISSING: hasTaintFlow
169+ sink ( cookie. to_str ( ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
170+ }
171+ }
172+
173+ let ( parts, body) = response. into_parts ( ) ;
174+
175+ if parts. headers . contains_key ( http:: header:: CONTENT_TYPE ) {
176+ println ! ( "CONTENT_TYPE = {}" , parts. headers[ http:: header:: CONTENT_TYPE ] . to_str( ) . unwrap( ) ) ;
177+ sink ( & parts. headers [ http:: header:: CONTENT_TYPE ] ) ; // $ MISSING: hasTaintFlow
178+ sink ( parts. headers [ http:: header:: CONTENT_TYPE ] . to_str ( ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
179+ sink ( parts. headers [ http:: header:: CONTENT_TYPE ] . as_bytes ( ) ) ; // $ MISSING: hasTaintFlow
180+ sink ( parts. headers . get ( http:: header:: CONTENT_TYPE ) . unwrap ( ) ) ; // $ MISSING: hasTaintFlow
181+ }
182+
183+ sink ( body) ; // $ MISSING: hasTaintFlow
184+ }
185+ _ => { }
186+ }
187+
188+ Ok ( ( ) )
189+ }
190+
191+ #[ tokio:: main]
192+ async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
193+ let case = std:: env:: args ( ) . nth ( 1 ) . unwrap_or ( String :: from ( "1" ) ) . parse :: < i64 > ( ) . unwrap ( ) ; // $ Alert[rust/summary/taint-sources]
194+
195+ println ! ( "test_hyper_http..." ) ;
196+ match futures:: executor:: block_on ( test_hyper_http ( case) ) {
197+ Ok ( _) => println ! ( "complete" ) ,
198+ Err ( e) => println ! ( "error: {}" , e) ,
199+ }
200+ println ! ( "" ) ;
201+
202+ Ok ( ( ) )
203+ }
0 commit comments