I ask for your help to understand part of the specification of the FastCGI protocol.
Currently this is the code I have:
#![allow(non_snake_case)]
#![allow(unused_must_use)]
use std::os::unix::net::{UnixStream};
use std::io::{Read, Write};
fn main() {
pub const FCGI_VERSION_1: u8 = 1;
pub const FCGI_BEGIN_REQUEST:u8 = 1;
pub const FCGI_RESPONDER: u16 = 1;
pub const FCGI_PARAMS: &str = "FCGI_PARAMS";
let socket_path = "/run/php-fpm/php-fpm.sock";
let mut socket = match UnixStream::connect(socket_path) {
Ok(sock) => sock,
Err(e) => {
println!("Couldn't connect: {e:?}");
return
}
};
let requestId: u16 = 1;
let role: u16 = FCGI_RESPONDER;
let beginRequest = vec![
// FCGI_Header
FCGI_VERSION_1, FCGI_BEGIN_REQUEST,
(requestId >> 8) as u8, (requestId & 0xFF) as u8,
0x00, 0x08, // This is the size of `FCGI_BeginRequestBody`
0, 0,
// FCGI_BeginRequestBody
(role >> 8) as u8, (role & 0xFF) as u8,
0, // Flags
0, 0, 0, 0, 0, // Reserved
];
socket.write_all(&beginRequest).unwrap();
let data = vec![
(100) as u8, // this value is just an example
];
let contentLength = data.len();
assert!(contentLength <= usize::MAX);
let requestHeader = vec![
FCGI_VERSION_1, FCGI_BEGIN_REQUEST,
(requestId >> 8) as u8, (requestId & 0xFF) as u8,
(contentLength >> 8) as u8, (contentLength & 0xFF) as u8,
0, 0,
];
socket.write_all(&requestHeader).unwrap();
}
I have this code thanks to the answer of my last question related to this topic, so, with that example code (which works perfectly for me) I would like to ask you my question.
How can I write the FCGI_PARAMS?
I mean, if I understand correctly, the documentation says:
FCGI_PARAMS is a stream record type used in sending name-value pairs from the Web server to the application
This means that the FCGI_PARAMS
are Name-Value Pairs. And the part of the documentation that describes the Name-Value Pairs
says:
FastCGI transmits a name-value pair as the length of the name, followed by the length of the value, followed by the name, followed by the value
Then this way I think that it would be (represented in code):
let param = vec![
"SCRIPT_FILENAME".len(),
"index.php".len(),
"SCRIPT_FILENAME",
"index.php",
]; // it is just an example, but i think it represents what i am talking about
But if I add this code, and then I write it to the socket with the following line:
socket.write_all(¶m);
And then when reading the socket, the socket does not return anything. What am I doing wrong? How should I send the data? I hope you can help me with this, I want to clarify that I am quite new to FastCGI
and unix sockets
so I am very sorry if any line of my displayed code is poorly exemplified.
CodePudding user response:
Rust doesn't support heterogeneous vectors, so your let param =…
shouldn't compile. The way to send the params is to use multiple writes:
let param_name = "SCRIPT_FILENAME".as_bytes(); // could also be written `b"SCRIPT_FILENAME"`
let param_value = "index.php".as_bytes();
let lengths = [ param_name.len() as u8, param_value.len() as u8 ];
socket.write_all (&lengths).unwrap();
socket.write_all (param_name).unwrap();
socket.write_all (param_value).unwrap();