fn build_headers(
        &self,
        req: &Parts,
        content_length: usize,
        client_addr: SocketAddr,
    ) -> HashMap<String, String> {
        // Note that we put these first so that there is no chance that they overwrite
        // the built-in vars. IMPORTANT: This is also why some values have empty strings
        // deliberately set (as opposed to omiting the pair altogether).
        let mut headers = self.environment.clone().unwrap_or_default();

        let host = req
            .headers
            .get(HOST)
            .map(|val| val.to_str().unwrap_or("localhost"))
            .unwrap_or("localhost")
            .to_owned();

        // CGI headers from RFC
        headers.insert("AUTH_TYPE".to_owned(), "".to_owned()); // Not currently supported

        // CONTENT_LENGTH (from the spec)
        // The server MUST set this meta-variable if and only if the request is
        // accompanied by a message-body entity.  The CONTENT_LENGTH value must
        // reflect the length of the message-body after the server has removed
        // any transfer-codings or content-codings.
        headers.insert("CONTENT_LENGTH".to_owned(), format!("{}", content_length));

        // CONTENT_TYPE (from the spec)
        // The server MUST set this meta-variable if an HTTP Content-Type field is present
        // in the client request header.  If the server receives a request with an
        // attached entity but no Content-Type header field, it MAY attempt to determine
        // the correct content type, otherwise it should omit this meta-variable.
        //
        // Right now, we don't attempt to determine a media type if none is presented.
        //
        // The spec seems to indicate that if CONTENT_LENGTH > 0, this may be set
        // to "application/octet-stream" if no type is otherwise set. Not sure that is
        // a good idea.
        headers.insert(
            "CONTENT_TYPE".to_owned(),
            req.headers
                .get("CONTENT_TYPE")
                .map(|c| c.to_str().unwrap_or(""))
                .unwrap_or("")
                .to_owned(),
        );

        // Since this is not in the specification, an X_ is prepended, per spec.
        // NB: It is strange that there is not a way to do this already. The Display impl
        // seems to only provide the path.
        let uri = req.uri.clone();
        headers.insert(
            "X_FULL_URL".to_owned(),
            format!(
                "{}://{}{}",
                uri.scheme_str().unwrap_or("http"), // It is not clear if Hyper ever sets scheme.
                uri.authority()
                    .map(|a| a.as_str())
                    .unwrap_or_else(|| host.as_str()),
                uri.path_and_query().map(|pq| pq.as_str()).unwrap_or("")
            ),
        );

        headers.insert("GATEWAY_INTERFACE".to_owned(), WAGI_VERSION.to_owned());
        headers.insert("X_MATCHED_ROUTE".to_owned(), self.route.to_owned()); // Specific to WAGI (not CGI)
        headers.insert("PATH_INFO".to_owned(), req.uri.path().to_owned()); // TODO: Does this get trimmed?

        // NOTE: The security model of WAGI means that we do not give the actual
        // translated path on the host filesystem, as that is off limits to the runtime.
        // Right now, this just returns the same as PATH_INFO, but we could attempt to
        // map it to something if we know what that "something" is.
        headers.insert("PATH_TRANSLATED".to_owned(), req.uri.path().to_owned());
        headers.insert(
            "QUERY_STRING".to_owned(),
            req.uri.query().unwrap_or("").to_owned(),
        );

        headers.insert("REMOTE_ADDR".to_owned(), client_addr.ip().to_string());
        headers.insert("REMOTE_HOST".to_owned(), client_addr.ip().to_string()); // The server MAY substitute it with REMOTE_ADDR
        headers.insert("REMOTE_USER".to_owned(), "".to_owned()); // TODO: Parse this out of uri.authority?
        headers.insert("REQUEST_METHOD".to_owned(), req.method.to_string());
        headers.insert("SCRIPT_NAME".to_owned(), self.module.to_owned());
        // From the spec: "the server would use the contents of the request's Host header
        // field to select the correct virtual host."
        headers.insert("SERVER_NAME".to_owned(), host);
        headers.insert(
            "SERVER_PORT".to_owned(),
            req.uri
                .port()
                .map(|p| p.to_string())
                .unwrap_or_else(|| "80".to_owned()),
        );
        headers.insert(
            "SERVER_PROTOCOL".to_owned(),
            req.uri
                .scheme()
                .unwrap_or(&Scheme::HTTP)
                .as_str()
                .to_owned(),
        );

        headers.insert(
            "SERVER_SOFTWARE".to_owned(),
            SERVER_SOFTWARE_VERSION.to_owned(),
        );

        // Normalize incoming HTTP headers. The spec says:
        // "The HTTP header field name is converted to upper case, has all
        // occurrences of "-" replaced with "_" and has "HTTP_" prepended to
        // give the meta-variable name."
        req.headers.iter().for_each(|header| {
            let key = format!(
                "HTTP_{}",
                header.0.as_str().to_uppercase().replace("-", "_")
            );
            // Per spec 4.1.18, skip some headers
            if key == "HTTP_AUHTORIZATION" || key == "HTTP_CONNECTION" {
                return;
            }
            let val = header.1.to_str().unwrap_or("CORRUPT VALUE").to_owned();
            headers.insert(key, val);
        });

        headers
    }
