{"id":13564328,"url":"https://github.com/emqx/quic","last_synced_at":"2025-10-09T00:10:40.617Z","repository":{"id":37015571,"uuid":"236436102","full_name":"emqx/quic","owner":"emqx","description":"QUIC protocol for Erlang \u0026 Elixir","archived":false,"fork":false,"pushed_at":"2025-04-01T11:07:30.000Z","size":2020,"stargazers_count":235,"open_issues_count":11,"forks_count":41,"subscribers_count":24,"default_branch":"main","last_synced_at":"2025-04-01T12:23:20.047Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.emqx.com","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emqx.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-27T07:02:02.000Z","updated_at":"2025-04-01T11:07:34.000Z","dependencies_parsed_at":"2024-01-13T02:56:13.870Z","dependency_job_id":"2b36ab11-2ec2-4232-a2d3-966061c0e4b4","html_url":"https://github.com/emqx/quic","commit_stats":{"total_commits":535,"total_committers":15,"mean_commits":"35.666666666666664","dds":"0.20747663551401874","last_synced_commit":"636d2ee0aef4117eb3ffe65a9f1a574819b06b45"},"previous_names":[],"tags_count":79,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emqx%2Fquic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emqx%2Fquic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emqx%2Fquic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emqx%2Fquic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emqx","download_url":"https://codeload.github.com/emqx/quic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247082911,"owners_count":20880741,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-01T13:01:29.757Z","updated_at":"2025-10-09T00:10:35.583Z","avatar_url":"https://github.com/emqx.png","language":"Erlang","funding_links":[],"categories":["Erlang","QUIC"],"sub_categories":[],"readme":"# Quicer\n\nQUIC (Next-generation transport protocol) erlang library.\n\n[msquic](https://github.com/microsoft/msquic) NIF binding.\n\nProject Status: Preview\n\n![Erlang](https://img.shields.io/badge/Erlang-white.svg?style=plastic\u0026logo=erlang\u0026logoColor=a90533)\n![CI](https://github.com/emqx/quic/workflows/ci/badge.svg)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Coverage Status](https://coveralls.io/repos/emqx/quic/badge.png?branch=main)](https://coveralls.io/r/emqx/quic?branch=main)\n\n## OS Support\n\n| OS      | Status      |\n|---------|-------------|\n| Linux   | Supported   |\n| macOS   | Supported   |\n| Windows | Help Needed |\n\n# Add to your project \n\n## rebar.config\n\n``` erlang\n{deps, [\n    {quicer, {git, \"https://github.com/emqx/quic.git\", {tag, \"0.2.4\"}}},\n    ...\n```\n\n## mix.exs\n\n``` elixir\ndefp deps do\n  [\n    {:quicer, git: \"https://github.com/emqx/quic.git\", tag: \"0.2.4\"},\n    ...\n  ]\nend\n\n```\n\n# Examples\n\n## Ping Pong server and client\n\n### Server\n\n``` erlang\napplication:ensure_all_started(quicer),\nPort = 4567,\nLOptions = [ {certfile, \"cert.pem\"}\n           , {keyfile,  \"key.pem\"}\n           , {alpn, [\"sample\"]}\n           , {peer_bidi_stream_count, 1}\n             ],\n{ok, L} = quicer:listen(Port, LOptions),\n{ok, Conn} = quicer:accept(L, [], 120000),\n{ok, Conn} = quicer:handshake(Conn),\n{ok, Stm} = quicer:accept_stream(Conn, []),\nreceive {quic, \u003c\u003c\"ping\"\u003e\u003e, Stm, _Props} -\u003e ok end,\n{ok, 4} = quicer:send(Stm, \u003c\u003c\"pong\"\u003e\u003e),\nquicer:close_listener(L).\n```\n\n### Client\n\n``` erlang\napplication:ensure_all_started(quicer),\nPort = 4567,\n{ok, Conn} = quicer:connect(\"localhost\", Port, [{alpn, [\"sample\"]}, {verify, none}], 5000),\n{ok, Stm} = quicer:start_stream(Conn, []),\n{ok, 4} = quicer:send(Stm, \u003c\u003c\"ping\"\u003e\u003e),\nreceive {quic, \u003c\u003c\"pong\"\u003e\u003e, Stm, _Props} -\u003e ok end,\nok = quicer:close_connection(Conn).\n```\n\n## Try connect to Google with QUIC transport\n\n``` erlang\n%% Connect to google and disconnect, \n%% You could also tweak the parameters to see how it goes\n{ok, Conn} = quicer:connect(\"google.com\", 443, [{alpn, [\"h3\"]}, \n                            {verify, verify_peer}, \n                            {peer_unidi_stream_count, 3}], 5000),\nquicer:shutdown_connection(Conn).\n```\n\n## More examples in test dir\n\nrefer to [test](./test) dir.\n\n# Documentation\n\n## Get Started\n\n1. Understand the `handles` and the `ownership` in [Terminology](docs/Terminology.md)\n\n1. Then check how to receives the data and signals:  [Messages](docs/messages_to_owner.md)\n\n1. Read more in [msquic doc](https://github.com/microsoft/msquic/tree/main/docs)\n\n## Offline hex doc\n\n``` sh\nmake doc\nfirefox doc/index.html\n```\n\n# Dependencies\n\n1. OTP25+\n1. rebar3\n1. cmake3.16+\n\n# Build and test\n\n## Dev mode\n``` sh\nmake ci\n```\n\n# Troubleshooting \n\n### Log to `stdout`\n\nDebug log could be enabled to print to `stdout` with the envvar `QUIC_LOGGING_TYPE=stdout` \n\n``` sh\nQUIC_LOGGING_TYPE=stdout make\n```\n\n``` sh\n%% Debug one testcase\nQUIC_LOGGING_TYPE=stdout rebar3 ct --suite test/quicer_connection_SUITE.erl --case tc_conn_basic_verify_peer\n```\n\n### Decrypt traffic with Wireshark\n\nClient could specify the connect param `sslkeylogfile` to record tls secrets for wireshark to decrypt.\n\n``` erlang\n    {ok, Conn} = quicer:connect(\n        \"google.com\",\n        443,\n        [\n            {verify, verify_peer},\n            {sslkeylogfile, \"/tmp/SSLKEYLOGFILE\"},\n            {peer_unidi_stream_count, 3},\n            {alpn, [\"h3\"]}\n        ],\n        5000\n    )\n```\n\n# License\nApache License Version 2.0\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femqx%2Fquic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femqx%2Fquic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femqx%2Fquic/lists"}