When working with Actix-Web, we sometimes need to access incoming HTTP requests to inspect for some values. In that case, we need to use the HttpRequest struct either in request handlers and middlewares.
Cargo.toml
We will use the following dependencies for the code examples.
1 2 3 4 5 6 7 8 9 | [package] name = "actix-web-http-request-and-response" version = "0.1.0" authors = ["Karl San Gabriel"] edition = "2018" [dependencies] actix-web = "2.0.0" actix-rt = "1.1.1" |
HTTP Requests in Middlewares
In middlewares, HTTP requests are accessible via the request-wrapper ServiceRequest struct. It has public functions with the same signature as those of the HttpRequest’s.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ... /// An service http request /// /// ServiceRequest allows mutable access to request's internal structures pub struct ServiceRequest(HttpRequest); impl ServiceRequest { /// Construct service request pub(crate) fn new(req: HttpRequest) -> Self { ServiceRequest(req) } /// Deconstruct request into parts pub fn into_parts(mut self) -> (HttpRequest, Payload) { let pl = Rc::get_mut(&mut (self.0).0).unwrap().payload.take(); (self.0, pl) } ... #[inline] pub fn uri(&self) -> &Uri { &self.head().uri } /// Read the Request method. #[inline] pub fn method(&self) -> &Method { &self.head().method } /// Read the Request Version. #[inline] pub fn version(&self) -> Version { self.head().version } #[inline] /// Returns request's headers. pub fn headers(&self) -> &HeaderMap { &self.head().headers } ... |
See Actix-Web Basic And Bearer Authentication Examples for sample middlewares.
HTTP Requests in Request Handlers
With request handlers, we only need to specify the HttpRequest struct as one of the function arguments. Consider the following function that does not include HttpRequest in its argument list.
1 2 3 4 5 | #[get("/persons/{id}")] async fn persons_with_id_handler(info: web::Path<(u32)>) -> impl Responder { let person_id = info.into_inner(); web::Json(vec![person_id]) } |
We can change the function signature to accept an instance of HttpRequest struct.
1 2 3 4 5 | #[get("/persons/{id}")] async fn persons_with_id_handler(req: HttpRequest, info: web::Path<(u32)>) -> impl Responder { let person_id = info.into_inner(); web::Json(vec![person_id]) } |
Working With HTTP Request Headers
To display HTTP request headers, we can loop through an instance of HeaderMap.
1 2 3 | for header in req.headers().into_iter() { println!("{:?} = {:?}", header.0, header.1); } |
The output is as follows.
1 2 3 4 5 6 7 8 9 10 11 12 | "accept" = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" "sec-fetch-user" = "?1" "accept-language" = "en-US,en;q=0.9" "cache-control" = "max-age=0" "sec-fetch-mode" = "navigate" "sec-fetch-site" = "cross-site" "accept-encoding" = "gzip, deflate, br" "host" = "127.0.0.1:8080" "user-agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36" "connection" = "keep-alive" "upgrade-insecure-requests" = "1" "sec-fetch-dest" = "document" |
Get the HTTP Request URI
To display the HTTP request URI in Actix-Web, we can use the following codes.
1 2 3 | println!("{:?}", req.head().uri); println!("{:?}", req.uri()); println!("{:?}", req.path()); |
The output is as follows.
1 2 3 | /persons/2 /persons/2 /persons/2 |
Get the HTTP Request Method
To display the HTTP method, we can use the following codes.
1 2 | println!("{:?}", req.head().method); println!("{:?}", req.method()); |
The output is as follows.
1 2 | GET GET |
Get HTTP Version
To display the HTTP version, we use the following codes.
1 2 | println!("{:?}", req.head().version); println!("{:?}", req.version()); |
The generated output is as follows.
1 2 | HTTP/1.1 HTTP/1.1 |
Get HTTP Peer Address
The peer address means socket address. It specifies the IP (Internet Protocol) version, the remote IP address, and the server port the request went through.
1 2 | println!("{:?}", req.head().peer_addr); println!("{:?}", req.peer_addr()); |
The output is as follows.
1 2 | Some(V4(127.0.0.1:57985)) Some(V4(127.0.0.1:57985)) |
Get Host Name in Actix-Web
Aside from the HTTP headers, the hostname is also available via Actix-Web’s AppConfig.
1 2 | // Output: 127.0.0.1:8080 println!("{:?}", req.app_config().host()); |
Working with AppConfig to Check For Secure Connections
We can also check if Actix-Web using HTTPS, and the requests come in from a secure connection.
1 2 | // false when SSL is not configured println!("{:?}", req.app_config().secure()); |
To test with a secure Actix-Web, please see Secure Actix-Web Application With TLS.
Working with Actix-Web HTTP requests via the HttpRequest may not be for everyone. But when we write applications that rely on HTTP-related information, the HttpRequest struct is the only way to access that information.