@@ -106,6 +106,7 @@ fn sanitize_uri(mut uri: String) -> String {
106106
107107/// Build a response for `request` and return response based on MMDS version
108108pub fn convert_to_response ( mmds : Arc < Mutex < Mmds > > , request : Request ) -> Response {
109+ // Check URI is not empty
109110 let uri = request. uri ( ) . get_abs_path ( ) ;
110111 if uri. is_empty ( ) {
111112 return build_response (
@@ -118,16 +119,13 @@ pub fn convert_to_response(mmds: Arc<Mutex<Mmds>>, request: Request) -> Response
118119
119120 let mut mmds_guard = mmds. lock ( ) . expect ( "Poisoned lock" ) ;
120121
121- match mmds_guard. version ( ) {
122- MmdsVersion :: V1 => respond_to_request_mmdsv1 ( & mmds_guard, request) ,
123- MmdsVersion :: V2 => respond_to_request_mmdsv2 ( & mut mmds_guard, request) ,
124- }
125- }
126-
127- fn respond_to_request_mmdsv1 ( mmds : & Mmds , request : Request ) -> Response {
128- // Allow only GET requests.
122+ // Allow only GET and PUT requests
129123 match request. method ( ) {
130- Method :: Get => respond_to_get_request_unchecked ( mmds, request) ,
124+ Method :: Get => match mmds_guard. version ( ) {
125+ MmdsVersion :: V1 => respond_to_get_request_v1 ( & mmds_guard, request) ,
126+ MmdsVersion :: V2 => respond_to_get_request_v2 ( & mmds_guard, request) ,
127+ } ,
128+ Method :: Put => respond_to_put_request ( & mut mmds_guard, request) ,
131129 _ => {
132130 let mut response = build_response (
133131 request. http_version ( ) ,
@@ -136,31 +134,18 @@ fn respond_to_request_mmdsv1(mmds: &Mmds, request: Request) -> Response {
136134 Body :: new ( VmmMmdsError :: MethodNotAllowed . to_string ( ) ) ,
137135 ) ;
138136 response. allow_method ( Method :: Get ) ;
137+ response. allow_method ( Method :: Put ) ;
139138 response
140139 }
141140 }
142141}
143142
144- fn respond_to_request_mmdsv2 ( mmds : & mut Mmds , request : Request ) -> Response {
145- // Allow only GET and PUT requests.
146- match request. method ( ) {
147- Method :: Get => respond_to_get_request_checked ( mmds, request) ,
148- Method :: Put => respond_to_put_request ( mmds, request) ,
149- _ => {
150- let mut response = build_response (
151- request. http_version ( ) ,
152- StatusCode :: MethodNotAllowed ,
153- MediaType :: PlainText ,
154- Body :: new ( VmmMmdsError :: MethodNotAllowed . to_string ( ) ) ,
155- ) ;
156- response. allow_method ( Method :: Get ) ;
157- response. allow_method ( Method :: Put ) ;
158- response
159- }
160- }
143+ fn respond_to_get_request_v1 ( mmds : & Mmds , request : Request ) -> Response {
144+ // TODO: Increments metrics that will be added in an upcoming commit.
145+ respond_to_get_request ( mmds, request)
161146}
162147
163- fn respond_to_get_request_checked ( mmds : & Mmds , request : Request ) -> Response {
148+ fn respond_to_get_request_v2 ( mmds : & Mmds , request : Request ) -> Response {
164149 // Check whether a token exists.
165150 let x_metadata_token = XMetadataToken :: from ( request. headers . custom_entries ( ) ) ;
166151 let token = match x_metadata_token. 0 {
@@ -178,18 +163,17 @@ fn respond_to_get_request_checked(mmds: &Mmds, request: Request) -> Response {
178163
179164 // Validate the token.
180165 match mmds. is_valid_token ( & token) {
181- Ok ( true ) => respond_to_get_request_unchecked ( mmds, request) ,
182- Ok ( false ) => build_response (
166+ true => respond_to_get_request ( mmds, request) ,
167+ false => build_response (
183168 request. http_version ( ) ,
184169 StatusCode :: Unauthorized ,
185170 MediaType :: PlainText ,
186171 Body :: new ( VmmMmdsError :: InvalidToken . to_string ( ) ) ,
187172 ) ,
188- Err ( _) => unreachable ! ( ) ,
189173 }
190174}
191175
192- fn respond_to_get_request_unchecked ( mmds : & Mmds , request : Request ) -> Response {
176+ fn respond_to_get_request ( mmds : & Mmds , request : Request ) -> Response {
193177 let uri = request. uri ( ) . get_abs_path ( ) ;
194178
195179 // The data store expects a strict json path, so we need to
@@ -465,8 +449,7 @@ mod tests {
465449 // Set version to V1.
466450 mmds. lock ( )
467451 . expect ( "Poisoned lock" )
468- . set_version ( MmdsVersion :: V1 )
469- . unwrap ( ) ;
452+ . set_version ( MmdsVersion :: V1 ) ;
470453 assert_eq ! (
471454 mmds. lock( ) . expect( "Poisoned lock" ) . version( ) ,
472455 MmdsVersion :: V1
@@ -494,7 +477,7 @@ mod tests {
494477 assert_eq ! ( actual_response, expected_response) ;
495478
496479 // Test not allowed HTTP Method.
497- let not_allowed_methods = [ "PUT" , " PATCH"] ;
480+ let not_allowed_methods = [ "PATCH" ] ;
498481 for method in not_allowed_methods. iter ( ) {
499482 let request = Request :: try_from (
500483 format ! ( "{method} http://169.254.169.255/ HTTP/1.0\r \n \r \n " ) . as_bytes ( ) ,
@@ -506,6 +489,7 @@ mod tests {
506489 expected_response. set_content_type ( MediaType :: PlainText ) ;
507490 expected_response. set_body ( Body :: new ( VmmMmdsError :: MethodNotAllowed . to_string ( ) ) ) ;
508491 expected_response. allow_method ( Method :: Get ) ;
492+ expected_response. allow_method ( Method :: Put ) ;
509493 let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
510494 assert_eq ! ( actual_response, expected_response) ;
511495 }
@@ -528,12 +512,47 @@ mod tests {
528512 let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
529513 assert_eq ! ( actual_response, expected_response) ;
530514
531- // Test Ok path .
515+ // Test valid v1 request .
532516 let ( request, expected_response) = generate_request_and_expected_response (
533517 b"GET http://169.254.169.254/ HTTP/1.0\r \n \
534518 Accept: application/json\r \n \r \n ",
535519 MediaType :: ApplicationJson ,
536520 ) ;
521+ let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
522+ assert_eq ! ( actual_response, expected_response) ;
523+
524+ // Test valid v2 request.
525+ let request = Request :: try_from (
526+ b"PUT http://169.254.169.254/latest/api/token HTTP/1.0\r \n \
527+ X-metadata-token-ttl-seconds: 60\r \n \r \n ",
528+ None ,
529+ )
530+ . unwrap ( ) ;
531+ let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
532+ assert_eq ! ( actual_response. status( ) , StatusCode :: OK ) ;
533+ assert_eq ! ( actual_response. content_type( ) , MediaType :: PlainText ) ;
534+
535+ let valid_token = String :: from_utf8 ( actual_response. body ( ) . unwrap ( ) . body ) . unwrap ( ) ;
536+ #[ rustfmt:: skip]
537+ let ( request, expected_response) = generate_request_and_expected_response (
538+ format ! (
539+ "GET http://169.254.169.254/ HTTP/1.0\r \n \
540+ Accept: application/json\r \n \
541+ X-metadata-token: {valid_token}\r \n \r \n ",
542+ )
543+ . as_bytes ( ) ,
544+ MediaType :: ApplicationJson ,
545+ ) ;
546+ let actual_response = convert_to_response ( mmds. clone ( ) , request) ;
547+ assert_eq ! ( actual_response, expected_response) ;
548+
549+ // Test GET request with invalid token is accepted when v1 is configured.
550+ let ( request, expected_response) = generate_request_and_expected_response (
551+ b"GET http://169.254.169.254/ HTTP/1.0\r \n \
552+ Accept: application/json\r \n \
553+ X-metadata-token: INVALID_TOKEN\r \n \r \n ",
554+ MediaType :: ApplicationJson ,
555+ ) ;
537556 let actual_response = convert_to_response ( mmds, request) ;
538557 assert_eq ! ( actual_response, expected_response) ;
539558 }
@@ -546,8 +565,7 @@ mod tests {
546565 // Set version to V2.
547566 mmds. lock ( )
548567 . expect ( "Poisoned lock" )
549- . set_version ( MmdsVersion :: V2 )
550- . unwrap ( ) ;
568+ . set_version ( MmdsVersion :: V2 ) ;
551569 assert_eq ! (
552570 mmds. lock( ) . expect( "Poisoned lock" ) . version( ) ,
553571 MmdsVersion :: V2
0 commit comments