/// Build the WAGI headers for injection into a module.
Build the WAGI headers for injection into a module.
Build the WAGI headers for injection into a module .
fn build_headers(
        &self,
        req: &Parts,
        content_length: usize,
        client_addr: SocketAddr,
    ) -> HashMap<String, String> {
        // Note that we put these first so that there is no chance that they overwrite
        // the built-in vars. IMPORTANT: This is also why some values have empty strings
        // deliberately set (as opposed to omiting the pair altogether).
        let mut headers = self.environment.clone().unwrap_or_default();
        let host = req
            .headers
            .get(HOST)
            .map(|val| val.to_str().unwrap_or("localhost"))
            .unwrap_or("localhost")
            .to_owned();
        // CGI headers from RFC
        headers.insert("AUTH_TYPE".to_owned(), "".to_owned()); // Not currently supported
        // CONTENT_LENGTH (from the spec)
        // The server MUST set this meta-variable if and only if the request is
        // accompanied by a message-body entity.  The CONTENT_LENGTH value must
        // reflect the length of the message-body after the server has removed
        // any transfer-codings or content-codings.
        headers.insert("CONTENT_LENGTH".to_owned(), format!("{}", content_length));
        // CONTENT_TYPE (from the spec)
        // The server MUST set this meta-variable if an HTTP Content-Type field is present
        // in the client request header.  If the server receives a request with an
        // attached entity but no Content-Type header field, it MAY attempt to determine
        // the correct content type, otherwise it should omit this meta-variable.
        //
        // Right now, we don't attempt to determine a media type if none is presented.
        //
        // The spec seems to indicate that if CONTENT_LENGTH > 0, this may be set
        // to "application/octet-stream" if no type is otherwise set. Not sure that is
        // a good idea.
        headers.insert(
            "CONTENT_TYPE".to_owned(),
            req.headers
                .get("CONTENT_TYPE")
                .map(|c| c.to_str().unwrap_or(""))
                .unwrap_or("")
                .to_owned(),
        );
        // Since this is not in the specification, an X_ is prepended, per spec.
        // NB: It is strange that there is not a way to do this already. The Display impl
        // seems to only provide the path.
        let uri = req.uri.clone();
        headers.insert(
            "X_FULL_URL".to_owned(),
            format!(
                "{}://{}{}",
                uri.scheme_str().unwrap_or("http"), // It is not clear if Hyper ever sets scheme.
                uri.authority()
                    .map(|a| a.as_str())
                    .unwrap_or_else(|| host.as_str()),
                uri.path_and_query().map(|pq| pq.as_str()).unwrap_or("")
            ),
        );
        headers.insert("GATEWAY_INTERFACE".to_owned(), WAGI_VERSION.to_owned());
        headers.insert("X_MATCHED_ROUTE".to_owned(), self.route.to_owned()); // Specific to WAGI (not CGI)
        headers.insert("PATH_INFO".to_owned(), req.uri.path().to_owned()); // TODO: Does this get trimmed?
        // NOTE: The security model of WAGI means that we do not give the actual
        // translated path on the host filesystem, as that is off limits to the runtime.
        // Right now, this just returns the same as PATH_INFO, but we could attempt to
        // map it to something if we know what that "something" is.
        headers.insert("PATH_TRANSLATED".to_owned(), req.uri.path().to_owned());
        headers.insert(
            "QUERY_STRING".to_owned(),
            req.uri.query().unwrap_or("").to_owned(),
        );
        headers.insert("REMOTE_ADDR".to_owned(), client_addr.ip().to_string());
        headers.insert("REMOTE_HOST".to_owned(), client_addr.ip().to_string()); // The server MAY substitute it with REMOTE_ADDR
        headers.insert("REMOTE_USER".to_owned(), "".to_owned()); // TODO: Parse this out of uri.authority?
        headers.insert("REQUEST_METHOD".to_owned(), req.method.to_string());
        headers.insert("SCRIPT_NAME".to_owned(), self.module.to_owned());
        // From the spec: "the server would use the contents of the request's Host header
        // field to select the correct virtual host."
        headers.insert("SERVER_NAME".to_owned(), host);
        headers.insert(
            "SERVER_PORT".to_owned(),
            req.uri
                .port()
                .map(|p| p.to_string())
                .unwrap_or_else(|| "80".to_owned()),
        );
        headers.insert(
            "SERVER_PROTOCOL".to_owned(),
            req.uri
                .scheme()
                .unwrap_or(&Scheme::HTTP)
                .as_str()
                .to_owned(),
        );
        headers.insert(
            "SERVER_SOFTWARE".to_owned(),
            SERVER_SOFTWARE_VERSION.to_owned(),
        );
        // Normalize incoming HTTP headers. The spec says:
        // "The HTTP header field name is converted to upper case, has all
        // occurrences of "-" replaced with "_" and has "HTTP_" prepended to
        // give the meta-variable name."
        req.headers.iter().for_each(|header| {
            let key = format!(
                "HTTP_{}",
                header.0.as_str().to_uppercase().replace("-", "_")
            );
            // Per spec 4.1.18, skip some headers
            if key == "HTTP_AUHTORIZATION" || key == "HTTP_CONNECTION" {
                return;
            }
            let val = header.1.to_str().unwrap_or("CORRUPT VALUE").to_owned();
            headers.insert(key, val);
        });
        headers
    }
