Repository: actix/actix-web
File: awc/src/middleware/redirect.rs (Rust)

Code before:
                body,
                addr,
                connector,
            } => match ready!(fut.poll(cx))? {
                ConnectResponse::Client(res) => match res.head().status {
                    StatusCode::MOVED_PERMANENTLY
                    | StatusCode::FOUND
                    | StatusCode::SEE_OTHER
                    | StatusCode::TEMPORARY_REDIRECT
                    | StatusCode::PERMANENT_REDIRECT
                        if *max_redirect_times > 0 =>
                    {
                        let is_redirect = res.head().status == StatusCode::TEMPORARY_REDIRECT
                            || res.head().status == StatusCode::PERMANENT_REDIRECT;

                        let prev_uri = uri.take().unwrap();

                        // rebuild uri from the location header value.
                        let next_uri = build_next_uri(&res, &prev_uri)?;

                        // take ownership of states that could be reused
                        let body = body.take();
                        let addr = addr.take();
                        let connector = connector.take();

                        // reset method
                        let method = if is_redirect {
                            let method = method.take().unwrap();
                            match method {
                                Method::GET | Method::HEAD => method,
                                _ => Method::GET,
                            }
                        } else {
                            method.take().unwrap()
                        };

                        let body_new = if is_redirect {
                            // try to reuse body
                            match body {
                                Some(ref bytes) => Body::Bytes(bytes.clone()),
                                // TODO: should this be Body::Empty or Body::None.
                                _ => Body::Empty,
                            }
                        } else {
                            // remove body
                            Body::None
                        };

                        let mut headers = headers.take().unwrap();

                        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);

Review comment (bug):
maybe i'm reading this wrong (and i think there isn't yet a test for this) but the 307 and 308 status codes should preserve the method, this looks like it's flipped the logic

Code after:
                body,
                addr,
                connector,
            } => match ready!(fut.poll(cx))? {
                ConnectResponse::Client(res) => match res.head().status {
                    StatusCode::MOVED_PERMANENTLY
                    | StatusCode::FOUND
                    | StatusCode::SEE_OTHER
                    | StatusCode::TEMPORARY_REDIRECT
                    | StatusCode::PERMANENT_REDIRECT
                        if *max_redirect_times > 0 =>
                    {
                        let is_redirect = res.head().status == StatusCode::TEMPORARY_REDIRECT
                            || res.head().status == StatusCode::PERMANENT_REDIRECT;

                        let prev_uri = uri.take().unwrap();

                        // rebuild uri from the location header value.
                        let next_uri = build_next_uri(&res, &prev_uri)?;

                        // take ownership of states that could be reused
                        let addr = addr.take();
                        let connector = connector.take();

                        // reset method
                        let method = if is_redirect {
                            method.take().unwrap()
                        } else {
                            let method = method.take().unwrap();
                            match method {
                                Method::GET | Method::HEAD => method,
                                _ => Method::GET,
                            }
                        };

                        let mut body = body.take();
                        let body_new = if is_redirect {
                            // try to reuse body
                            match body {
                                Some(ref bytes) => Body::Bytes(bytes.clone()),
                                // TODO: should this be Body::Empty or Body::None.
                                _ => Body::Empty,
                            }
                        } else {
                            body = None;
                            // remove body
                            Body::None
                        };

                        let mut headers = headers.take().unwrap();