FileInfoPtr FileInfoService::query(const std::string& _filename) { std::string filename(_filename[_filename.size() - 1] == '/' ? _filename.substr(0, _filename.size() - 1) : _filename); auto i = cache_.find(filename); if (i != cache_.end()) { FileInfoPtr fi = i->second; if (isValid(fi.get())) { TRACE("query.cached(%s) len:%ld\n", filename.c_str(), fi->size()); return fi; } TRACE("query.expired(%s) len:%ld\n", filename.c_str(), fi->size()); #if defined(HAVE_SYS_INOTIFY_H) if (fi->inotifyId_ >= 0) { inotify_rm_watch(handle_, fi->inotifyId_); auto i = inotifies_.find(fi->inotifyId_); if (i != inotifies_.end()) inotifies_.erase(i); } #endif cache_.erase(i); } if (FileInfoPtr fi = FileInfoPtr(new FileInfo(*this, filename))) { fi->mimetype_ = get_mimetype(filename); fi->etag_ = make_etag(*fi); #if defined(HAVE_SYS_INOTIFY_H) int wd = handle_ != -1 && fi->exists() ? ::inotify_add_watch(handle_, filename.c_str(), /*IN_ONESHOT |*/ IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_DELETE_SELF | IN_MOVE_SELF) : -1; TRACE("query(%s).new -> %d len:%ld\n", filename.c_str(), wd, fi->size()); if (wd != -1) { fi->inotifyId_ = wd; inotifies_[wd] = fi; } cache_[filename] = fi; #else TRACE("query(%s)! len:%ld\n", filename.c_str(), fi->size()); cache_[filename] = fi; #endif return fi; } TRACE("query(%s) failed (%s)\n", filename.c_str(), strerror(errno)); // either ::stat() or caching failed. return FileInfoPtr(); }
/* * setup_session * * Create a new session for the given handler */ void setup_session(struct handler_args* hargs, xmlHashTablePtr sessions, struct qz_config* conf){ struct session * this_session; // session_id is a number here, a string in the session struct, // and the encrypted contents of the session key, same value for each. uint64_t session_id; this_session = calloc(1, sizeof(struct session)); // Assign a random number that has no zero octets // as the session identifier, then test it. session_id = qzrandom64ch(this_session->session_id); // There is a risk of session id collisions that // is larger than might be hoped from the // birthday paradox. // With around 200 users, the chance of a hash key // collission is around 10^-15. This is on the order // of random bit errors and cosmic ray bit flipping. // With around 6000 users, the chance goes up to // around 10^-6, or once in a million. // Or it could be the NSA is messing with your PRNG, // or it could be your PRNG is setup wrong. // In any case, it is bad and wrong to continue. struct session* test_for_session; test_for_session = xmlHashLookup(sessions, this_session->session_id); if (test_for_session != NULL){ fprintf(hargs->log, "%f %d %s:%d collision in session identifiers - %s\n", gettime(), hargs->request_id, __func__, __LINE__, "terminating application now"); FCGX_FPrintF(hargs->err, "collision in session identifiers - ending program now\n"); exit(49); } if (pthread_mutex_init( &(this_session->session_lock), NULL) != 0){ fprintf(hargs->log, "%f %d %s:%d mutex_init failed\n", gettime(), hargs->request_id, __func__, __LINE__); fflush(hargs->log); free(this_session); return; } make_etag(hargs->session_key, conf->tagger_socket_path, session_id); snprintf(this_session->tagger_socket_path, MAXPATHLEN, "%s", conf->tagger_socket_path); this_session->zero = 0; this_session->is_logged_in = false; this_session->logged_in_time = 0; this_session->logged_out_time = 0; this_session->last_activity_time = time(NULL); this_session->conn = NULL; // 197 is just an arbritrary value. // It is prime, hashes should be a prime size. // These should be in the config file. XXXXXXXXXXXXX this_session->opentables = xmlHashCreate(197); this_session->pgtype_datum = xmlHashCreate(197); this_session->form_tags = xmlHashCreate(197); this_session->form_sets = xmlHashCreate(197); this_session->integrity_token = conf->integrity_token; // index on session_id for crypto etag xmlHashAddEntry(sessions, this_session->session_id, this_session); // cookie path is /qz/ or whatever is used as the base path char* uri_parts[] = {hargs->uri_parts[0],"",NULL}; char* path = build_path(uri_parts); make_cookie(hargs, "session_key", hargs->session_key, path, NULL, 0, false, true); free(path); hargs->session = this_session; fprintf(hargs->log, "%f %d %s:%d setup_session complete\n", gettime(), hargs->request_id, __func__, __LINE__); return; }