{"id":20373116,"url":"https://github.com/st235/uric","last_synced_at":"2026-05-31T22:31:51.455Z","repository":{"id":249159610,"uuid":"829055460","full_name":"st235/URIC","owner":"st235","description":"A Uniform Resource Identifier (URI) implementation in C++, designed strictly in compliance with RFC 3986.","archived":false,"fork":false,"pushed_at":"2024-08-03T16:47:18.000Z","size":223,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-04T20:43:51.710Z","etag":null,"topics":["cpp","parser","pico","raspberry-pi-pico","rfc3986","uri","url"],"latest_commit_sha":null,"homepage":"https://datatracker.ietf.org/doc/html/rfc3986","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/st235.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-15T17:02:09.000Z","updated_at":"2025-01-23T13:41:18.000Z","dependencies_parsed_at":"2025-01-15T05:44:14.651Z","dependency_job_id":"54e65136-036b-4b4a-b544-f2752ff48138","html_url":"https://github.com/st235/URIC","commit_stats":null,"previous_names":["st235/uric"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/st235/URIC","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FURIC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FURIC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FURIC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FURIC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/st235","download_url":"https://codeload.github.com/st235/URIC/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/st235%2FURIC/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33752286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","parser","pico","raspberry-pi-pico","rfc3986","uri","url"],"created_at":"2024-11-15T01:16:38.809Z","updated_at":"2026-05-31T22:31:51.438Z","avatar_url":"https://github.com/st235.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# URIC\n\nA Uniform Resource Identifier (URI) implementation in `C++`, designed strictly in compliance with [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).\n\nThe library also includes an implementation of Uniform Resource Locator (URL) rules, which are a subset of URI rules. This implementation follows [the `MDN` definition of URL]((https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL)), specifically:\n\n\u003e Parameters\n\u003e `?key1=value1\u0026key2=value2` are extra parameters provided to the Web server. Those parameters are a list of key/value pairs separated with the \u0026 symbol. The Web server can use those parameters to do extra stuff before returning the resource. Each Web server has its own rules regarding parameters, and the only reliable way to know if a specific Web server is handling parameters is by asking the Web server owner.\n\nThe library was tested with [`Raspberry Pi Pico and Pico W`](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html).\n\n\u003e[!NOTE]\n\u003eIn the event that RFC 3986 is unavailable, please refer to the [local copy](./rfc3986.pdf).\n\n## Bringing Dependencies\n\nTo install the library, which is utilizes CMake, follow these simple steps: \n\nfirst, include the FetchContent module in your CMake configuration. Then, declare the library by specifying the `git` repository and branch. Finally, make the content available and link the library to your target. Here’s a sample CMake snippet for reference:\n\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n  URIC\n  GIT_REPOSITORY git@github.com:st235/URIC.git\n  GIT_TAG \"main\"\n  GIT_SHALLOW TRUE\n  GIT_PROGRESS ON\n)\nFetchContent_MakeAvailable(URIC)\n\ntarget_link_libraries(uri-validator uric)\n```\n\n## API\n\nUsing the API is really straightforward. Here’s a quick example to get you started:\n\nFirst, parse the URI using `uri::Uri::parse(uri)`. If the URI is invalid, you'll get `std::nullopt` object. If it’s valid, you can easily access different parts of the URI. For example, you can get the scheme, authority, and other components.\n\nHere’s a code snippet (from [samples](./samples/)) to illustrate:\n\n```cpp\nconst auto\u0026 uri_opt = uri::Uri::parse(uri_to_verify);\nif (!uri_opt) {\n    std::cout \u003c\u003c \"Not a valid URI.\"  \u003c\u003c std::endl;\n    return 0;\n}\n\nconst auto\u0026 uri = uri_opt.value();\n\nif (uri.getScheme()) {\n    std::cout \u003c\u003c \"Scheme: \" \u003c\u003c uri.getScheme().value() \u003c\u003c std::endl;\n}\n\nif (uri.getAuthority()) {\n    const auto\u0026 authority = uri.getAuthority().value();\n\n    std::cout \u003c\u003c \"Authority:\" \u003c\u003c std::endl;\n    if (authority.getUserInfo()) {\n        std::cout \u003c\u003c \"\\tUser Info: \" \u003c\u003c authority.getUserInfo().value() \u003c\u003c std::endl;\n    }\n\n    std::cout \u003c\u003c \"\\tHost: \" \u003c\u003c authority.getHost() \u003c\u003c std::endl;\n\n    if (authority.getPort()) {\n        std::cout \u003c\u003c \"\\tPort: \" \u003c\u003c authority.getPort().value() \u003c\u003c std::endl;\n    }\n}\n```\n\n### Normalisation\n\nThe library provides handy methods for path normalisation, according to the `RFC 3986`.\n\nThe rules are:\n\n- The following unreserved characters are percent decoded:\n    - Alphabetical characters: `a-z`, `A-Z` (decoded from `%41`-`%5A` and `%61`-`%7A`)\n    - Digit characters: `0-9` (decoded from `%30`-`%39`)\n    - hyphen '-' (`%2D`), period '.' (`%2E`), underscore '_' (`%5F`), and tilde '~' (`%7E`)\n- These reserved characters are not encoded or decoded: `: / ? # [ ] @ ! $ \u0026 ' ( ) * + , ; =`\n- Other characters, for example literal byte values, are percent encoded.\n- Percent encoded representations are converted to upper case.\n- Paths are normalized according to the Remove Dot Segments protocol.\n\n\u003e[!NOTE]\n\u003e Use `Uri::normalisePath` to perform path normalisation.\n\n## Grammar\n\n\u003e[!NOTE]\n\u003e URI Grammar for future reference, see `RFC 3986` for more details.\n\n```text\nURI           = scheme \":\" hier-part [ \"?\" query ] [ \"#\" fragment ]\n\n   hier-part     = \"//\" authority path-abempty\n                 / path-absolute\n                 / path-rootless\n                 / path-empty\n\n   URI-reference = URI / relative-ref\n\n   absolute-URI  = scheme \":\" hier-part [ \"?\" query ]\n\n   relative-ref  = relative-part [ \"?\" query ] [ \"#\" fragment ]\n\n   relative-part = \"//\" authority path-abempty\n                 / path-absolute\n                 / path-noscheme\n                 / path-empty\n\n   scheme        = ALPHA *( ALPHA / DIGIT / \"+\" / \"-\" / \".\" )\n\n   authority     = [ userinfo \"@\" ] host [ \":\" port ]\n   userinfo      = *( unreserved / pct-encoded / sub-delims / \":\" )\n   host          = IP-literal / IPv4address / reg-name\n   port          = *DIGIT\n\n   IP-literal    = \"[\" ( IPv6address / IPvFuture  ) \"]\"\n\n   IPvFuture     = \"v\" 1*HEXDIG \".\" 1*( unreserved / sub-delims / \":\" )\n\n   IPv6address   =                            6( h16 \":\" ) ls32\n                 /                       \"::\" 5( h16 \":\" ) ls32\n                 / [               h16 ] \"::\" 4( h16 \":\" ) ls32\n                 / [ *1( h16 \":\" ) h16 ] \"::\" 3( h16 \":\" ) ls32\n                 / [ *2( h16 \":\" ) h16 ] \"::\" 2( h16 \":\" ) ls32\n                 / [ *3( h16 \":\" ) h16 ] \"::\"    h16 \":\"   ls32\n                 / [ *4( h16 \":\" ) h16 ] \"::\"              ls32\n                 / [ *5( h16 \":\" ) h16 ] \"::\"              h16\n                 / [ *6( h16 \":\" ) h16 ] \"::\"\n\n   h16           = 1*4HEXDIG\n   ls32          = ( h16 \":\" h16 ) / IPv4address\n   IPv4address   = dec-octet \".\" dec-octet \".\" dec-octet \".\" dec-octet\n\n   dec-octet     = DIGIT                 ; 0-9\n                 / %x31-39 DIGIT         ; 10-99\n                 / \"1\" 2DIGIT            ; 100-199\n                 / \"2\" %x30-34 DIGIT     ; 200-249\n                 / \"25\" %x30-35          ; 250-255\n\n   reg-name      = *( unreserved / pct-encoded / sub-delims )\n\n   path          = path-abempty    ; begins with \"/\" or is empty\n                 / path-absolute   ; begins with \"/\" but not \"//\"\n                 / path-noscheme   ; begins with a non-colon segment\n                 / path-rootless   ; begins with a segment\n                 / path-empty      ; zero characters\n\n   path-abempty  = *( \"/\" segment )\n   path-absolute = \"/\" [ segment-nz *( \"/\" segment ) ]\n   path-noscheme = segment-nz-nc *( \"/\" segment )\n   path-rootless = segment-nz *( \"/\" segment )\n   path-empty    = 0\u003cpchar\u003e\n\n   segment       = *pchar\n   segment-nz    = 1*pchar\n   segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / \"@\" )\n                 ; non-zero-length segment without any colon \":\"\n\n   pchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n\n   query         = *( pchar / \"/\" / \"?\" )\n\n   fragment      = *( pchar / \"/\" / \"?\" )\n\n   pct-encoded   = \"%\" HEXDIG HEXDIG\n\n   unreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n   reserved      = gen-delims / sub-delims\n   gen-delims    = \":\" / \"/\" / \"?\" / \"#\" / \"[\" / \"]\" / \"@\"\n   sub-delims    = \"!\" / \"$\" / \"\u0026\" / \"'\" / \"(\" / \")\"\n                 / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n```\n\n## Building the project\n\nUse these commands to build the project:\n\n```bash\nmkdir build\ncmake .. -DCOMPILE_TESTS=ON\nmake\n```\n\n### Running test\n\nA lot of logic in the library heavily relies on _unit_ tests.\nTo run them you need yo _successfully build the project_ and run the command below:\n\n```bash\nctest --output-on-failure [-R filter regex]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fst235%2Furic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fst235%2Furic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fst235%2Furic/lists"}