fn build_headers ( & self , req : & Parts , content_length : usize , client_addr : SocketAddr , ) -> HashMap < String , String > { // Note that we put these first so that there is no chance that they overwrite // the built-in vars. IMPORTANT: This is also why some values have empty strings // deliberately set (as opposed to omiting the pair altogether). let mut headers = self . environment . clone ( ) . unwrap_or_default ( ) ; let host = req . headers . get ( HOST ) . map ( | val | val . to_str ( ) . unwrap_or ( " " ) ) . unwrap_or ( " " ) . to_owned ( ) ; // CGI headers from RFC headers . insert ( " " . to_owned ( ) , " " . to_owned ( ) ) ; // Not currently supported // CONTENT_LENGTH (from the spec) // The server MUST set this meta-variable if and only if the request is // accompanied by a message-body entity.  The CONTENT_LENGTH value must // reflect the length of the message-body after the server has removed // any transfer-codings or content-codings. headers . insert ( " " . to_owned ( ) , format ! ( " " content_length ) ) ; // CONTENT_TYPE (from the spec) // The server MUST set this meta-variable if an HTTP Content-Type field is present // in the client request header.  If the server receives a request with an // attached entity but no Content-Type header field, it MAY attempt to determine // the correct content type, otherwise it should omit this meta-variable. // // Right now, we don't attempt to determine a media type if none is presented. // // The spec seems to indicate that if CONTENT_LENGTH > 0, this may be set // to "application/octet-stream" if no type is otherwise set. Not sure that is // a good idea. headers . insert ( " " . to_owned ( ) , req . headers . get ( " " ) . map ( | c | c . to_str ( ) . unwrap_or ( " " ) ) . unwrap_or ( " " ) . to_owned ( ) , ) ; // Since this is not in the specification, an X_ is prepended, per spec. // NB: It is strange that there is not a way to do this already. The Display impl // seems to only provide the path. let uri = req . uri . clone ( ) ; headers . insert ( " " . to_owned ( ) , format ! ( " " uri scheme_str ( ) unwrap_or ( " " ) // It is not clear if Hyper ever sets scheme. uri authority ( ) map ( a a as_str ( ) ) unwrap_or_else ( host as_str ( ) ) uri path_and_query ( ) map ( pq pq as_str ( ) ) unwrap_or ( " " ) ) , ) ; headers . insert ( " " . to_owned ( ) , WAGI_VERSION . to_owned ( ) ) ; headers . insert ( " " . to_owned ( ) , self . route . to_owned ( ) ) ; // Specific to WAGI (not CGI) headers . insert ( " " . to_owned ( ) , req . uri . path ( ) . to_owned ( ) ) ; // TODO: Does this get trimmed? // NOTE: The security model of WAGI means that we do not give the actual // translated path on the host filesystem, as that is off limits to the runtime. // Right now, this just returns the same as PATH_INFO, but we could attempt to // map it to something if we know what that "something" is. headers . insert ( " " . to_owned ( ) , req . uri . path ( ) . to_owned ( ) ) ; headers . insert ( " " . to_owned ( ) , req . uri . query ( ) . unwrap_or ( " " ) . to_owned ( ) , ) ; headers . insert ( " " . to_owned ( ) , client_addr . ip ( ) . to_string ( ) ) ; headers . insert ( " " . to_owned ( ) , client_addr . ip ( ) . to_string ( ) ) ; // The server MAY substitute it with REMOTE_ADDR headers . insert ( " " . to_owned ( ) , " " . to_owned ( ) ) ; // TODO: Parse this out of uri.authority? headers . insert ( " " . to_owned ( ) , req . method . to_string ( ) ) ; headers . insert ( " " . to_owned ( ) , self . module . to_owned ( ) ) ; // From the spec: "the server would use the contents of the request's Host header // field to select the correct virtual host." headers . insert ( " " . to_owned ( ) , host ) ; headers . insert ( " " . to_owned ( ) , req . uri . port ( ) . map ( | p | p . to_string ( ) ) . unwrap_or_else ( | | " " . to_owned ( ) ) , ) ; headers . insert ( " " . to_owned ( ) , req . uri . scheme ( ) . unwrap_or ( & Scheme :: HTTP ) . as_str ( ) . to_owned ( ) , ) ; headers . insert ( " " . to_owned ( ) , SERVER_SOFTWARE_VERSION . to_owned ( ) , ) ; // Normalize incoming HTTP headers. The spec says: // "The HTTP header field name is converted to upper case, has all // occurrences of "-" replaced with "_" and has "HTTP_" prepended to // give the meta-variable name." req . headers . iter ( ) . for_each ( | header | { let key = format ! ( " " header 0 as_str ( ) to_uppercase ( ) replace ( " " " " ) ) ; // Per spec 4.1.18, skip some headers if key == " " || key == " " { return ; } let val = header . 1 . to_str ( ) . unwrap_or ( " " ) . to_owned ( ) ; headers . insert ( key , val ) ; } ) ; headers }
Build the WAGI headers for injection into a module.
Build the WAGI headers for injection into a module .
&self
req
&Parts
content_length
usize
client_addr
SocketAddr