Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/netwerk/protocol/http/binary_http/src/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  lib.rs

  Sprache: Rust
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


extern crate bhttp;
extern crate nserror;
extern crate nsstring;
extern crate thin_vec;
#[macro_use]
extern crate xpcom;

use bhttp::{Message, Mode};
use nserror::{nsresult, NS_ERROR_FAILURE, NS_ERROR_INVALID_ARG, NS_ERROR_UNEXPECTED, NS_OK};
use nsstring::{nsACString, nsCString};
use std::io::Cursor;
use thin_vec::ThinVec;
use xpcom::interfaces::{nsIBinaryHttpRequest, nsIBinaryHttpResponse};
use xpcom::RefPtr;

enum HeaderComponent {
    Name,
    Value,
}

// Extracts either the names or the values of a slice of header (name, value) pairs.
fn extract_header_components(
    headers: &[(Vec<u8>, Vec<u8>)],
    component: HeaderComponent,
) -> ThinVec<nsCString> {
    let mut header_components = ThinVec::with_capacity(headers.len());
    for (name, value) in headers {
        match component {
            HeaderComponent::Name => header_components.push(nsCString::from(name.clone())),
            HeaderComponent::Value => header_components.push(nsCString::from(value.clone())),
        }
    }
    header_components
}

#[xpcom(implement(nsIBinaryHttpRequest), atomic)]
struct BinaryHttpRequest {
    method: Vec<u8>,
    scheme: Vec<u8>,
    authority: Vec<u8>,
    path: Vec<u8>,
    headers: Vec<(Vec<u8>, Vec<u8>)>,
    content: Vec<u8>,
}

impl BinaryHttpRequest {
    xpcom_method!(get_method => GetMethod() -> nsACString);
    fn get_method(&self) -> Result<nsCString, nsresult> {
        Ok(nsCString::from(self.method.clone()))
    }

    xpcom_method!(get_scheme => GetScheme() -> nsACString);
    fn get_scheme(&self) -> Result<nsCString, nsresult> {
        Ok(nsCString::from(self.scheme.clone()))
    }

    xpcom_method!(get_authority => GetAuthority() -> nsACString);
    fn get_authority(&self) -> Result<nsCString, nsresult> {
        Ok(nsCString::from(self.authority.clone()))
    }

    xpcom_method!(get_path => GetPath() -> nsACString);
    fn get_path(&self) -> Result<nsCString, nsresult> {
        Ok(nsCString::from(self.path.clone()))
    }

    xpcom_method!(get_content => GetContent() -> ThinVec<u8>);
    fn get_content(&self) -> Result<ThinVec<u8>, nsresult> {
        Ok(self.content.clone().into_iter().collect())
    }

    xpcom_method!(get_header_names => GetHeaderNames() -> ThinVec<nsCString>);
    fn get_header_names(&self) -> Result<ThinVec<nsCString>, nsresult> {
        Ok(extract_header_components(
            &self.headers,
            HeaderComponent::Name,
        ))
    }

    xpcom_method!(get_header_values => GetHeaderValues() -> ThinVec<nsCString>);
    fn get_header_values(&self) -> Result<ThinVec<nsCString>, nsresult> {
        Ok(extract_header_components(
            &self.headers,
            HeaderComponent::Value,
        ))
    }
}

#[xpcom(implement(nsIBinaryHttpResponse), atomic)]
struct BinaryHttpResponse {
    status: u16,
    headers: Vec<(Vec<u8>, Vec<u8>)>,
    content: Vec<u8>,
}

impl BinaryHttpResponse {
    xpcom_method!(get_status => GetStatus() -> u16);
    fn get_status(&self) -> Result<u16, nsresult> {
        Ok(self.status)
    }

    xpcom_method!(get_content => GetContent() -> ThinVec<u8>);
    fn get_content(&self) -> Result<ThinVec<u8>, nsresult> {
        Ok(self.content.clone().into_iter().collect())
    }

    xpcom_method!(get_header_names => GetHeaderNames() -> ThinVec<nsCString>);
    fn get_header_names(&self) -> Result<ThinVec<nsCString>, nsresult> {
        Ok(extract_header_components(
            &self.headers,
            HeaderComponent::Name,
        ))
    }

    xpcom_method!(get_header_values => GetHeaderValues() -> ThinVec<nsCString>);
    fn get_header_values(&self) -> Result<ThinVec<nsCString>, nsresult> {
        Ok(extract_header_components(
            &self.headers,
            HeaderComponent::Value,
        ))
    }
}

#[xpcom(implement(nsIBinaryHttp), atomic)]
struct BinaryHttp {}

