--- /dev/null
+#ifndef SQUID_SRC_AUTH_QUEUENODE_H
+#define SQUID_SRC_AUTH_QUEUENODE_H
+
+namespace Auth
+{
+
+/**
+ * A queue of auth requests waiting for verification to occur.
+ *
+ * Certain authentication schemes such a Basic and Bearer auth
+ * permit credentials tokens to be repeated from multiple sources
+ * simultaneously. This queue node allows multiple validation
+ * queries to be collapsed into one backend helper lookup.
+ * CBDATA and handlers stored in these queue nodes can be notified
+ * all at once with a result when the lookup completes.
+ */
+class QueueNode
+{
+
+private:
+ // we store CBDATA here, copy is not safe
+ QueueNode(const QueueNode &);
+ QueueNode &operator =(const QueueNode &);
+
+public:
+ QueueNode(Auth::UserRequest *aRequest, AUTHCB *aHandler, void *aData) : auth_user_request(aRequest), handler(aHandler), data(cbdataReference(aData)) {}
+ ~QueueNode() {
+ cbdataReferenceDone(data);
+ while (next) {
+ QueueNode *tmp = next->next;
+ next->next = NULL;
+ delete next;
+ next = tmp;
+ };
+ }
+
+ Auth::QueueNode *next;
+ Auth::UserRequest::Pointer auth_user_request;
+ AUTHCB *handler;
+ void *data;
+
+ MEMPROXY_CLASS(Auth::QueueNode);
+};
+
+MEMPROXY_CLASS_INLINE(Auth::QueueNode);
+
+} // namespace Auth
+
+#endif /* SQUID_SRC_AUTH_QUEUENODE_H */
#include "auth/basic/auth_basic.h"
#include "auth/basic/User.h"
#include "auth/basic/UserRequest.h"
+#include "auth/QueueNode.h"
#include "auth/State.h"
#include "charset.h"
#include "Debug.h"
if (user()->credentials() == Auth::Pending) {
/* there is a request with the same credentials already being verified */
- BasicAuthQueueNode *node = static_cast<BasicAuthQueueNode *>(xcalloc(1, sizeof(BasicAuthQueueNode)));
- assert(node);
- node->auth_user_request = this;
- node->handler = handler;
- node->data = cbdataReference(data);
+ Auth::QueueNode *node = new Auth::QueueNode(this, handler, data);
/* queue this validation request to be infored of the pending lookup results */
- node->next = basic_auth->auth_queue;
- basic_auth->auth_queue = node;
+ node->next = basic_auth->queue;
+ basic_auth->queue = node;
return;
}
// otherwise submit this request to the auth helper(s) for validation
Auth::Basic::UserRequest::HandleReply(void *data, const HelperReply &reply)
{
Auth::StateData *r = static_cast<Auth::StateData *>(data);
- BasicAuthQueueNode *tmpnode;
void *cbdata;
debugs(29, 5, HERE << "reply=" << reply);
cbdataReferenceDone(r->data);
- while (basic_auth->auth_queue) {
- tmpnode = basic_auth->auth_queue->next;
+ while (basic_auth->queue) {
+ if (cbdataReferenceValidDone(basic_auth->queue->data, &cbdata))
+ basic_auth->queue->handler(cbdata);
- if (cbdataReferenceValidDone(basic_auth->auth_queue->data, &cbdata))
- basic_auth->auth_queue->handler(cbdata);
+ Auth::QueueNode *tmpnode = basic_auth->queue->next;
+ basic_auth->queue->next = NULL;
+ delete basic_auth->queue;
- xfree(basic_auth->auth_queue);
-
- basic_auth->auth_queue = tmpnode;
+ basic_auth->queue = tmpnode;
}
delete r;