@@ -108,6 +108,7 @@ fn sanitize_uri(mut uri: String) -> String {
108108
109109/// Build a response for `request` and return response based on MMDS version
110110pub fn convert_to_response ( mmds : Arc < Mutex < Mmds > > , request : Request ) -> Response {
111+ // Check URI is not empty
111112 let uri = request. uri ( ) . get_abs_path ( ) ;
112113 if uri. is_empty ( ) {
113114 return build_response (
@@ -120,16 +121,13 @@ pub fn convert_to_response(mmds: Arc<Mutex<Mmds>>, request: Request) -> Response
120121
121122 let mut mmds_guard = mmds. lock ( ) . expect ( "Poisoned lock" ) ;
122123
123- match mmds_guard. version ( ) {
124- MmdsVersion :: V1 => respond_to_request_mmdsv1 ( & mmds_guard, request) ,
125- MmdsVersion :: V2 => respond_to_request_mmdsv2 ( & mut mmds_guard, request) ,
126- }
127- }
128-
129- fn respond_to_request_mmdsv1 ( mmds : & Mmds , request : Request ) -> Response {
130- // Allow only GET requests.
124+ // Allow only GET and PUT requests
131125 match request. method ( ) {
132- Method :: Get => respond_to_get_request_unchecked ( mmds, request) ,
126+ Method :: Get => match mmds_guard. version ( ) {
127+ MmdsVersion :: V1 => respond_to_get_request_v1 ( & mmds_guard, request) ,
128+ MmdsVersion :: V2 => respond_to_get_request_v2 ( & mmds_guard, request) ,
129+ } ,
130+ Method :: Put => respond_to_put_request ( & mut mmds_guard, request) ,
133131 _ => {
134132 let mut response = build_response (
135133 request. http_version ( ) ,
@@ -138,31 +136,18 @@ fn respond_to_request_mmdsv1(mmds: &Mmds, request: Request) -> Response {
138136 Body :: new ( VmmMmdsError :: MethodNotAllowed . to_string ( ) ) ,
139137 ) ;
140138 response. allow_method ( Method :: Get ) ;
139+ response. allow_method ( Method :: Put ) ;
141140 response
142141 }
143142 }
144143}
145144
146- fn respond_to_request_mmdsv2 ( mmds : & mut Mmds , request : Request ) -> Response {
147- // Allow only GET and PUT requests.
148- match request. method ( ) {
149- Method :: Get => respond_to_get_request_checked ( mmds, request) ,
150- Method :: Put => respond_to_put_request ( mmds, request) ,
151- _ => {
152- let mut response = build_response (
153- request. http_version ( ) ,
154- StatusCode :: MethodNotAllowed ,
155- MediaType :: PlainText ,
156- Body :: new ( VmmMmdsError :: MethodNotAllowed . to_string ( ) ) ,
157- ) ;
158- response. allow_method ( Method :: Get ) ;
159- response. allow_method ( Method :: Put ) ;
160- response
161- }
162- }
145+ fn respond_to_get_request_v1 ( mmds : & Mmds , request : Request ) -> Response {
146+ // TODO: Increments metrics that will be added in an upcoming commit.
147+ respond_to_get_request ( mmds, request)
163148}
164149
165- fn respond_to_get_request_checked ( mmds : & Mmds , request : Request ) -> Response {
150+ fn respond_to_get_request_v2 ( mmds : & Mmds , request : Request ) -> Response {
166151 // Check whether a token exists.
167152 let token = match get_header_value_pair (
168153 request. headers . custom_entries ( ) ,
@@ -182,18 +167,17 @@ fn respond_to_get_request_checked(mmds: &Mmds, request: Request) -> Response {
182167
183168 // Validate the token.
184169 match mmds. is_valid_token ( & token) {
185- Ok ( true ) => respond_to_get_request_unchecked ( mmds, request) ,
186- Ok ( false ) => build_response (
170+ true => respond_to_get_request ( mmds, request) ,
171+ false => build_response (
187172 request. http_version ( ) ,
188173 StatusCode :: Unauthorized ,
189174 MediaType :: PlainText ,
190175 Body :: new ( VmmMmdsError :: InvalidToken . to_string ( ) ) ,
191176 ) ,
192- Err ( _) => unreachable ! ( ) ,
193177 }
194178}
195179
196- fn respond_to_get_request_unchecked ( mmds : & Mmds , request : Request ) -> Response {
180+ fn respond_to_get_request ( mmds : & Mmds , request : Request ) -> Response {
197181 let uri = request. uri ( ) . get_abs_path ( ) ;
198182
199183 // The data store expects a strict json path, so we need to
@@ -483,8 +467,7 @@ mod tests {
483467 // Set version to V1.
484468 mmds. lock ( )
485469 . expect ( "Poisoned lock" )
486- . set_version ( MmdsVersion :: V1 )
487- . unwrap ( ) ;
470+ . set_version ( MmdsVersion :: V1 ) ;
488471 assert_eq ! (
489472 mmds. lock( ) . expect( "Poisoned lock" ) . version( ) ,
490473 MmdsVersion :: V1
@@ -512,7 +495,7 @@ mod tests {
512495 assert_eq ! ( actual_response, expected_response) ;
513496
514497 // Test not allowed HTTP Method.
515- let not_allowed_methods = [ "PUT" , " PATCH"] ;
498+ let not_allowed_methods = [ "PATCH" ] ;
516499 for method in not_allowed_methods. iter ( ) {
517500 let request = Request :: try_from (
518501 format ! ( "{method} http://169.254.169.255/ HTTP/1.0\r \n \r \n " ) . as_bytes ( ) ,
@@ -524,6 +507,7 @@ mod tests {
524507 expected_response. set_content_type ( MediaType :: PlainText ) ;
525508 expected_response. set_body ( Body :: new ( VmmMmdsError :: MethodNotAllowed . to_string ( ) ) ) ;
526509 expected_response. allow_method ( Method :: Get ) ;
510+ expected_response. allow_method ( Method :: Put ) ;
527511 let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
528512 assert_eq ! ( actual_response, expected_response) ;
529513 }
@@ -546,12 +530,47 @@ mod tests {
546530 let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
547531 assert_eq ! ( actual_response, expected_response) ;
548532
549- // Test Ok path .
533+ // Test valid v1 request .
550534 let ( request, expected_response) = generate_request_and_expected_response (
551535 b"GET http://169.254.169.254/ HTTP/1.0\r \n \
552536 Accept: application/json\r \n \r \n ",
553537 MediaType :: ApplicationJson ,
554538 ) ;
539+ let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
540+ assert_eq ! ( actual_response, expected_response) ;
541+
542+ // Test valid v2 request.
543+ let request = Request :: try_from (
544+ b"PUT http://169.254.169.254/latest/api/token HTTP/1.0\r \n \
545+ X-metadata-token-ttl-seconds: 60\r \n \r \n ",
546+ None ,
547+ )
548+ . unwrap ( ) ;
549+ let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
550+ assert_eq ! ( actual_response. status( ) , StatusCode :: OK ) ;
551+ assert_eq ! ( actual_response. content_type( ) , MediaType :: PlainText ) ;
552+
553+ let valid_token = String :: from_utf8 ( actual_response. body ( ) . unwrap ( ) . body ) . unwrap ( ) ;
554+ #[ rustfmt:: skip]
555+ let ( request, expected_response) = generate_request_and_expected_response (
556+ format ! (
557+ "GET http://169.254.169.254/ HTTP/1.0\r \n \
558+ Accept: application/json\r \n \
559+ X-metadata-token: {valid_token}\r \n \r \n ",
560+ )
561+ . as_bytes ( ) ,
562+ MediaType :: ApplicationJson ,
563+ ) ;
564+ let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
565+ assert_eq ! ( actual_response, expected_response) ;
566+
567+ // Test GET request with invalid token is accepted when v1 is configured.
568+ let ( request, expected_response) = generate_request_and_expected_response (
569+ b"GET http://169.254.169.254/ HTTP/1.0\r \n \
570+ Accept: application/json\r \n \
571+ X-metadata-token: INVALID_TOKEN\r \n \r \n ",
572+ MediaType :: ApplicationJson ,
573+ ) ;
555574 let actual_response = convert_to_response ( mmds, request) ;
556575 assert_eq ! ( actual_response, expected_response) ;
557576 }
@@ -564,8 +583,7 @@ mod tests {
564583 // Set version to V2.
565584 mmds. lock ( )
566585 . expect ( "Poisoned lock" )
567- . set_version ( MmdsVersion :: V2 )
568- . unwrap ( ) ;
586+ . set_version ( MmdsVersion :: V2 ) ;
569587 assert_eq ! (
570588 mmds. lock( ) . expect( "Poisoned lock" ) . version( ) ,
571589 MmdsVersion :: V2
0 commit comments