ret_t cherokee_regex_table_get (cherokee_regex_table_t *table, char *pattern, void **regex) { ret_t ret; /* Check if it is already in the cache */ CHEROKEE_RWLOCK_READER(&table->rwlock); ret = cherokee_avl_get_ptr (&table->cache, pattern, regex); CHEROKEE_RWLOCK_UNLOCK(&table->rwlock); if (ret == ret_ok) return ret_ok; /* It wasn't there; add a new entry */ return _add (table, pattern, regex); }
static ret_t _add (cherokee_regex_table_t *table, char *pattern, void **regex) { ret_t ret; const char *error_msg; int error_offset; void *tmp = NULL; /* It wasn't in the cache. Lets go to compile the pattern.. * First of all, we have to check again the table because another * thread could create a new entry after the previous unlock. */ CHEROKEE_RWLOCK_WRITER (&table->rwlock); ret = cherokee_avl_get_ptr (&table->cache, pattern, &tmp); if ((tmp != NULL) && (ret == ret_ok)) { if (regex != NULL) *regex = tmp; CHEROKEE_RWLOCK_UNLOCK (&table->rwlock); return ret_ok; } tmp = pcre_compile (pattern, 0, &error_msg, &error_offset, NULL); if (tmp == NULL) { LOG_ERROR (CHEROKEE_ERROR_REGEX_COMPILATION, pattern, error_msg, error_offset); CHEROKEE_RWLOCK_UNLOCK (&table->rwlock); return ret_error; } cherokee_avl_add_ptr (&table->cache, pattern, tmp); CHEROKEE_RWLOCK_UNLOCK (&table->rwlock); if (regex != NULL) *regex = tmp; return ret_ok; }
static ret_t match (cherokee_rule_extensions_t *rule, cherokee_connection_t *conn, cherokee_config_entry_t *ret_conf) { ret_t ret; char *dot; char *slash; char *end; char *p; void *foo; char *dot_prev = NULL; UNUSED(ret_conf); end = conn->request.buf + conn->request.len; p = end - 1; /* For each '.' */ while (p > conn->request.buf) { if (*p != '.') { p--; continue; } if (p[1] == '\0') { p--; continue; } if (p[1] == '/') { p--; continue; } dot = p; slash = NULL; /* Find a slash after the dot */ while (p < end) { if (*p == '/') { slash = p; *p = '\0'; break; } p++; if ((dot_prev != NULL) && (p >= dot_prev)) { break; } } /* Check it out */ ret = cherokee_avl_get_ptr (&rule->extensions, dot+1, &foo); switch (ret) { case ret_ok: if (rule->check_local_file) { ret = local_file_exists (rule, conn, ret_conf); if (ret != ret_ok) { break; } } TRACE(ENTRIES, "Match extension: '%s'\n", dot+1); if (slash != NULL) { *slash = '/'; } return ret_ok; case ret_not_found: TRACE(ENTRIES, "Rule extension: did not match '%s'\n", dot+1); break; default: conn->error_code = http_internal_error; return ret_error; } /* Revert pathinfo match char */ if (slash != NULL) { *slash = '/'; } dot_prev = dot; p = dot - 1; } TRACE(ENTRIES, "Rule extension: nothing more to test '%s'\n", conn->request.buf); return ret_not_found; }
static ret_t load_common (cherokee_plugin_loader_t *loader, const char *modname, int flags) { ret_t ret; entry_t *entry = NULL; cherokee_plugin_info_t *info = NULL; void *dl_handle = NULL; /* If it is already loaded just return */ ret = cherokee_avl_get_ptr (&loader->table, modname, (void **)&entry); if (ret == ret_ok) return ret_ok; /* Check deps */ ret = check_deps_file (loader, modname); if (ret != ret_ok) return ret; /* Get the module info */ ret = get_info (loader, modname, flags, &info, &dl_handle); switch (ret) { case ret_ok: break; case ret_error: LOG_ERROR (CHEROKEE_ERROR_PLUGIN_NO_OPEN, modname); return ret; case ret_not_found: LOG_ERROR (CHEROKEE_ERROR_PLUGIN_NO_INFO, modname); return ret; default: SHOULDNT_HAPPEN; return ret_error; } /* Add new entry */ entry = malloc (sizeof(entry_t)); entry->dlopen_ref = dl_handle; entry->info = info; entry->built_in = false; ret = cherokee_avl_add_ptr (&loader->table, modname, entry); if (unlikely(ret != ret_ok)) { dlclose (entry->dlopen_ref); free(entry); return ret; } /* Execute init function */ ret = execute_init_func (loader, modname, entry); if (ret != ret_ok) { return ret; } return ret_ok; }