ADA es un analizador URL rápido y compatible con especificaciones escrita en C ++. Se puede encontrar especificaciones para el analizador URL en el sitio web de Whatwg.
La biblioteca ADA pasa la gama completa de pruebas de la especificación, en una amplia gama de plataformas (por ejemplo, Windows, Linux, MacOS). Apoya completamente el estándar técnico Unicode relevante.
Un uso común de un analizador URL es tomar una cadena de URL y normalizarla. La especificación de URL WhatWG ha sido adoptada por la mayoría de los navegadores. Otras herramientas, como Curl y muchas bibliotecas estándar, sigan el RFC 3986. La siguiente tabla ilustra las posibles diferencias en la práctica (codificación del host, codificación de la ruta):
| fuente de cadena | valor de cadena |
|---|---|
| cadena de entrada | https://www.7-eleven.com/home/privacy/montréal |
| Cadena normalizada de Ada | https://www.xn --7eleven-506c.com/home/privacy/montr%C3%A9al |
| Curl 7.87 | (Devuelve el original sin cambios) |
El proyecto es de otro modo autónomo y no tiene dependencia. Un reciente compilador de C ++ que admite C ++ 20. Probamos GCC 12 o mejor, LLVM 12 o mejor y Microsoft Visual Studio 2022.
En un punto de referencia donde necesitamos validar y normalizar miles de URL que se encuentran en sitios web populares, encontramos que ADA puede ser varias veces más rápido que los competidores populares (Sistema: Apple MacBook 2022 con LLVM 14).
ada ▏ 188 ns/URL ███▏
servo url ▏ 664 ns/URL ███████████▎
CURL ▏ 1471 ns/URL █████████████████████████
ADA ha mejorado el rendimiento del popular entorno JavaScript Node.js:
Desde Node.js 18, se agregó una nueva dependencia del analizador URL a Node.js - ADA. Esta adición aumentó el rendimiento del nodo.js al analizar las URL a un nuevo nivel. Algunos resultados podrían alcanzar una mejora del 400% . (Estado de nodo.js rendimiento 2023)
La biblioteca ADA es utilizada por sistemas importantes además de nodo.js como los trabajadores de Redpanda, Kong, Telegram y Cloudflare.
Los paquetes binarios para los siguientes sistemas están actualmente disponibles:
Los usuarios de Linux o MacOS pueden seguir las siguientes instrucciones si tienen un compilador C ++ reciente instalado y una utilidad estándar ( wget )
Tire de la biblioteca en un directorio
wget https://github.com/ada-url/ada/releases/download/v2.6.10/ada.cpp
wget https://github.com/ada-url/ada/releases/download/v2.6.10/ada.h
Cree un nuevo archivo llamado demo.cpp con este contenido:
# include " ada.cpp "
# include " ada.h "
# include < iostream >
int main ( int , char *[]) {
auto url = ada::parse ( " https://www.google.com " );
if (!url) {
std::cout << " failure " << std::endl;
return EXIT_FAILURE;
}
url-> set_protocol ( " http " );
std::cout << url-> get_protocol () << std::endl;
std::cout << url-> get_host () << std::endl;
return EXIT_SUCCESS;
}Compilar
c++ -std=c++20 -o demo demo.cpp
./demo
http:
www.google.com
El equipo de ADA mantiene las siguientes bibliotecas y está disponible bajo la organización Ada Github.
ADA admite dos tipos de instancias de URL, ada::url y ada::url_aggregator . El uso es el mismo en cualquier caso: tenemos una plantilla de función de análisis ada::parse que puede devolver un resultado del tipo ada::result<ada::url> o de tipo ada::result<ada::url_aggregator> dependiendo de sus necesidades. La clase ada::url_aggregator es más pequeña y está respaldada por una cadena de URL serializada precomputada. La clase ada::url está hecha de varias cadenas separadas para los diversos componentes (ruta, host, etc.).
ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
if (url) { /* URL is valid */ }Después de llamar a 'analizador', debe verificar que el resultado sea válido antes de acceder a él cuando no esté seguro de que tenga éxito. El siguiente código no es seguro:
ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " some bad url " );
url-> get_href ();Deberías hacer ...
ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " some bad url " );
if (url) {
// next line is now safe:
url-> get_href ();
} else {
// report a parsing failure
}Para simplificar, en los ejemplos a continuación, saltamos el cheque porque sabemos que el análisis tiene éxito. Se supone que todas las cadenas son válidas de las cadenas UTF-8.
ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_username ( " username " );
url-> set_password ( " password " );
// ada->get_href() will return "https://username:[email protected]/"ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_protocol ( " wss " );
// url->get_protocol() will return "wss:"
// url->get_href() will return "wss://www.google.com/"ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_host ( " github.com " );
// url->get_host() will return "github.com"
// you can use `url.set_hostname` depending on your usage.ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_port ( " 8080 " );
// url->get_port() will return "8080"ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_pathname ( " /my-super-long-path " )
// url->get_pathname() will return "/my-super-long-path"ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_search ( " target=self " );
// url->get_search() will return "?target=self"ada::result<ada::url_aggregator> url = ada::parse<ada::url_aggregator>( " https://www.google.com " );
url-> set_hash ( " is-this-the-real-life " );
// url->get_hash() will return "#is-this-the-real-life"Para obtener más información sobre las opciones de línea de comandos, consulte la documentación de la CLI.
ada::url_search_params search_params ( " a=b&c=d&e=f " );
search_params.append( " g=h " );
search_params.get( " g " ); // will return "h"
auto keys = search_params.get_keys();
while (keys.has_next()) {
auto key = keys. next (); // "a", "c", "e", "g"
} Consulte el archivo include/ada_c.h para nuestra interfaz C. Esperamos cadenas ASCII o UTF-8.
#include "ada_c.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
static void ada_print ( ada_string string ) {
printf ( "%.*sn" , ( int ) string . length , string . data );
}
int main ( int c , char * arg [] ) {
const char * input =
"https://username:[email protected]:8080/"
"pathname?query=true#hash-exists" ;
ada_url url = ada_parse ( input , strlen ( input ));
if (! ada_is_valid ( url )) { puts ( "failure" ); return EXIT_FAILURE ; }
ada_print ( ada_get_href ( url )); // prints https://username:password@host:8080/pathname?query=true#hash-exists
ada_print ( ada_get_protocol ( url )); // prints https:
ada_print ( ada_get_username ( url )); // prints username
ada_set_href ( url , "https://www.yagiz.co" , strlen ( "https://www.yagiz.co" ));
if (! ada_is_valid ( url )) { puts ( "failure" ); return EXIT_FAILURE ; }
ada_set_hash ( url , "new-hash" , strlen ( "new-hash" ));
ada_set_hostname ( url , "new-host" , strlen ( "new-host" ));
ada_set_host ( url , "changed-host:9090" , strlen ( "changed-host:9090" ));
ada_set_pathname ( url , "new-pathname" , strlen ( "new-pathname" ));
ada_set_search ( url , "new-search" , strlen ( "new-search" ));
ada_set_protocol ( url , "wss" , 3 );
ada_print ( ada_get_href ( url )); // will print wss://changed-host:9090/new-pathname?new-search#new-hash
// Manipulating search params
ada_string search = ada_get_search ( url );
ada_url_search_params search_params =
ada_parse_search_params ( search . data , search . length );
ada_search_params_append ( search_params , "a" , 1 , "b" , 1 );
ada_owned_string result = ada_search_params_to_string ( search_params );
ada_set_search ( url , result . data , result . length );
ada_free_owned_string ( result );
ada_free_search_params ( search_params );
ada_free ( url );
return EXIT_SUCCESS ;
}Al vincular con la biblioteca ADA de C ++, se ocupe de que ADA requiere acceso a la biblioteca C ++ estándar. Por ejemplo, puede vincular con el compilador C ++.
Por ejemplo, si toma nuestros archivos C ++ de un solo cabezal ( ada.cpp y ada.h ), así como el encabezado C ( ada_c.h ), a menudo puede compilar un programa C ( demo.c ) como sigue en los sistemas Linux/MacOS:
c++ -c ada.cpp -std=c++20
cc -c demo.c
c++ demo.o ada.o -o cdemo
./cdemo
Consulte las tests/installation/CMakeLists.txt para obtener un ejemplo de cómo puede usar ADA desde su propio proyecto CMake, después de haber instalado ADA en su sistema.
Ada está disponible a través de Homebrew. Puede instalar ADA usando brew install ada-url .
ADA usa Cmake como sistema de compilación. Se recomienda ejecutar los siguientes comandos para construirlo localmente.
cmake -B build && cmake --build buildctest --output-on-failure --test-dir build Los usuarios de Windows necesitan indicadores adicionales para especificar la configuración de compilación, por ejemplo, --config Release .
El proyecto también se puede construir a través de Docker utilizando el archivo Docker predeterminado del repositorio con los siguientes comandos.
docker build -t ada-builder . && docker run --rm -it -v ${PWD}:/repo ada-builder
Puede amalgamar todos los archivos de origen en solo dos archivos ( ada.h y ada.cpp ) escribiendo ejecutando el script python 3 script singleheader/amalgamate.py . De forma predeterminada, los archivos se crean en el directorio de singleheader .
Este código está disponible bajo la licencia APACHE 2.0, así como la licencia MIT.
Nuestras pruebas incluyen código de terceros y datos. El código de evaluación comparativa incluye código de terceros: se proporciona solo para fines de investigación y no parte de la biblioteca.