impl BinaryHttp {
    xpcom_method!(encode_request => EncodeRequest(request: *const nsIBinaryHttpRequest) -> ThinVec<u8>);
    fn encode_request(&self, request: &nsIBinaryHttpRequest) -> Result<ThinVec<u8>, nsresult> {
        let mut method = nsCString::new();
        unsafe { request.GetMethod(&mut *method) }.to_result()?;
        let mut scheme = nsCString::new();
        unsafe { request.GetScheme(&mut *scheme) }.to_result()?;
        let mut authority = nsCString::new();
        unsafe { request.GetAuthority(&mut *authority) }.to_result()?;
        let mut path = nsCString::new();
        unsafe { request.GetPath(&mut *path) }.to_result()?;
        let mut message = Message::request(
            method.to_vec(),
            scheme.to_vec(),
            authority.to_vec(),
            path.to_vec(),
        );
        let mut header_names = ThinVec::new();
        unsafe { request.GetHeaderNames(&mut header_names) }.to_result()?;
        let mut header_values = ThinVec::with_capacity(header_names.len());
        unsafe { request.GetHeaderValues(&mut header_values) }.to_result()?;
        if header_names.len() != header_values.len() {
            return Err(NS_ERROR_INVALID_ARG);
        }
        for (name, value) in header_names.iter().zip(header_values.iter()) {
            message.put_header(name.to_vec(), value.to_vec());
        }
        let mut content = ThinVec::new();
        unsafe { request.GetContent(&mut content) }.to_result()?;
        message.write_content(content);
        let mut encoded = ThinVec::new();
        message
            .write_bhttp(Mode::KnownLength, &mut encoded)
            .map_err(|_| NS_ERROR_FAILURE)?;
        Ok(encoded)
    }

    xpcom_method!(decode_response => DecodeResponse(response: *const ThinVec<u8>) -> *const nsIBinaryHttpResponse);
    fn decode_response(
        &self,
        response: &ThinVec<u8>,
    ) -> Result<RefPtr<nsIBinaryHttpResponse>, nsresult> {
        let mut cursor = Cursor::new(response);
        let decoded = Message::read_bhttp(&mut cursor).map_err(|_| NS_ERROR_UNEXPECTED)?;
        let status = decoded.control().status().ok_or(NS_ERROR_UNEXPECTED)?;
        let headers = decoded
            .header()
            .iter()
            .map(|field| (field.name().to_vec(), field.value().to_vec()))
            .collect();
        let content = decoded.content().to_vec();
        let binary_http_response = BinaryHttpResponse::allocate(InitBinaryHttpResponse {
            status,
            headers,
            content,
        });
        binary_http_response
            .query_interface::<nsIBinaryHttpResponse>()
            .ok_or(NS_ERROR_FAILURE)
    }

    xpcom_method!(decode_request => DecodeRequest(request: *const ThinVec<u8>) -> *const nsIBinaryHttpRequest);
    fn decode_request(
        &self,
        request: &ThinVec<u8>,
    ) -> Result<RefPtr<nsIBinaryHttpRequest>, nsresult> {
        let mut cursor = Cursor::new(request);
        let decoded = Message::read_bhttp(&mut cursor).map_err(|_| NS_ERROR_UNEXPECTED)?;
        let method = decoded
            .control()
            .method()
            .ok_or(NS_ERROR_UNEXPECTED)?
            .to_vec();
        let scheme = decoded
            .control()
            .scheme()
            .ok_or(NS_ERROR_UNEXPECTED)?
            .to_vec();
        // authority and path can be empty, in which case we return empty arrays
        let authority = decoded.control().authority().unwrap_or(&[]).to_vec();
        let path = decoded.control().path().unwrap_or(&[]).to_vec();
        let headers = decoded
            .header()
            .iter()
            .map(|field| (field.name().to_vec(), field.value().to_vec()))
            .collect();
        let content = decoded.content().to_vec();
        let binary_http_request = BinaryHttpRequest::allocate(InitBinaryHttpRequest {
            method,
            scheme,
            authority,
            path,
            headers,
            content,
        });
        binary_http_request
            .query_interface::<nsIBinaryHttpRequest>()
            .ok_or(NS_ERROR_FAILURE)
    }

    xpcom_method!(encode_response => EncodeResponse(response: *const nsIBinaryHttpResponse) -> ThinVec<u8>);
    fn encode_response(&self, response: &nsIBinaryHttpResponse) -> Result<ThinVec<u8>, nsresult> {
        let mut status = 0;
        unsafe { response.GetStatus(&mut status) }.to_result()?;
        let mut message = Message::response(status);
        let mut header_names = ThinVec::new();
        unsafe { response.GetHeaderNames(&mut header_names) }.to_result()?;
        let mut header_values = ThinVec::with_capacity(header_names.len());
        unsafe { response.GetHeaderValues(&mut header_values) }.to_result()?;
        if header_names.len() != header_values.len() {
            return Err(NS_ERROR_INVALID_ARG);
        }
        for (name, value) in header_names.iter().zip(header_values.iter()) {
            message.put_header(name.to_vec(), value.to_vec());
        }
        let mut content = ThinVec::new();
        unsafe { response.GetContent(&mut content) }.to_result()?;
        message.write_content(content);
        let mut encoded = ThinVec::new();
        message
            .write_bhttp(Mode::KnownLength, &mut encoded)
            .map_err(|_| NS_ERROR_FAILURE)?;
        Ok(encoded)
    }
}

#[no_mangle]
pub extern "C" fn binary_http_constructor(
    iid: *const xpcom::nsIID,
    result: *mut *mut xpcom::reexports::libc::c_void,
) -> nsresult {
    let binary_http = BinaryHttp::allocate(InitBinaryHttp {});
    unsafe { binary_http.QueryInterface(iid, result) }
}

Messung V0.5 in Prozent
C=99 H=86 G=92

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-06-20) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.