MprRomFileSystem *mprCreateRomFileSystem(MprCtx ctx, cchar *path) { MprFileSystem *fs; MprRomFileSystem *rfs; rfs = mprAllocObjZeroed(ctx, MprRomFileSystem); if (rfs == 0) { return rfs; } fs = &rfs->fileSystem; fs->accessPath = (MprAccessFileProc) accessPath; fs->deletePath = (MprDeleteFileProc) deletePath; fs->getPathInfo = (MprGetPathInfoProc) getPathInfo; fs->getPathLink = (MprGetPathLinkProc) getPathLink; fs->makeDir = (MprMakeDirProc) makeDir; fs->makeLink = (MprMakeDirProc) makeLink; fs->openFile = (MprOpenFileProc) openFile; fs->closeFile = closeFile; fs->readFile = readFile; fs->seekFile = seekFile; fs->writeFile = writeFile; #if !WINCE fs->stdError = mprAllocObjZeroed(fs, MprFile); if (fs->stdError == 0) { mprFree(fs); } fs->stdError->fd = 2; fs->stdError->fileSystem = fs; fs->stdError->mode = O_WRONLY; fs->stdInput = mprAllocObjZeroed(fs, MprFile); if (fs->stdInput == 0) { mprFree(fs); } fs->stdInput->fd = 0; fs->stdInput->fileSystem = fs; fs->stdInput->mode = O_RDONLY; fs->stdOutput = mprAllocObjZeroed(fs, MprFile); if (fs->stdOutput == 0) { mprFree(fs); } fs->stdOutput->fd = 1; fs->stdOutput->fileSystem = fs; fs->stdOutput->mode = O_WRONLY; #endif return rfs; }
MprXml *ejsCreateXmlParser(Ejs *ejs, EjsXML *xml, cchar *filename) { EjsXmlState *parser; MprXml *xp; xp = mprXmlOpen(ejs, MPR_BUFSIZE, EJS_E4X_BUF_MAX); mprAssert(xp); /* * Create the parser stack */ parser = mprAllocObjZeroed(xp, EjsXmlState); if (parser == 0) { mprFree(xp); return 0; } parser->ejs = ejs; parser->nodeStack[0].obj = xml; parser->xmlType = ejs->xmlType; parser->xmlListType = ejs->xmlListType; parser->filename = filename; mprXmlSetParseArg(xp, parser); mprXmlSetParserHandler(xp, parserHandler); return xp; }
MaAlias *maCreateAlias(MprCtx ctx, cchar *prefix, cchar *target, int code) { MaAlias *ap; mprAssert(ctx); mprAssert(prefix); ap = mprAllocObjZeroed(ctx, MaAlias); if (ap == 0) { return 0; } ap->prefix = mprStrdup(ctx, prefix); ap->prefixLen = (int) strlen(prefix); /* * Always strip trailing "/". Note this is a URL and not a path. */ if (ap->prefixLen > 0 && ap->prefix[ap->prefixLen - 1] == '/') { ap->prefix[--ap->prefixLen] = '\0'; } if (code) { ap->redirectCode = code; ap->uri = mprStrdup(ctx, target); } else { mprAssert(target && *target); ap->filename = mprGetAbsPath(ctx, target); } return ap; }
int ecOpenMemoryStream(EcLexer *lp, const uchar *buf, int len) { EcMemStream *ms; int c; ms = mprAllocObjZeroed(lp->input, EcMemStream); if (ms == 0) { return MPR_ERR_NO_MEMORY; } ms->stream.lineNumber = 0; ms->stream.buf = mprMemdup(ms, buf, len); ms->stream.nextChar = ms->stream.buf; ms->stream.end = &ms->stream.buf[len]; ms->stream.currentLine = ms->stream.buf; ms->stream.lineNumber = 1; ms->stream.compiler = lp->compiler; mprFree(lp->input->stream); lp->input->stream = (EcStream*) ms; lp->input->putBack = 0; lp->input->token = 0; lp->input->state = 0; lp->input->next = 0; /* * Initialize the stream line and column data. */ c = getNextChar(&ms->stream); putBackChar(&ms->stream, c); return 0; }
/* * Dynamic module initialization */ MprModule *maEgiHandlerInit(MaHttp *http, cchar *path) { MprModule *module; MaStage *handler; MaEgi *egi; module = mprCreateModule(http, "egiHandler", BLD_VERSION, NULL, NULL, NULL); if (module == 0) { return 0; } handler = maCreateHandler(http, "egiHandler", MA_STAGE_GET | MA_STAGE_HEAD | MA_STAGE_POST | MA_STAGE_PUT | MA_STAGE_FORM_VARS | MA_STAGE_ENV_VARS | \ MA_STAGE_VIRTUAL); if (handler == 0) { mprFree(module); return 0; } http->egiHandler = handler; handler->run = runEgi; handler->stageData = egi = mprAllocObjZeroed(handler, MaEgi); egi->forms = mprCreateHash(egi, MA_EGI_HASH_SIZE); #if EGI_TEST egiTestInit(http, path); #endif return module; }
EcLexer *ecCreateLexer(EcCompiler *cp) { EcLexer *lp; ReservedWord *rp; int size; lp = mprAllocObjWithDestructorZeroed(cp, EcLexer, destroyLexer); if (lp == 0) { return 0; } lp->input = mprAllocObjZeroed(lp, EcInput); if (lp->input == 0) { mprFree(lp); return 0; } lp->input->lexer = lp; lp->input->compiler = cp; lp->compiler = cp; size = sizeof(keywords) / sizeof(ReservedWord); lp->keywords = mprCreateHash(lp, size); if (lp->keywords == 0) { mprFree(lp); return 0; } for (rp = keywords; rp->name; rp++) { mprAddHash(lp->keywords, rp->name, rp); } return lp; }
static void openPhp(MaQueue *q) { MaRequest *req; MaResponse *resp; MaConn *conn; conn = q->conn; if (!q->stage->stageData) { if (initializePhp(conn->http) < 0) { maFailRequest(conn, MPR_HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP initialization failed"); } q->stage->stageData = (void*) 1; } resp = conn->response; req = conn->request; switch (req->method) { case MA_REQ_GET: case MA_REQ_HEAD: case MA_REQ_POST: case MA_REQ_PUT: q->queueData = mprAllocObjZeroed(resp, MaPhp); maDontCacheResponse(conn); maSetHeader(conn, 0, "Last-Modified", req->host->currentDate); break; case MA_REQ_DELETE: default: maFailRequest(q->conn, MPR_HTTP_CODE_BAD_METHOD, "Method not supported by file handler: %s", req->methodName); break; } }
int ecOpenConsoleStream(EcLexer *lp, EcStreamGet gets) { EcConsoleStream *cs; cs = mprAllocObjZeroed(lp->input, EcConsoleStream); if (cs == 0) { return MPR_ERR_NO_MEMORY; } /* * TODO - need API for this */ cs->stream.lineNumber = 0; cs->stream.nextChar = 0; cs->stream.end = 0; cs->stream.currentLine = 0; cs->stream.gets = gets; cs->stream.compiler = lp->compiler; /* * TODO - need API for this */ mprFree(lp->input->stream); lp->input->stream = (EcStream*) cs; lp->input->putBack = 0; lp->input->token = 0; lp->input->state = 0; lp->input->next = 0; return 0; }
/* * Post a message to this worker. Note: the worker is the destination worker which may be the parent. * * function postMessage(data: Object, ports: Array = null): Void */ static EjsVar *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv) { EjsVar *data; EjsWorker *target; MprDispatcher *dispatcher; Message *msg; if (worker->state >= EJS_WORKER_CLOSED) { ejsThrowStateError(ejs, "Worker has completed"); return 0; } /* * Create the event with serialized data in the originating interpreter. It owns the data. */ if ((data = ejsSerialize(ejs, argv[0], -1, 0, 0)) == 0) { ejsThrowArgError(ejs, "Can't serialize message data"); return 0; } if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) { ejsThrowMemoryError(ejs); return 0; } target = worker->pair; msg->data = mprStrdup(target->ejs, ejsGetString(data)); msg->worker = target; msg->callback = "onmessage"; msg->callbackSlot = ES_ejs_sys_Worker_onmessage; dispatcher = target->ejs->dispatcher; mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0); mprSignalCond(dispatcher->cond); return 0; }
/* * Create a new virtual host and inherit settings from another host */ MaHost *maCreateVirtualHost(MaServer *server, cchar *ipAddrPort, MaHost *parent) { MaHost *host; host = mprAllocObjZeroed(server, MaHost); if (host == 0) { return 0; } host->parent = parent; host->connections = mprCreateList(host); if (ipAddrPort) { host->ipAddrPort = mprStrdup(server, ipAddrPort); host->name = mprStrdup(server, ipAddrPort); } else { host->ipAddrPort = 0; host->name = 0; } /* * The aliases, dirs and locations are all copy-on-write */ host->aliases = parent->aliases; host->dirs = parent->dirs; host->locations = parent->locations; host->server = parent->server; host->flags = parent->flags; host->httpVersion = parent->httpVersion; host->timeout = parent->timeout; host->limits = parent->limits; host->keepAliveTimeout = parent->keepAliveTimeout; host->maxKeepAlive = parent->maxKeepAlive; host->keepAlive = parent->keepAlive; host->accessLog = parent->accessLog; host->mimeTypes = parent->mimeTypes; host->location = maCreateLocation(host, parent->location); host->logHost = parent->logHost; host->traceMask = parent->traceMask; host->traceLevel = parent->traceLevel; host->traceMaxLength = parent->traceMaxLength; if (parent->traceInclude) { host->traceInclude = mprCopyHash(host, parent->traceInclude); } if (parent->traceExclude) { host->traceExclude = mprCopyHash(host, parent->traceExclude); } maAddLocation(host, host->location); updateCurrentDate(host); #if BLD_FEATURE_MULTITHREAD host->mutex = mprCreateLock(host); #endif return host; }
/* * Dynamic module initialization */ MprModule *maEjsHandlerInit(MaHttp *http, cchar *path) { MprModule *module; MaStage *handler; EjsWebControl *control; module = mprCreateModule(http, "ejsHandler", BLD_VERSION, 0, 0, 0); if (module == 0) { return 0; } handler = maCreateHandler(http, "ejsHandler", MA_STAGE_GET | MA_STAGE_HEAD | MA_STAGE_POST | MA_STAGE_PUT | MA_STAGE_FORM_VARS | MA_STAGE_VIRTUAL); if (handler == 0) { mprFree(module); return 0; } http->ejsHandler = handler; handler->match = matchEjs; handler->run = runEjs; handler->parse = parseEjs; /* * Setup the control block */ handler->stageData = control = mprAllocObjZeroed(handler, EjsWebControl); control->defineParams = defineParams; control->discardOutput = discardOutput; control->error = error; control->getHeader = getHeader; control->getVar = getVar; control->redirect = redirect; control->setCookie = setCookie; control->setHeader = setHeader; control->setHttpCode = setHttpCode; control->setMimeType = setMimeType; control->write = writeBlock; control->modulePath = mprStrdup(control, path); #if BLD_FEATURE_MULTITHREAD && FUTURE /* * This mutex is used very sparingly and must be an application global lock. */ mutex = mprCreateLock(control); control->lock = ejsWebLock; control->unlock = ejsWebUnlock; control->lockData = mutex; #endif if (ejsOpenWebFramework(control, 1) < 0) { return 0; } return module; }
MprXml *mprXmlOpen(MprCtx ctx, int initialSize, int maxSize) { MprXml *xp; xp = mprAllocObjZeroed(ctx, MprXml); xp->inBuf = mprCreateBuf(xp, MPR_XML_BUFSIZE, MPR_XML_BUFSIZE); xp->tokBuf = mprCreateBuf(xp, initialSize, maxSize); return xp; }
/* * Worker thread main procedure */ static void workerMain(EjsWorker *worker, MprWorker *mprWorker) { Ejs *ejs, *inside; EjsWorker *insideWorker; MprDispatcher *dispatcher; Message *msg; mprAssert(!worker->inside); insideWorker = worker->pair; mprAssert(insideWorker->state == EJS_WORKER_BEGIN); ejs = worker->ejs; inside = insideWorker->ejs; insideWorker->state = EJS_WORKER_STARTED; /* * Run the script or file */ if (worker->scriptFile) { loadFile(insideWorker, worker->scriptFile); } else if (worker->scriptLiteral) { if (ejs->service->loadScriptLiteral == 0) { ejsThrowIOError(ejs, "worker: Compiling is not enabled"); return; } (ejs->service->loadScriptLiteral)(inside, worker->scriptLiteral); } /* * Check for exceptions */ if (inside->exception) { handleError(ejs, worker, inside->exception); } if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) { ejsThrowMemoryError(ejs); return; } /* * Post "onclose" finalization message */ msg->worker = worker; msg->callback = "onclose"; msg->callbackSlot = ES_ejs_sys_Worker_onclose; insideWorker->state = EJS_WORKER_CLOSED; worker->state = EJS_WORKER_CLOSED; insideWorker->obj.var.permanent = 0; dispatcher = worker->ejs->dispatcher; mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0); mprSignalCond(dispatcher->cond); }
/* * Create the GC service */ int ejsCreateGCService(Ejs *ejs) { EjsGC *gc; int i; mprAssert(ejs); gc = &ejs->gc; gc->enabled = !(ejs->flags & (EJS_FLAG_EMPTY)); gc->firstGlobal = ES_global_NUM_CLASS_PROP; gc->numPools = EJS_MAX_TYPE; gc->allocGeneration = EJS_GEN_ETERNAL; ejs->workQuota = EJS_GC_WORK_QUOTA; for (i = 0; i < EJS_MAX_GEN; i++) { gc->generations[i] = mprAllocObjZeroed(ejs->heap, EjsGen); } for (i = 0; i < EJS_MAX_TYPE; i++) { gc->pools[i] = mprAllocObjZeroed(ejs->heap, EjsPool); } ejs->currentGeneration = ejs->gc.generations[EJS_GEN_ETERNAL]; return 0; }
MaRange *maCreateRange(MaConn *conn, MprOff start, MprOff end) { MaRange *range; range = mprAllocObjZeroed(conn->request, MaRange); if (range == 0) { return 0; } range->start = start; range->end = end; range->len = end - start; return range; }
/* * Create a new buffer. "maxsize" is the limit to which the buffer can ever grow. -1 means no limit. "initialSize" is * used to define the amount to increase the size of the buffer each time if it becomes full. (Note: mprGrowBuf() will * exponentially increase this number for performance.) */ MprBuf *mprCreateBuf(MprCtx ctx, int initialSize, int maxSize) { MprBuf *bp; if (initialSize <= 0) { initialSize = MPR_DEFAULT_ALLOC; } if ((bp = mprAllocObjZeroed(ctx, MprBuf)) == 0) { return 0; } bp->growBy = MPR_BUFSIZE; mprSetBufSize(bp, initialSize, maxSize); return bp; }
/* * Create a host from scratch */ MaHost *maCreateHost(MaServer *server, cchar *ipAddrPort, MaLocation *location) { MaHost *host; host = mprAllocObjZeroed(server, MaHost); if (host == 0) { return 0; } host->aliases = mprCreateList(host); host->dirs = mprCreateList(host); host->connections = mprCreateList(host); host->locations = mprCreateList(host); if (ipAddrPort) { host->ipAddrPort = mprStrdup(server, ipAddrPort); host->name = mprStrdup(server, ipAddrPort); } else { host->ipAddrPort = 0; host->name = 0; } host->server = server; host->flags = MA_HOST_NO_TRACE; host->httpVersion = MPR_HTTP_1_1; host->timeout = MA_SERVER_TIMEOUT; host->limits = &server->http->limits; host->traceMask = MA_TRACE_REQUEST | MA_TRACE_RESPONSE | MA_TRACE_HEADERS; host->traceLevel = 3; host->traceMaxLength = INT_MAX; host->keepAliveTimeout = MA_KEEP_TIMEOUT; host->maxKeepAlive = MA_MAX_KEEP_ALIVE; host->keepAlive = 1; host->location = (location) ? location : maCreateBareLocation(host); maAddLocation(host, host->location); updateCurrentDate(host); #if BLD_FEATURE_AUTH host->location->auth = maCreateAuth(host->location, host->location->auth); #endif #if BLD_FEATURE_MULTITHREAD host->mutex = mprCreateLock(host); #endif mprSetIdleCallback(host, appwebIsIdle); return host; }
MaUser *maCreateUser(MaAuth *auth, cchar *realm, cchar *user, cchar *password, bool enabled) { MaUser *up; up = mprAllocObjZeroed(auth, MaUser); if (up == 0) { return 0; } up->name = mprStrdup(up, user); up->realm = mprStrdup(up, realm); up->password = mprStrdup(up, password); up->enabled = enabled; return up; }
MaGroup *maCreateGroup(MaAuth *auth, cchar *name, MaAcl acl, bool enabled) { MaGroup *gp; gp = mprAllocObjZeroed(auth, MaGroup); if (gp == 0) { return 0; } gp->acl = acl; gp->name = mprStrdup(gp, name); gp->enabled = enabled; gp->users = mprCreateList(gp); return gp; }
/* * Create a new packet. If size is -1, then also create a default growable buffer -- used for incoming body content. If * size > 0, then create a non-growable buffer of the requested size. */ MaPacket *maCreatePacket(MprCtx ctx, int size) { MaPacket *packet; packet = mprAllocObjZeroed(ctx, MaPacket); if (packet == 0) { return 0; } if (size != 0) { packet->content = mprCreateBuf(packet, size < 0 ? MA_BUFSIZE: size, -1); if (packet->content == 0) { mprFree(packet); return 0; } } return packet; }
MaHostAddress *maCreateHostAddress(MprCtx ctx, cchar *ipAddr, int port) { MaHostAddress *hostAddress; mprAssert(ipAddr && ipAddr); mprAssert(port >= 0); hostAddress = mprAllocObjZeroed(ctx, MaHostAddress); if (hostAddress == 0) { return 0; } hostAddress->flags = 0; hostAddress->ipAddr = mprStrdup(hostAddress, ipAddr); hostAddress->port = port; hostAddress->vhosts = mprCreateList(hostAddress); return hostAddress; }
/* * Create a host from scratch */ MaHost *maCreateHost(MaServer *server, cchar *ipAddrPort, MaLocation *location) { MaHost *host; host = mprAllocObjZeroed(server, MaHost); if (host == 0) { return 0; } host->currentDate = maGetDateString(host, 0); host->aliases = mprCreateList(host); host->dirs = mprCreateList(host); host->connections = mprCreateList(host); host->locations = mprCreateList(host); if (ipAddrPort) { host->ipAddrPort = mprStrdup(server, ipAddrPort); host->name = mprStrdup(server, ipAddrPort); } else { host->ipAddrPort = 0; host->name = 0; } host->server = server; host->flags = MA_HOST_NO_TRACE; host->httpVersion = MPR_HTTP_1_1; host->timeout = MA_SERVER_TIMEOUT; host->limits = &server->http->limits; host->keepAliveTimeout = MA_KEEP_TIMEOUT; host->maxKeepAlive = MA_MAX_KEEP_ALIVE; host->keepAlive = 1; host->location = (location) ? location : maCreateBareLocation(host); maAddLocation(host, host->location); #if BLD_FEATURE_AUTH host->location->auth = maCreateAuth(host->location, host->location->auth); #endif #if BLD_FEATURE_MULTITHREAD host->mutex = mprCreateLock(host); #endif return host; }
/* * Create a new virtual host and inherit settings from another host */ MaHost *maCreateVirtualHost(MaServer *server, cchar *ipAddrPort, MaHost *parent) { MaHost *host; host = mprAllocObjZeroed(server, MaHost); if (host == 0) { return 0; } host->parent = parent; host->currentDate = maGetDateString(host, 0); host->connections = mprCreateList(host); if (ipAddrPort) { host->ipAddrPort = mprStrdup(server, ipAddrPort); host->name = mprStrdup(server, ipAddrPort); } else { host->ipAddrPort = 0; host->name = 0; } /* * The aliases, dirs and locations are all copy-on-write */ host->aliases = parent->aliases; host->dirs = parent->dirs; host->locations = parent->locations; host->server = parent->server; host->flags = parent->flags; host->httpVersion = parent->httpVersion; host->timeout = parent->timeout; host->limits = parent->limits; host->keepAliveTimeout = parent->keepAliveTimeout; host->maxKeepAlive = parent->maxKeepAlive; host->keepAlive = parent->keepAlive; host->accessLog = parent->accessLog; host->location = maCreateLocation(host, parent->location); maAddLocation(host, host->location); #if BLD_FEATURE_MULTITHREAD host->mutex = mprCreateLock(host); #endif return host; }
/* * Createa a new queue for the given stage. If prev is given, then link the new queue after the previous queue. */ MaQueue *maCreateQueue(MaConn *conn, MaStage *stage, int direction, MaQueue *prev) { MaQueue *q; MaResponse *resp; MaLimits *limits; resp = conn->response; limits = &conn->http->limits; q = mprAllocObjZeroed(resp, MaQueue); if (q == 0) { return 0; } maInitQueue(conn->http, q, stage->name); maInitSchedulerQueue(q); q->conn = conn; q->stage = stage; q->close = stage->close; q->open = stage->open; q->start = stage->start; q->direction = direction; q->max = limits->maxStageBuffer; q->packetSize = limits->maxStageBuffer; if (direction == MA_QUEUE_SEND) { q->put = stage->outgoingData; q->service = stage->outgoingService; } else { q->put = stage->incomingData; q->service = stage->incomingService; } if (prev) { maInsertQueue(prev, q); } return q; }
/* * WARNING: the inside interpreter owns the exception object. Must fully extract all fields */ static void handleError(Ejs *ejs, EjsWorker *worker, EjsVar *exception) { EjsError *error; MprDispatcher *dispatcher; Message *msg; mprAssert(!worker->inside); mprAssert(exception); mprAssert(ejs == worker->ejs); if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) { ejsThrowMemoryError(ejs); return; } msg->worker = worker; msg->callback = "onerror"; msg->callbackSlot = ES_ejs_sys_Worker_onerror; /* * Inside interpreter owns the exception object, so must fully extract all exception. * Allocate into the outside worker's interpreter. */ if (ejsIsError(exception)) { error = (EjsError*) exception; msg->message = mprStrdup(ejs, error->message); msg->filename = mprStrdup(ejs, error->filename ? error->filename : "script"); msg->lineNumber = error->lineNumber; msg->stack = mprStrdup(ejs, error->stack); } else if (ejsIsString(exception)) { msg->message = mprStrdup(ejs, ejsGetString(exception)); } else { msg->message = mprStrdup(ejs, ejsGetString(ejsToString(ejs, exception))); } dispatcher = ejs->dispatcher; mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0); mprSignalCond(dispatcher->cond); }
/* * Create a new server. There is typically only one server with one or more (virtual) hosts. */ MaServer *maCreateServer(MaHttp *http, cchar *name, cchar *root, cchar *ipAddr, int port) { MaServer *server; MaHostAddress *hostAddress; MaListen *listen; static int staticModulesLoaded = 0; mprAssert(http); mprAssert(name && *name); server = mprAllocObjZeroed(http, MaServer); if (server == 0) { return 0; } server->hosts = mprCreateList(server); server->listens = mprCreateList(server); server->hostAddresses = mprCreateList(server); server->name = mprStrdup(server, name); server->http = http; maAddServer(http, server); maSetServerRoot(server, root); if (ipAddr && port > 0) { listen = maCreateListen(server, ipAddr, port, 0); maAddListen(server, listen); hostAddress = maCreateHostAddress(server, ipAddr, port); mprAddItem(server->hostAddresses, hostAddress); } maSetDefaultServer(http, server); if (!staticModulesLoaded) { staticModulesLoaded = 1; maLoadStaticModules(http); } return server; }
/* * Dynamic module initialization */ MprModule *maDirHandlerInit(MaHttp *http, cchar *path) { MprModule *module; MaStage *handler; Dir *dir; module = mprCreateModule(http, "dirHandler", BLD_VERSION, NULL, NULL, NULL); if (module == 0) { return 0; } handler = maCreateHandler(http, "dirHandler", MA_STAGE_GET | MA_STAGE_HEAD); if (handler == 0) { mprFree(module); return 0; } handler->match = matchDir; handler->run = runDir; handler->parse = parseDir; handler->stageData = dir = mprAllocObjZeroed(handler, Dir); dir->sortOrder = 1; http->dirHandler = handler; return module; }
/* * Format is: Range: bytes=n1-n2,n3-n4,... * Where n1 is first byte pos and n2 is last byte pos * * Examples: * Range: 0-49 first 50 bytes * Range: 50-99,200-249 Two 50 byte ranges from 50 and 200 * Range: -50 Last 50 bytes * Range: 1- Skip first byte then emit the rest * * Return 1 if more ranges, 0 if end of ranges, -1 if bad range. */ static bool parseRange(MaConn *conn, char *value) { MaRequest *req; MaResponse *resp; MaRange *range, *last, *next; char *tok, *ep; req = conn->request; resp = conn->response; value = mprStrdup(conn, value); if (value == 0) { return 0; } /* * Step over the "bytes=" */ tok = mprStrTok(value, "=", &value); for (last = 0; value && *value; ) { range = mprAllocObjZeroed(req, MaRange); if (range == 0) { return 0; } /* * A range "-7" will set the start to -1 and end to 8 */ tok = mprStrTok(value, ",", &value); if (*tok != '-') { range->start = (int) mprAtoi(tok, 10); } else { range->start = -1; } range->end = -1; if ((ep = strchr(tok, '-')) != 0) { if (*++ep != '\0') { /* * End is one beyond the range. Makes the math easier. */ range->end = (int) mprAtoi(ep, 10) + 1; } } if (range->start >= 0 && range->end >= 0) { range->len = range->end - range->start; } if (last == 0) { req->ranges = range; } else { last->next = range; } last = range; } /* * Validate ranges */ for (range = req->ranges; range; range = range->next) { if (range->end != -1 && range->start >= range->end) { return 0; } if (range->start < 0 && range->end < 0) { return 0; } next = range->next; if (range->start < 0 && next) { /* This range goes to the end, so can't have another range afterwards */ return 0; } if (next) { if (next->start >= 0 && range->end > next->start) { return 0; } } } resp->currentRange = req->ranges; return (last) ? 1: 0; }
/* * Allocate a new (empty) unicode string */ uni *mprAllocUs(MprCtx ctx) { mprAssert(ctx); return mprAllocObjZeroed(ctx, uni); }
/* * Match the request for authorization. This implements basic and digest authentication. */ static bool matchAuth(MaConn *conn, MaStage *stage, cchar *url) { MaRequest *req; MaAuth *auth; AuthData *ad; cchar *requiredPassword; char *msg; int actualAuthType; req = conn->request; auth = req->auth; if (auth == 0) { maFailRequest(conn, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Authorization enabled."); return 1; } if ((ad = mprAllocObjZeroed(req, AuthData)) == 0) { maFailRequest(conn, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Server Error."); return 1; } if (auth->type == 0) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Authorization required.", 0); return 1; } if (req->authDetails == 0) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Missing authorization details.", 0); return 1; } if (mprStrcmpAnyCase(req->authType, "basic") == 0) { decodeBasicAuth(conn, ad); actualAuthType = MA_AUTH_BASIC; #if BLD_FEATURE_AUTH_DIGEST } else if (mprStrcmpAnyCase(req->authType, "digest") == 0) { if (decodeDigestDetails(conn, ad) < 0) { maFailRequest(conn, 400, "Bad authorization header"); return 1; } actualAuthType = MA_AUTH_DIGEST; #endif } else { actualAuthType = MA_AUTH_UNKNOWN; } mprLog(conn, 4, "openAuth: type %d, url %s\nDetails %s\n", auth->type, req->url, req->authDetails); if (ad->userName == 0) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Missing user name.", 0); return 1; } if (auth->type != actualAuthType) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Wrong authentication protocol.", 0); return 1; } /* * Some backend methods can't return the password and will simply do everything in validateUserCredentials. * In this case, they and will return "". That is okay. */ if ((requiredPassword = getPassword(conn, auth->requiredRealm, ad->userName)) == 0) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, authentication error.", "User not defined"); return 1; } #if BLD_FEATURE_AUTH_DIGEST if (auth->type == MA_AUTH_DIGEST) { char *requiredDigest; if (strcmp(ad->qop, auth->qop) != 0) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access Denied, Quality of protection does not match.", 0); return 1; } mprCalcDigest(req, &requiredDigest, 0, requiredPassword, ad->realm, req->url, ad->nonce, ad->qop, ad->nc, ad->cnonce, req->methodName); requiredPassword = requiredDigest; } #endif if (!validateUserCredentials(conn, auth->requiredRealm, ad->userName, ad->password, requiredPassword, &msg)) { formatAuthResponse(conn, auth, MPR_HTTP_CODE_UNAUTHORIZED, "Access denied, authentication error", msg); return 1; } return 0; }