static int updatePassFile(char *passFile) { User *up; char tempFile[MPR_MAX_FNAME]; int fd; mprMakeTempFileName(tempFile, sizeof(tempFile), "httpPass", 1); fd = open(tempFile, O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664); if (fd < 0) { mprError(MPR_L, MPR_USER, "Can't open %s\n", tempFile); return MPR_ERR_CANT_OPEN; } up = (User*) users.getFirst(); while (up) { if (mprFprintf(fd, "%d: %s: %s: %s\n", up->getEnabled(), up->getName(), up->getRealm(), up->getPassword()) < 0) { mprError(MPR_L, MPR_USER, "Can't write to %s\n", tempFile); return MPR_ERR_CANT_WRITE; } up = (User*) users.getNext(up); } close(fd); unlink(passFile); if (rename(tempFile, passFile) < 0) { mprError(MPR_L, MPR_USER, "Can't rename %s to %s\n", tempFile, passFile); return MPR_ERR_CANT_WRITE; } return 0; }
static void addUser(char *user, char *realm, char *password, bool enabled) { User *up; up = (User*) users.getFirst(); while (up) { if (strcmp(user, up->getName()) == 0 && strcmp(realm, up->getRealm()) == 0) { up->setPassword(password); return; } up = (User*) users.getNext(up); } users.insert(new User(user, realm, password, enabled)); }
static void readEventWrapper(void *data, MprSocket *sp, int mask, int isPoolThread) { MaClient *cp; int moreData, loopCount; mprLog(5, "%d: readEventWrapper: mask %x, isPool %d\n", sp->getFd(), mask, isPoolThread); // // Make sure we are not being deleted // mprGetMpr()->lock(); cp = (MaClient*) clients.getFirst(); while (cp) { if (cp == (MaClient*) data) { break; } cp = (MaClient*) clients.getNext(cp); } if (cp == 0) { mprError(MPR_L, MPR_LOG, "Client deleted prematurely."); return; } cp->lock(); mprGetMpr()->unlock(); // // If we are multi-threaded and called on a pool thread, we can block and // read as much data as we can. If single threaded, just do 25 reads. // loopCount = 25; do { moreData = cp->readEvent(); if (cp->getState() == MPR_HTTP_CLIENT_DONE) { cp->signalComplete(); break; } } while (moreData > 0 && (isPoolThread || loopCount-- > 0)); cp->unlock(); }
MprCond::~MprCond() { mutex->lock(); pthread_cond_destroy(&cv); #if BLD_DEBUG condList.remove(&link); #endif delete mutex; }
MprCond::MprCond() { memset(&cv, 0, sizeof(cv)); mutex = new MprMutex(); triggered = 0; pthread_cond_init(&cv, NULL); #if BLD_DEBUG condList.insert(&link); #endif }
MprMutex::~MprMutex() { pthread_mutex_unlock(&cs); pthread_mutex_destroy(&cs); #if BLD_DEBUG pthread_mutex_lock(&listLock); mutexList.remove(&link); pthread_mutex_unlock(&listLock); #endif }
MprMutex::MprMutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); memset(&cs, 0, sizeof(cs)); pthread_mutex_init(&cs, &attr); pthread_mutexattr_destroy(&attr); #if BLD_DEBUG pthread_mutex_lock(&listLock); mutexList.insert(&link); pthread_mutex_unlock(&listLock); #endif }
static int readPassFile(char *passFile) { FILE *fp; char buf[MPR_HTTP_MAX_PASS * 2]; char *tok, *enabledSpec, *user, *realm, *password; bool enabled; int line; fp = fopen(passFile, "r" MPR_TEXT); if (fp == 0) { mprError(MPR_L, MPR_USER, "Can't open %s\n", passFile); return MPR_ERR_CANT_OPEN; } line = 0; while (fgets(buf, sizeof(buf), fp) != 0) { line++; enabledSpec = mprStrTok(buf, ":", &tok); user = mprStrTok(0, ":", &tok); realm = mprStrTok(0, ":", &tok); password = mprStrTok(0, "\n\r", &tok); if (enabledSpec == 0 || user == 0 || realm == 0 || password == 0) { mprError(MPR_L, MPR_USER, "Badly formed password on line %d\n", line); return MPR_ERR_CANT_OPEN; } user = trimWhiteSpace(user); if (*user == '#' || *user == '\0') { continue; } enabled = (enabledSpec[0] == '1'); realm = trimWhiteSpace(realm); password = trimWhiteSpace(password); users.insert(new User(user, realm, password, enabled)); } fclose(fp); return 0; }
MprThreadService::~MprThreadService() { lock(); // // We expect users who created the threads to delete them prior to this // delete mainThread; delete mutex; mutex = 0; #if BLD_DEBUG if (threads.getNumItems() > 0) { mprError(MPR_L, MPR_LOG, "Exiting with %d thread(s) unfreed", threads.getNumItems()); } if (condList.getNumItems() > 0) { mprError(MPR_L, MPR_LOG, "Exiting with %d cond var(s) unfreed", condList.getNumItems()); } pthread_mutex_lock(&listLock); if (mutexList.getNumItems() > 0) { mprError(MPR_L, MPR_LOG, "Exiting with %d mutex(es) unfreed", mutexList.getNumItems() - 0); MprMutex *mp; mp = (MprMutex*) mutexList.getFirst(); while (mp) { mprLog(0, "Mutex %x unfreed\n", mp); mp = (MprMutex*) mutexList.getNext(&mp->link); } } pthread_mutex_unlock(&listLock); pthread_mutex_destroy(&listLock); #endif }
static int configureViaApi() { MaHostAddress *address; MaHost *host; MprList *listens; MaListen *lp; MprHashTable *hostAddresses; MaDir *dir; MaAlias *ap; MaLocation *loc; char *cp, *docRootPath; char addrBuf[MPR_MAX_IP_ADDR_PORT], pathBuf[MPR_MAX_FNAME]; int port; mprLog(MPR_CONFIG, "Configuration via Command Line\n"); #if BLD_FEATURE_ROMFS mprLog(MPR_CONFIG, "Server Root \"%s\" in ROM\n", serverRoot); docRootPath = mprStrdup(docRoot); #else // // Set the document root. Is relative to the server root unless an absolute path is used. // #if WIN if (*docRoot != '/' && docRoot[1] != ':' && docRoot[2] != '/') #elif WINCE if (*docRoot != '\\' && docRoot != '/') #else if (*docRoot != '/') #endif { if (*docRoot) { mprAllocSprintf(&docRootPath, MPR_MAX_FNAME, "%s/%s", serverRoot, docRoot); } else { docRootPath = mprStrdup(serverRoot); } } else { docRootPath = mprStrdup(docRoot); } #endif // BLD_FEATURE_ROMFS mprLog(MPR_CONFIG, "Document Root \"%s\"\n", docRootPath); // // Setup the listening addresses. If only a port is specified, listen on // all interfaces. If only the IP address is specified without a port, // then default to port 80. IF autoScan is on, scan for a free port // starting from the base address. // listens = server->getListens(); port = MA_SERVER_DEFAULT_PORT_NUM; if ((cp = strchr(ipAddr, ':')) != 0) { *cp++ = '\0'; port = atoi(cp); if (port <= 0 || port > 65535) { mprError(MPR_L, MPR_USER, "Bad listen port number %d", port); return MPR_ERR_BAD_SYNTAX; } if (autoScan) { port = findFreePort(ipAddr, port); } listens->insert(new MaListen(ipAddr, port, 0)); } else { if (isdigit((uchar) *ipAddr) && strchr(ipAddr, '.') == 0) { port = atoi(ipAddr); if (port <= 0 || port > 65535) { mprError(MPR_L, MPR_USER, "Bad listen port number %d", port); return MPR_ERR_BAD_SYNTAX; } if (autoScan) { port = findFreePort("", port); } listens->insert(new MaListen("", port)); } else { if (autoScan) { port = findFreePort(ipAddr, MA_SERVER_DEFAULT_PORT_NUM); } listens->insert(new MaListen(ipAddr, port)); } } mprFree(ipAddr); ipAddr = 0; host = server->newHost(docRootPath); if (host == 0) { return MPR_ERR_CANT_OPEN; } // // Add the default server listening addresses to the HostAddress hash. // FUTURE -- this should be moved into newHost // hostAddresses = server->getHostAddresses(); lp = (MaListen*) listens->getFirst(); while (lp) { mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", lp->getIpAddr(), lp->getPort()); address = (MaHostAddress*) hostAddresses->lookup(addrBuf); if (address == 0) { address = new MaHostAddress(addrBuf); hostAddresses->insert(address); } mprLog(MPR_CONFIG, "Listening for HTTP on %s\n", addrBuf); address->insertVhost(new MaVhost(host)); lp = (MaListen*) listens->getNext(lp); mprFree(ipAddr); ipAddr = mprStrdup(addrBuf); } // // Setup a module search path that works for production and developement. // #if BLD_FEATURE_DLL char searchPath[MPR_MAX_FNAME]; mprSprintf(searchPath, sizeof(searchPath), "./lib ../lib ../lib/modules ../../lib ../../lib/modules %s/lib", BLD_PREFIX); host->setModuleDirs(searchPath); #endif // // Load all possible modules // #if BLD_FEATURE_AUTH_MODULE // // Handler must be added first to authorize all requests. // if (server->loadModule("auth") == 0) { host->addHandler("authHandler", ""); } #endif #if BLD_FEATURE_UPLOAD_MODULE // // Must be after auth and before ESP, EGI. // if (server->loadModule("upload") == 0) { host->addHandler("uploadHandler", ""); } #endif #if BLD_FEATURE_CGI_MODULE if (server->loadModule("cgi") == 0) { host->addHandler("cgiHandler", ".cgi .cgi-nph .bat .cmd .pl .py"); } #endif #if BLD_FEATURE_EGI_MODULE if (server->loadModule("egi") == 0) { host->addHandler("egiHandler", ".egi"); } #endif #if BLD_FEATURE_ESP_MODULE if (server->loadModule("esp") == 0) { host->addHandler("espHandler", ".esp .asp"); } #endif #if BLD_FEATURE_C_API_MODULE server->loadModule("capi"); #endif #if BLD_FEATURE_GACOMPAT_MODULE server->loadModule("compat"); #endif #if BLD_FEATURE_SSL_MODULE server->loadModule("ssl"); #endif // // Only load one of matrixSsl / openssl // #if BLD_FEATURE_OPENSSL_MODULE server->loadModule("openSsl"); #elif BLD_FEATURE_MATRIXSSL_MODULE server->loadModule("matrixSsl"); #endif #if BLD_FEATURE_PHP5_MODULE if (server->loadModule("php5") == 0) { host->addHandler("php5Handler", ".php"); } #endif #if BLD_FEATURE_COPY_MODULE // // Handler must be added last to be the catch all // if (server->loadModule("copy") == 0) { host->addHandler("copyHandler", ""); } #endif // // Create the top level directory // dir = new MaDir(host); dir->setPath(docRootPath); host->insertDir(dir); // // Add cgi-bin // mprSprintf(pathBuf, sizeof(pathBuf), "%s/cgi-bin", serverRoot); ap = new MaAlias("/cgi-bin/", pathBuf); mprLog(4, "ScriptAlias \"/cgi-bin/\":\n\t\t\t\"%s\"\n", pathBuf); host->insertAlias(ap); loc = new MaLocation(dir->getAuth()); loc->setPrefix("/cgi-bin/"); loc->setHandler("cgiHandler"); host->insertLocation(loc); mprFree(docRootPath); return 0; }
MaClient::MaClient() { authCnonce = 0; authNc = 0; serverAlgorithm = 0; serverDomain = 0; serverNonce = 0; serverOpaque = 0; serverRealm = 0; serverQop = 0; serverStale = 0; serverAuthType = 0; callbackArg = 0; callback = 0; contentLength = 0; contentRemaining = -1; currentHost = 0; currentPort = -1; defaultHost = 0; defaultPort = -1; errorMsg = 0; flags = 0; fd = -1; inBuf = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE + 1, -1); headerValues = 0; method = 0; outBuf = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE, MPR_HTTP_CLIENT_BUFSIZE); password = 0; proxyHost = 0; proxyPort = -1; realm = 0; retries = MPR_HTTP_CLIENT_RETRIES; responseCode = -1; responseProto = 0; responseContent = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE, -1); responseHeader = new MprBuf(MPR_HTTP_CLIENT_BUFSIZE, MPR_HTTP_MAX_HEADER); responseText = 0; secret = 0; sock = 0; state = MPR_HTTP_CLIENT_START; timeoutPeriod = MPR_HTTP_CLIENT_TIMEOUT; timer = 0; timestamp = 0; user = 0; userFlags = MPR_HTTP_KEEP_ALIVE; userHeaders = 0; #if BLD_FEATURE_LOG tMod = new MprLogModule("client"); #endif #if BLD_FEATURE_MULTITHREAD completeCond = new MprCond(); mutex = new MprMutex(); #endif #if BLD_FEATURE_MULTITHREAD // FUTURE -- ideal case for spin-locks mprGetMpr()->lock(); #endif clients.insert(this); #if BLD_FEATURE_MULTITHREAD mprGetMpr()->unlock(); #endif }
MaClient::~MaClient() { // // Must be careful because readEventWrapper is passed "this" and must // not accessed a deleted object. Remove from the list of clients safely // and readEventWrapper will check if it has been deleted. // mprGetMpr()->lock(); lock(); mprGetMpr()->unlock(); clients.remove(this); if (sock) { sock->setCallback(readEventWrapper, (void*) this, 0, 0); mprLog(3, tMod, "%d: ~MaClient: close sock\n", sock->getFd()); sock->close(0); sock->dispose(); sock = 0; } delete headerValues; delete inBuf; delete outBuf; delete responseContent; delete responseHeader; mprFree(authCnonce); mprFree(method); mprFree(serverAlgorithm); mprFree(serverDomain); mprFree(serverNonce); mprFree(serverOpaque); mprFree(serverRealm); mprFree(serverQop); mprFree(serverStale); mprFree(serverAuthType); mprFree(errorMsg); mprFree(defaultHost); mprFree(proxyHost); mprFree(realm); mprFree(responseProto); mprFree(responseText); mprFree(password); mprFree(user); mprFree(userHeaders); mprFree(secret); if (timer) { timer->stop(MPR_TIMEOUT_STOP); timer->dispose(); timer = 0; } #if BLD_FEATURE_LOG delete tMod; #endif #if BLD_FEATURE_MULTITHREAD delete completeCond; delete mutex; #endif }