1: 9c6a340119 = 1: 0278c7ba90 common/jsonapi: support FRONTEND clients 2: 8072d0416e ! 2: bb3ce4b6a9 libpq: add OAUTHBEARER SASL mechanism @@ src/interfaces/libpq/fe-auth-oauth-curl.c (new) +#include "libpq-int.h" +#include "mb/pg_wchar.h" + -+#ifdef HAVE_SYS_EVENT_H -+/* macOS doesn't define the time unit macros, but uses milliseconds by default. */ -+#ifndef NOTE_MSECONDS -+#define NOTE_MSECONDS 0 -+#endif -+#endif -+ +/* + * Parsed JSON Representations + * @@ src/interfaces/libpq/fe-auth-oauth-curl.c (new) + switch (what) + { + case CURL_POLL_IN: -+ EV_SET(&ev[nev], socket, EVFILT_READ, EV_ADD, 0, 0, 0); ++ EV_SET(&ev[nev], socket, EVFILT_READ, EV_ADD | EV_RECEIPT, 0, 0, 0); + nev++; + break; + + case CURL_POLL_OUT: -+ EV_SET(&ev[nev], socket, EVFILT_WRITE, EV_ADD, 0, 0, 0); ++ EV_SET(&ev[nev], socket, EVFILT_WRITE, EV_ADD | EV_RECEIPT, 0, 0, 0); + nev++; + break; + + case CURL_POLL_INOUT: -+ EV_SET(&ev[nev], socket, EVFILT_READ, EV_ADD, 0, 0, 0); ++ EV_SET(&ev[nev], socket, EVFILT_READ, EV_ADD | EV_RECEIPT, 0, 0, 0); + nev++; -+ EV_SET(&ev[nev], socket, EVFILT_WRITE, EV_ADD, 0, 0, 0); ++ EV_SET(&ev[nev], socket, EVFILT_WRITE, EV_ADD | EV_RECEIPT, 0, 0, 0); + nev++; + break; + @@ src/interfaces/libpq/fe-auth-oauth-curl.c (new) + * both, so we try to remove both. This means we need to tolerate + * ENOENT below. + */ -+ EV_SET(&ev[nev], socket, EVFILT_READ, EV_DELETE, 0, 0, 0); ++ EV_SET(&ev[nev], socket, EVFILT_READ, EV_DELETE | EV_RECEIPT, 0, 0, 0); + nev++; -+ EV_SET(&ev[nev], socket, EVFILT_WRITE, EV_DELETE, 0, 0, 0); ++ EV_SET(&ev[nev], socket, EVFILT_WRITE, EV_DELETE | EV_RECEIPT, 0, 0, 0); + nev++; + break; + @@ src/interfaces/libpq/fe-auth-oauth-curl.c (new) + */ + for (int i = 0; i < res; ++i) + { -+ if (ev_out[i].flags & EV_ERROR && ev_out[i].data != ENOENT) ++ /* ++ * EV_RECEIPT should guarantee one EV_ERROR result for every change, ++ * whether successful or not. Failed entries contain a non-zero errno in ++ * the `data` field. ++ */ ++ Assert(ev_out[i].flags & EV_ERROR); ++ ++ errno = ev_out[i].data; ++ if (errno && errno != ENOENT) + { -+ errno = ev_out[i].data; + switch (what) + { + case CURL_POLL_REMOVE: @@ src/interfaces/libpq/fe-auth-oauth-curl.c (new) + struct kevent ev; + + EV_SET(&ev, 1, EVFILT_TIMER, timeout < 0 ? EV_DELETE : EV_ADD, -+ NOTE_MSECONDS, timeout, 0); ++ 0, timeout, 0); + if (kevent(actx->mux, &ev, 1, NULL, 0, NULL) < 0 && errno != ENOENT) + { + actx_error(actx, "setting kqueue timer to %ld: %m", timeout); @@ src/interfaces/libpq/fe-auth-oauth-curl.c (new) +#endif +#ifdef HAVE_SYS_EVENT_H + // XXX: I guess this wants to be hidden in a routine -+ EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD, NOTE_MSECONDS, ++ EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD, 0, + actx->authz.interval * 1000, 0); + if (kevent(actx->mux, &ev, 1, NULL, 0, NULL) < 0) + { 3: 07be9375aa = 3: 20b7522228 backend: add OAUTHBEARER SASL mechanism 4: 71cedc6ff5 = 4: f3cec068f9 Add pytest suite for OAuth 5: 9b02e14829 = 5: da1933ac1d squash! Add pytest suite for OAuth 6: 7d179f7e53 = 6: 8f36b5c124 XXX work around psycopg2 build failures