summaryrefslogtreecommitdiffstats
path: root/modules/metadata/mod_unique_id.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/metadata/mod_unique_id.c')
-rw-r--r--modules/metadata/mod_unique_id.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/modules/metadata/mod_unique_id.c b/modules/metadata/mod_unique_id.c
index 0b05fbf..2555749 100644
--- a/modules/metadata/mod_unique_id.c
+++ b/modules/metadata/mod_unique_id.c
@@ -26,6 +26,11 @@
#include "apr_general.h" /* for APR_OFFSETOF */
#include "apr_network_io.h"
+#ifdef APR_HAS_THREADS
+#include "apr_atomic.h" /* for apr_atomic_inc32 */
+#include "mpm_common.h" /* for ap_mpm_query */
+#endif
+
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
@@ -104,7 +109,7 @@ typedef struct {
/*
* Sun Jun 7 05:43:49 CEST 1998 -- Alvaro
* More comments:
- * 1) The UUencoding prodecure is now done in a general way, avoiding the problems
+ * 1) The UUencoding procedure is now done in a general way, avoiding the problems
* with sizes and paddings that can arise depending on the architecture. Now the
* offsets and sizes of the elements of the unique_id_rec structure are calculated
* in unique_id_global_init; and then used to duplicate the structure without the
@@ -123,6 +128,10 @@ typedef struct {
* XXX: thrashing.
*/
static unique_id_rec cur_unique_id;
+static apr_uint32_t cur_unique_counter;
+#ifdef APR_HAS_THREADS
+static int is_threaded_mpm;
+#endif
/*
* Number of elements in the structure unique_id_rec.
@@ -160,6 +169,11 @@ static int unique_id_global_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *pt
static void unique_id_child_init(apr_pool_t *p, server_rec *s)
{
+#ifdef APR_HAS_THREADS
+ is_threaded_mpm = 0;
+ ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded_mpm);
+#endif
+
ap_random_insecure_bytes(&cur_unique_id.root,
sizeof(cur_unique_id.root));
@@ -168,28 +182,29 @@ static void unique_id_child_init(apr_pool_t *p, server_rec *s)
* against restart problems, and a little less protection against a clock
* going backwards in time.
*/
- ap_random_insecure_bytes(&cur_unique_id.counter,
- sizeof(cur_unique_id.counter));
+ ap_random_insecure_bytes(&cur_unique_counter,
+ sizeof(cur_unique_counter));
}
-/* NOTE: This is *NOT* the same encoding used by base64encode ... the last two
- * characters should be + and /. But those two characters have very special
- * meanings in URLs, and we want to make it easy to use identifiers in
- * URLs. So we replace them with @ and -.
- */
+/* Use the base64url encoding per RFC 4648, avoiding characters which
+ * are not safe in URLs. ### TODO: can switch to apr_encode_*. */
static const char uuencoder[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
};
+#ifndef APR_UINT16_MAX
+#define APR_UINT16_MAX 0xffffu
+#endif
+
static const char *gen_unique_id(const request_rec *r)
{
char *str;
/*
- * Buffer padded with two final bytes, used to copy the unique_id_red
+ * Buffer padded with two final bytes, used to copy the unique_id_rec
* structure without the internal paddings that it could have.
*/
unique_id_rec new_unique_id;
@@ -197,14 +212,24 @@ static const char *gen_unique_id(const request_rec *r)
unique_id_rec foo;
unsigned char pad[2];
} paddedbuf;
+ apr_uint32_t counter;
unsigned char *x,*y;
- unsigned short counter;
int i,j,k;
memcpy(&new_unique_id.root, &cur_unique_id.root, ROOT_SIZE);
- new_unique_id.counter = cur_unique_id.counter;
new_unique_id.stamp = htonl((unsigned int)apr_time_sec(r->request_time));
new_unique_id.thread_index = htonl((unsigned int)r->connection->id);
+#ifdef APR_HAS_THREADS
+ if (is_threaded_mpm)
+ counter = apr_atomic_inc32(&cur_unique_counter);
+ else
+#endif
+ counter = cur_unique_counter++;
+
+ /* The counter is two bytes for the uuencoded unique id, in network
+ * byte order.
+ */
+ new_unique_id.counter = htons(counter % APR_UINT16_MAX);
/* we'll use a temporal buffer to avoid uuencoding the possible internal
* paddings of the original structure */
@@ -236,11 +261,6 @@ static const char *gen_unique_id(const request_rec *r)
}
str[k++] = '\0';
- /* and increment the identifier for the next call */
-
- counter = ntohs(new_unique_id.counter) + 1;
- cur_unique_id.counter = htons(counter);
-
return str;
}