Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listener Example #161

Open
WindowsNT opened this issue Aug 7, 2023 · 11 comments
Open

Listener Example #161

WindowsNT opened this issue Aug 7, 2023 · 11 comments
Labels
documentation Improvements or additions to documentation

Comments

@WindowsNT
Copy link

I did this:

MsH3Api Api;
auto ct = MyCert();
 MSH3_CERTIFICATE_CONFIG ccfg = {};
 MSH3_CERTIFICATE_CONTEXT* c2 = (MSH3_CERTIFICATE_CONTEXT*)ct;
 ccfg.CertificateContext = c2;
 ccfg.Type = MSH3_CERTIFICATE_TYPE_CONTEXT;
 MsH3Certificate c(Api, ccfg);

 MsH3Addr addr;
 addr.SetPortW(p2);
  MsH3Listener li(Api,addr);
  auto conn = li.NewConnection.Wait();
    if (conn)
        {
            conn->SetCertificate(c);
            auto req = conn->NewRequest.Wait();
            if (req)
            {
                MSH3_HEADER Headers[] = {
                    { ":Content-Type", 13, "text/html", 9 },
                };
                const size_t HeadersCount = sizeof(Headers) / sizeof(MSH3_HEADER);

                req->SendHeaders(Headers, 1, MSH3_REQUEST_FLAG_NONE);
                req->Send(MSH3_REQUEST_FLAG_NONE, "Hello", 5, 0);
                MessageBox(0, L"OK", 0, 0);
            }
        }

Upon chrome connection, li.NewRequest.Wait() returns successfully a MsH3Connection* , however at that point I can't do anything else. The configuration/certificate is supposed to be created before the callback returns.

Any clues on the server usage?

@nibanks
Copy link
Owner

nibanks commented Aug 7, 2023

Have you looked at the test code here? It might help you put things together.

@WindowsNT
Copy link
Author

WindowsNT commented Aug 7, 2023

I tried, I'm not sure what I 'm doing wrong.

        auto conn = li.NewConnection.Wait();
        if (conn)
        {
            conn->SetCertificate(c);
            conn->Connected.Wait();

// this never returns;

@nibanks
Copy link
Owner

nibanks commented Aug 7, 2023

Are you using a self-signed certificate? I believe you have to do some special stuff on the Chrome side to get it to accept self-signed certs.

@WindowsNT
Copy link
Author

WindowsNT commented Aug 7, 2023

Yes, this certificate is imported to the trusted store so Chrome considers it safe. It is also used to the normal HTTP server which contains the alt-svc header that redirects to quic.

As I asked before, the certificate must be passed on callback, are you sure I have to do it after the connection is returned?

@nibanks
Copy link
Owner

nibanks commented Aug 7, 2023

You can grab MsQuic logs to see what exactly is happening at the QUIC layer, but I suspect you'll need to look at Chrome logs to see what's up. I still suspect certificate issues. Chrome might not use the machine store to validate certificates, but instead maintain its own list of trusted CAs.

@WindowsNT
Copy link
Author

WindowsNT commented Aug 9, 2023

No, Chrome uses the machine store to validate, because in my HTTP local server the certificate works. As I said, I suspect that the certificate isn't set correctly.

       MSH3_CERTIFICATE_CONFIG ccfg = {};
      MSH3_CERTIFICATE_CONTEXT* c2 = (MSH3_CERTIFICATE_CONTEXT*)ct;
      ccfg.CertificateContext = c2;
      ccfg.Type = MSH3_CERTIFICATE_TYPE_CONTEXT;
      MsH3Certificate c(Api, ccfg);

        auto conn = li.NewConnection.Wait();
        if (conn)
        {                
            MsH3ConnectionSetCertificate((MSH3_CONNECTION*)conn, c); // is this correct?
        }

@WindowsNT
Copy link
Author

Btw in curl it works
curl https://localhost:5014/ --http3 -v -i -k -d "Hello"

@nibanks
Copy link
Owner

nibanks commented Aug 10, 2023

Have you tried to grab Chrome logs? What version of HTTP/3 did you use with curl? msh3 or one of the others?

@WindowsNT
Copy link
Author

WindowsNT commented Aug 10, 2023

curl uses ngtcp2.I will have to check Chrome's certificate stuff because in plain HTTPS it uses the store, it seems there's not the case in quic.

Another thing: is this correct? curl receives the headers but then says 'HTTP/3 stream 0 was not closed cleanly: (err 270)
Connection #0 to host localhost left intact
curl: (95) HTTP/3 stream 0 was not closed cleanly: (err 270)'

Between msquic it works correctly.

    if (conn)
    {
        MsH3ConnectionSetCertificate(conn->operator MSH3_CONNECTION * (), c);
        auto req = conn->NewRequest.Wait();
        if (req)
        {
            req->SetReceiveEnabled(1);
            req->HeaderRecvFn = [](MsH3Request* r, const MSH3_HEADER* hdr)
            {
                if (hdr->Name)
                    nop();
                if (hdr->Value)
                    nop();
            };
            req->DataRecvFn = [](MsH3Request* r, uint32_t* Length, const uint8_t* Data) -> bool
            {
                nop();
                return true;
            };
            req->CompleteFn = [](MsH3Request* r, bool Aborted, uint64_t AbortError)
            {
                nop();
            };
            req->Complete.Wait();

            MSH3_HEADER Headers[] = {
                { ":status", 0, "200", 0 },
                { ":content-type", 0, "text/html", 0 },
                { ":content-length", 0, "10", 0 },
                { ":host", 0, "localhost:5014", 0 },
                { ":authority", 0, "localhost:5014", 0 },
            };
            const size_t HeadersCount = sizeof(Headers) / sizeof(MSH3_HEADER);
            for (int i = 0; i < HeadersCount; i++)
            {
                Headers[i].NameLength = strlen(Headers[i].Name);
                Headers[i].ValueLength = strlen(Headers[i].Value);
            }
            req->SendHeaders(Headers, HeadersCount, MSH3_REQUEST_FLAG_NONE);
            req->Send(MSH3_REQUEST_FLAG_NONE, "HelloThere", 10, 0);
            req->Shutdown(MSH3_REQUEST_SHUTDOWN_FLAG_GRACEFUL, 0);
            req->ShutdownComplete.Wait();
            conn->Shutdown(0);
            conn->ShutdownComplete.Wait();
            ExitProcess(0);
        }
    }   

@WindowsNT
Copy link
Author

  1. Tested with a letsencrypt certificate, Chrome/Edge works. It surely was a certificate issue. Thanks for your support.
    1. Curl still doesn't like req->Send(). It fails after req->SendHeaders. Chrome works.

@nibanks
Copy link
Owner

nibanks commented Aug 12, 2023

Curl still doesn't like req->Send(). It fails after req->SendHeaders. Chrome works.

Could be a bug in the HTTP stack you're using with Curl. Try the msh3 version of curl?

@nibanks nibanks added the documentation Improvements or additions to documentation label Jan 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants