예제 #1
0
파일: ejsCgi.c 프로젝트: jsjohnst/ejscript
/*
 *  Create an initialize the Ejscript Web Framework control block
 */
static int initControlBlock() 
{
    control = mprAllocZeroed(mpr, sizeof(EjsWebControl));
    if (control == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    /*
     *  These are the callbacks from the web framework into the gateway
     */
    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->setVar = setVar;
    control->write = writeBlock;

    if (ejsOpenWebFramework(control, 0) < 0) {
        return EJS_ERR;
    }

    output = mprCreateBuf(mpr, EJS_CGI_MIN_BUF, EJS_CGI_MAX_BUF);
    headerOutput = mprCreateBuf(mpr, MPR_BUFSIZE, -1);
    if (output == 0 || headerOutput == 0) {
        return EJS_ERR;
    }
    return 0;
}
예제 #2
0
파일: mprXml.c 프로젝트: ni-webtech/mpr-4
MprXml *mprXmlOpen(ssize initialSize, ssize maxSize)
{
    MprXml  *xp;

    xp = mprAllocObj(MprXml, manageXml);
    
    xp->inBuf = mprCreateBuf(MPR_XML_BUFSIZE, MPR_XML_BUFSIZE);
    xp->tokBuf = mprCreateBuf(initialSize, maxSize);
    return xp;
}
예제 #3
0
파일: mprXml.c 프로젝트: doghell/mpr-3
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;
}
예제 #4
0
파일: ejsUri.c 프로젝트: monmarzia/ejs-2
/*  
    Expand a template with {word} tokens from the given options objects

    function template(pattern: String, ...options): Uri
 */
static EjsUri *uri_template(Ejs *ejs, EjsUri *up, int argc, EjsObj **argv)
{
    EjsArray    *options;
    EjsObj      *obj, *value;
    MprBuf      *buf;
    cchar       *pattern, *cp, *ep, *str;
    char        *token;
    int         i, len;

    pattern = ejsToMulti(ejs, argv[0]);
    options = (EjsArray*) argv[1];

    buf = mprCreateBuf(-1, -1);
    for (cp = pattern; *cp; cp++) {
        if (*cp == '~' && (cp == pattern || cp[-1] != '\\')) {
            for (i = 0; i < options->length; i++) {
                obj = options->data[i];
                if ((value = ejsGetPropertyByName(ejs, obj, N(NULL, "scriptName"))) != 0 && ejsIsDefined(ejs, value)) {
                    str = ejsToMulti(ejs, value);
                    if (str && *str) {
                        mprPutStringToBuf(buf, str);
                        break;
                    } else {
                        value = 0;
                    }
                }
            }
        } else if (*cp == '{' && (cp == pattern || cp[-1] != '\\')) {
            if ((ep = strchr(++cp, '}')) != 0) {
                len = (int) (ep - cp);
                token = mprMemdup(cp, len + 1);
                token[len] = '\0';
                value = 0;
                for (i = 0; i < options->length; i++) {
                    obj = options->data[i];
                    if ((value = ejsGetPropertyByName(ejs, obj, N(NULL, token))) != 0 && ejsIsDefined(ejs, value)) {
                        str = ejsToMulti(ejs, value);
                        if (str && *str) {
                            mprPutStringToBuf(buf, str);
                            break;
                        } else {
                            value = 0;
                        }
                    }
                }
                if (!ejsIsDefined(ejs, value)) {
                    //  MOB - remove this. Should not be erasing the prior "/"
                    if (cp >= &pattern[2] && cp[-2] == '/') {
                        mprAdjustBufEnd(buf, -1);
                    }
                }
                cp = ep;
            }
        } else {
            mprPutCharToBuf(buf, *cp);
        }
    }
    mprAddNullToBuf(buf);
    return ejsCreateUriFromAsc(ejs, mprGetBufStart(buf));
}
예제 #5
0
/*
    Get a character from the file. This will put the file into buffered mode.
 */
PUBLIC int mprGetFileChar(MprFile *file)
{
    MprBuf      *bp;
    ssize     len;

    assert(file);

    if (file == 0) {
        return MPR_ERR;
    }
    if (file->buf == 0) {
        file->buf = mprCreateBuf(ME_MAX_BUFFER, ME_MAX_BUFFER);
    }
    bp = file->buf;

    if (mprGetBufLength(bp) == 0) {
        len = fillBuf(file);
        if (len <= 0) {
            return -1;
        }
    }
    if (mprGetBufLength(bp) == 0) {
        return 0;
    }
    file->pos++;
    return mprGetCharFromBuf(bp);
}
예제 #6
0
/*
    This replace will replace the given pattern and the next word on the same line with the given replacement.
 */
static char *replace(cchar *str, cchar *pattern, cchar *fmt, ...)
{
    va_list     args;
    MprBuf      *buf;
    cchar       *s, *replacement;
    ssize       plen;

    va_start(args, fmt);
    replacement = sfmtv(fmt, args);
    buf = mprCreateBuf(-1, -1);
    plen = slen(pattern);
    for (s = str; *s; s++) {
        if (*s == *pattern && sncmp(s, pattern, plen) == 0) {
            mprPutStringToBuf(buf, replacement);
            for (s += plen; *s && isspace((uchar) *s) && *s != '\n'; s++) ;
            for (; *s && !isspace((uchar) *s) && *s != '\n' && *s != '>'; s++) ;
         
        }
#if BIT_WIN_LIKE
        if (*s == '\n' && s[-1] != '\r') {
            mprPutCharToBuf(buf, '\r');
        }
#endif
        mprPutCharToBuf(buf, *s);
    }
    va_end(args);
    mprAddNullToBuf(buf);
    return sclone(mprGetBufStart(buf));
}
예제 #7
0
/*
    Peek at a character from the file without disturbing the read position. This will put the file into buffered mode.
 */
PUBLIC int mprPeekFileChar(MprFile *file)
{
    MprBuf      *bp;
    ssize       len;

    assert(file);

    if (file == 0) {
        return MPR_ERR;
    }
    if (file->buf == 0) {
        file->buf = mprCreateBuf(ME_MAX_BUFFER, ME_MAX_BUFFER);
    }
    bp = file->buf;

    if (mprGetBufLength(bp) == 0) {
        len = fillBuf(file);
        if (len <= 0) {
            return -1;
        }
    }
    if (mprGetBufLength(bp) == 0) {
        return 0;
    }
    return ((uchar*) mprGetBufStart(bp))[0];
}
예제 #8
0
파일: cache.c 프로젝트: ni-webtech/http
/*
    See if there is acceptable cached content to serve
 */
static int matchCacheHandler(HttpConn *conn, HttpRoute *route, int dir)
{
    HttpCache   *cache;

    mprAssert(route->caching);

    if ((cache = conn->tx->cache = lookupCacheControl(conn)) == 0) {
        /* Caching not configured for this route */
        return HTTP_ROUTE_REJECT;
    }
    if (cache->flags & HTTP_CACHE_CLIENT) {
        cacheAtClient(conn);
    }
    if (cache->flags & HTTP_CACHE_SERVER) {
        if (!(cache->flags & HTTP_CACHE_MANUAL) && fetchCachedResponse(conn)) {
            /* Found cached content */
            return HTTP_ROUTE_OK;
        }
        /*
            Caching is configured but no acceptable cached content. Create a capture buffer for the cacheFilter.
         */
        conn->tx->cacheBuffer = mprCreateBuf(-1, -1);
    }
    return HTTP_ROUTE_REJECT;
}
예제 #9
0
/*  
    Populate a packet with file data. Return the number of bytes read or a negative error code. Will not return with
    a short read.
 */
static ssize readFileData(HttpQueue *q, HttpPacket *packet, MprOff pos, ssize size)
{
    HttpConn    *conn;
    HttpTx      *tx;
    ssize       nbytes;
//	int btint = 0;
    conn = q->conn;
    tx = conn->tx;

    if (packet->content == 0 && (packet->content = mprCreateBuf(size, -1)) == 0) {
        return MPR_ERR_MEMORY;
    }
    assure(size <= mprGetBufSpace(packet->content));    
    mprLog(7, "readFileData size %d, pos %Ld", size, pos);

    if (pos >= 0) {
        mprSeekFile(tx->file, SEEK_SET, pos);
    }
    if ((nbytes = mprReadFile(tx->file, mprGetBufStart(packet->content), size)) != size) {
        /*  
            As we may have sent some data already to the client, the only thing we can do is abort and hope the client 
            notices the short data.
         */
        httpError(conn, HTTP_CODE_SERVICE_UNAVAILABLE, "Can't read file %s", tx->filename);
        return MPR_ERR_CANT_READ;
    }
    mprAdjustBufEnd(packet->content, nbytes);
    packet->esize -= nbytes;
    assure(packet->esize == 0);
    return nbytes;
}
예제 #10
0
/*
    Read a line from the file. This will put the file into buffered mode.
    Return NULL on eof.
 */
PUBLIC char *mprReadLine(MprFile *file, ssize maxline, ssize *lenp)
{
    MprBuf          *bp;
    MprFileSystem   *fs;
    ssize           size, len, nlen, consumed;
    cchar           *eol, *newline, *start;
    char            *result;

    assert(file);

    if (file == 0) {
        return NULL;
    }
    if (lenp) {
        *lenp = 0;
    }
    if (maxline <= 0) {
        maxline = ME_MAX_BUFFER;
    }
    fs = file->fileSystem;
    newline = fs->newline;
    if (file->buf == 0) {
        file->buf = mprCreateBuf(maxline, maxline);
    }
    bp = file->buf;

    result = NULL;
    size = 0;
    do {
        if (mprGetBufLength(bp) == 0) {
            if (fillBuf(file) <= 0) {
                return result;
            }
        }
        start = mprGetBufStart(bp);
        len = mprGetBufLength(bp);
        if ((eol = findNewline(start, newline, len, &nlen)) != 0) {
            len = eol - start;
            consumed = len + nlen;
        } else {
            consumed = len;
        }
        file->pos += (MprOff) consumed;
        if (lenp) {
            *lenp += len;
        }
        if ((result = mprRealloc(result, size + len + 1)) == 0) {
            return NULL;
        }
        memcpy(&result[size], start, len);
        size += len;
        result[size] = '\0';
        mprAdjustBufStart(bp, consumed);
    } while (!eol);

    return result;
}
예제 #11
0
파일: ejsHttp.c 프로젝트: soffmodd/ejs-2
/*  
    function Http(uri: Uri = null)
 */
static EjsHttp *httpConstructor(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    ejsLoadHttpService(ejs);
    hp->ejs = ejs;

    if ((hp->conn = httpCreateConn(ejs->http, NULL, ejs->dispatcher)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    httpPrepClientConn(hp->conn, 0);
    httpSetConnNotifier(hp->conn, httpEventChange);
    httpSetConnContext(hp->conn, hp);
    if (argc == 1 && ejsIs(ejs, argv[0], Null)) {
        hp->uri = httpUriToString(((EjsUri*) argv[0])->uri, HTTP_COMPLETE_URI);
    }
    hp->method = sclone("GET");
    hp->requestContent = mprCreateBuf(BIT_MAX_BUFFER, -1);
    hp->responseContent = mprCreateBuf(BIT_MAX_BUFFER, -1);
    return hp;
}
예제 #12
0
/*
    Cast the object operand to a primitive type
 */
static EjsObj *xlCast(Ejs *ejs, EjsXML *vp, EjsType *type)
{
    MprBuf      *buf;
    EjsObj      *result;
    EjsXML      *elt, *item;
    int         next;

    if (type == ESV(XML)) {
        return (EjsObj*) vp;
    }
    switch (type->sid) {
    case S_Object:

    case S_Boolean:
        return (EjsObj*) ejsCreateBoolean(ejs, 1);

    case S_Number:
        result = xlCast(ejs, vp, ESV(String));
        result = (EjsObj*) ejsToNumber(ejs, result);
        return result;

    case S_String:
        buf = mprCreateBuf(MPR_BUFSIZE, -1);
        if (mprGetListLength(vp->elements) == 1) {
            elt = mprGetFirstItem(vp->elements);
            if (elt->kind == EJS_XML_ELEMENT) {
                if (elt->elements == 0) {
                    return (EjsObj*) ESV(empty);
                }
                if (elt->elements && mprGetListLength(elt->elements) == 1) {
                    //  TODO - what about PI and comments?
                    item = mprGetFirstItem(elt->elements);
                    if (item->kind == EJS_XML_TEXT) {
                        return (EjsObj*) item->value;
                    }
                }
            }
        }
        for (next = 0; (elt = mprGetNextItem(vp->elements, &next)) != 0; ) {
            if (ejsXMLToBuf(ejs, buf, elt, -1) < 0) {
                return 0;
            }
            if (next < vp->elements->length) {
                mprPutStringToBuf(buf, " ");
            }
        }
        return (EjsObj*) ejsCreateStringFromAsc(ejs, (char*) buf->start);

    default:
        ejsThrowTypeError(ejs, "Cannot cast to this type");
        return 0;
    }
}
예제 #13
0
파일: service.c 프로젝트: DavidQuan/http
PUBLIC char *httpStatsReport(int flags)
{
    MprTime             now;
    MprBuf              *buf;
    HttpStats           s;
    double              elapsed;
    static MprTime      lastTime;
    static HttpStats    last;
    double              mb;

    mb = 1024.0 * 1024;
    now = mprGetTime();
    elapsed = (now - lastTime) / 1000.0;
    httpGetStats(&s);
    buf = mprCreateBuf(0, 0);

    mprPutToBuf(buf, "\nHttp Report: at %s\n\n", mprGetDate("%D %T"));
    if (flags & HTTP_STATS_MEMORY) {
        mprPutToBuf(buf, "Memory       %8.1f MB, %5.1f%% max\n", s.mem / mb, s.mem / (double) s.memMax * 100.0);
        mprPutToBuf(buf, "Heap         %8.1f MB, %5.1f%% mem\n", s.heap / mb, s.heap / (double) s.mem * 100.0);
        mprPutToBuf(buf, "Heap-peak    %8.1f MB\n", s.heapPeak / mb);
        mprPutToBuf(buf, "Heap-used    %8.1f MB, %5.1f%% used\n", s.heapUsed / mb, s.heapUsed / (double) s.heap * 100.0);
        mprPutToBuf(buf, "Heap-free    %8.1f MB, %5.1f%% free\n", s.heapFree / mb, s.heapFree / (double) s.heap * 100.0);

        if (s.memMax == (size_t) -1) {
            mprPutToBuf(buf, "Heap limit          -\n");
            mprPutToBuf(buf, "Heap readline       -\n");
        } else {
            mprPutToBuf(buf, "Heap limit   %8.1f MB\n", s.memMax / mb);
            mprPutToBuf(buf, "Heap redline %8.1f MB\n", s.memRedline / mb);
        }
    }

    mprPutToBuf(buf, "Connections  %8.1f per/sec\n", (s.totalConnections - last.totalConnections) / elapsed);
    mprPutToBuf(buf, "Requests     %8.1f per/sec\n", (s.totalRequests - last.totalRequests) / elapsed);
    mprPutToBuf(buf, "Sweeps       %8.1f per/sec\n", (s.totalSweeps - last.totalSweeps) / elapsed);
    mprPutCharToBuf(buf, '\n');

    mprPutToBuf(buf, "Clients      %8d active\n", s.activeClients);
    mprPutToBuf(buf, "Connections  %8d active\n", s.activeConnections);
    mprPutToBuf(buf, "Processes    %8d active\n", s.activeProcesses);
    mprPutToBuf(buf, "Requests     %8d active\n", s.activeRequests);
    mprPutToBuf(buf, "Sessions     %8d active\n", s.activeSessions);
    mprPutToBuf(buf, "Workers      %8d busy - %d yielded, %d idle, %d max\n", 
        s.workersBusy, s.workersYielded, s.workersIdle, s.workersMax);
    mprPutToBuf(buf, "Sessions     %8.1f MB\n", s.memSessions / mb);
    mprPutCharToBuf(buf, '\n');

    last = s;
    lastTime = now;
    mprAddNullToBuf(buf);
    return sclone(mprGetBufStart(buf));
}
예제 #14
0
파일: ejsZlib.c 프로젝트: monmarzia/ejs-2
/*
    uncompressString(data: String): String
 */
static EjsString *zlib_uncompressString(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsString       *in;
    MprBuf          *out;
    z_stream        zs;
    uchar           outbuf[ZBUFSIZE];
    ssize           nbytes, size;
    int             rc;

    in = (EjsString*) argv[0];
    if ((out = mprCreateBuf(ZBUFSIZE, -1)) == 0) {
        return 0;
    }
    if ((size = in->length) == 0) {
        return ESV(empty);
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    zs.avail_in = 0;
    rc = inflateInit(&zs);
    zs.next_in = (uchar*) in->value;
    zs.avail_in = (int) size;

    do {
        if (zs.avail_in == 0) {
            break;
        }
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = outbuf;
            if ((rc = inflate(&zs, Z_NO_FLUSH)) == Z_NEED_DICT) {
                inflateEnd(&zs);
                return 0;
            } else if (rc == Z_DATA_ERROR || rc == Z_MEM_ERROR) {
                inflateEnd(&zs);
                return 0;
            } else {
                nbytes = ZBUFSIZE - zs.avail_out;
            }
            if (mprPutBlockToBuf(out, (char*) outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to byte array");
                inflateEnd(&zs);
                return 0;
            }
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (rc != Z_STREAM_END);

    deflateEnd(&zs);
    return ejsCreateStringFromBytes(ejs, mprGetBufStart(out), mprGetBufLength(out));
}
예제 #15
0
파일: pam.c 프로젝트: ni-webtech/http
bool httpPamVerifyUser(HttpConn *conn)
{
    MprBuf              *abilities;
    pam_handle_t        *pamh;
    UserInfo            info;
    struct pam_conv     conv = { pamChat, &info };
    struct group        *gp;
    int                 res, i;
   
    mprAssert(conn->username);
    mprAssert(conn->password);
    mprAssert(!conn->encoded);

    info.name = (char*) conn->username;
    info.password = (char*) conn->password;
    pamh = NULL;
    if ((res = pam_start("login", info.name, &conv, &pamh)) != PAM_SUCCESS) {
        return 0;
    }
    if ((res = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK)) != PAM_SUCCESS) {
        pam_end(pamh, PAM_SUCCESS);
        mprLog(5, "httpPamVerifyUser failed to verify %s", conn->username);
        return 0;
    }
    pam_end(pamh, PAM_SUCCESS);
    mprLog(5, "httpPamVerifyUser verified %s", conn->username);

    if (!conn->user) {
        conn->user = mprLookupKey(conn->rx->route->auth->users, conn->username);
    }
    if (!conn->user) {
        Gid     groups[32];
        int     ngroups;
        /* 
            Create a temporary user with a abilities set to the groups 
         */
        ngroups = sizeof(groups) / sizeof(Gid);
        if ((i = getgrouplist(conn->username, 99999, groups, &ngroups)) >= 0) {
            abilities = mprCreateBuf(0, 0);
            for (i = 0; i < ngroups; i++) {
                if ((gp = getgrgid(groups[i])) != 0) {
                    mprPutFmtToBuf(abilities, "%s ", gp->gr_name);
                }
            }
            mprAddNullToBuf(abilities);
            mprLog(5, "Create temp user \"%s\" with abilities: %s", conn->username, mprGetBufStart(abilities));
            conn->user = httpCreateUser(conn->rx->route->auth, conn->username, 0, mprGetBufStart(abilities));
        }
    }
    return 1;
}
예제 #16
0
int mprPuts(MprFile *file, const char *writeBuf, uint count)
{
	MprBuf	*bp;
	char	*buf;
	int		total, bytes, len;

	mprAssert(file);

	/*
	 *	Buffer output and flush when full.
	 */
	if (file->buf == 0) {
		file->buf = mprCreateBuf(file, MPR_BUFSIZE, 0);
		if (file->buf == 0) {
			return MPR_ERR_CANT_ALLOCATE;
		}
	}
	bp = file->buf;

	if (mprGetBufLength(bp) > 0 && mprGetBufSpace(bp) < (int) count) {
		len = mprGetBufLength(bp);
		if (mprWrite(file, mprGetBufStart(bp), len) != len) {
			return MPR_ERR_CANT_WRITE;
		}
		mprFlushBuf(bp);
	}

	total = 0;
	buf = (char*) writeBuf;

	while (count > 0) {
		bytes = mprPutBlockToBuf(bp, buf, count);
		if (bytes <= 0) {
			return MPR_ERR_CANT_ALLOCATE;
		}
		count -= bytes;
		buf += bytes;
		total += bytes;
		mprAddNullToBuf(bp);

		if (count > 0) {
			len = mprGetBufLength(bp);
			if (mprWrite(file, mprGetBufStart(bp), len) != len) {
				return MPR_ERR_CANT_WRITE;
			}
			mprFlushBuf(bp);
		}
	}
	return total;
}
예제 #17
0
/*
    Map options to an attribute string. Remove all internal control specific options and transparently handle URI link options.
    WARNING: this returns a non-cloned reference and relies on no GC yield until the returned value is used or cloned.
    This is done as an optimization to reduce memeory allocations.
 */
static cchar *map(HttpConn *conn, MprHash *options)
{
    Esp         *esp;
    EspReq      *req;
    MprHash     *params;
    MprKey      *kp;
    MprBuf      *buf;
    cchar       *value;
    char        *pstr;

    if (options == 0 || mprGetHashLength(options) == 0) {
        return MPR->emptyString;
    }
    req = conn->data;
    if (httpGetOption(options, EDATA("refresh"), 0) && !httpGetOption(options, "id", 0)) {
        httpAddOption(options, "id", sfmt("id_%d", req->lastDomID++));
    }
    esp = MPR->espService;
    buf = mprCreateBuf(-1, -1);
    for (kp = 0; (kp = mprGetNextKey(options, kp)) != 0; ) {
        if (kp->type != MPR_JSON_OBJ && kp->type != MPR_JSON_ARRAY && !mprLookupKey(esp->internalOptions, kp->key)) {
            mprPutCharToBuf(buf, ' ');
            value = kp->data;
            /*
                Support link template resolution for these options
             */
            if (smatch(kp->key, EDATA("click")) || smatch(kp->key, EDATA("remote")) || smatch(kp->key, EDATA("refresh"))) {
                value = httpUriEx(conn, value, options);
                if ((params = httpGetOptionHash(options, "params")) != 0) {
                    pstr = (char*) "";
                    for (kp = 0; (kp = mprGetNextKey(params, kp)) != 0; ) {
                        pstr = sjoin(pstr, mprUriEncode(kp->key, MPR_ENCODE_URI_COMPONENT), "=", 
                            mprUriEncode(kp->data, MPR_ENCODE_URI_COMPONENT), "&", NULL);
                    }
                    if (pstr[0]) {
                        /* Trim last "&" */
                        pstr[strlen(pstr) - 1] = '\0';
                    }
                    mprPutToBuf(buf, "%s-params='%s", params);
                }
            }
            mprPutStringToBuf(buf, kp->key);
            mprPutStringToBuf(buf, "='");
            mprPutStringToBuf(buf, value);
            mprPutCharToBuf(buf, '\'');
        }
    }
    mprAddNullToBuf(buf);
    return mprGetBufStart(buf);
}
예제 #18
0
파일: string.c 프로젝트: embedthis/mpr
/*
    Expand ${token} references in a path or string.
 */
static char *stemplateInner(cchar *str, void *keys, int json)
{
    MprBuf      *buf;
    cchar       *value;
    char        *src, *result, *cp, *tok;

    if (str) {
        if (schr(str, '$') == 0) {
            return sclone(str);
        }
        buf = mprCreateBuf(0, 0);
        for (src = (char*) str; *src; ) {
            if (*src == '$') {
                if (*++src == '{') {
                    for (cp = ++src; *cp && *cp != '}'; cp++) ;
                    tok = snclone(src, cp - src);
                } else {
                    for (cp = src; *cp && (isalnum((uchar) *cp) || *cp == '_'); cp++) ;
                    tok = snclone(src, cp - src);
                }
                if (json) {
                    value = mprGetJson(keys, tok);
                } else {
                    value = mprLookupKey(keys, tok);
                }
                if (value != 0) {
                    mprPutStringToBuf(buf, value);
                    if (src > str && src[-1] == '{') {
                        src = cp + 1;
                    } else {
                        src = cp;
                    }
                } else {
                    mprPutCharToBuf(buf, '$');
                    if (src > str && src[-1] == '{') {
                        mprPutCharToBuf(buf, '{');
                    }
                    mprPutCharToBuf(buf, *src++);
                }
            } else {
                mprPutCharToBuf(buf, *src++);
            }
        }
        mprAddNullToBuf(buf);
        result = sclone(mprGetBufStart(buf));
    } else {
        result = MPR->emptyString;
    }
    return result;
}
예제 #19
0
파일: ejsArray.c 프로젝트: leemit/ejscript
static EjsString *joinArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsString       *sep, *sp;
    MprBuf          *buf;
    ssize           len;
    int             i, nonString;

    sep = (argc == 1) ? (EjsString*) argv[0] : NULL;
    if (sep == ESV(empty) && ap->length == 1 && ejsIs(ejs, ap->data[0], String)) {
        /* Optimized path for joining [string]. This happens frequently with fun(...args) */
        return (EjsString*) ap->data[0];
    }
    /*
        Get an estimate of the string length
     */
    len = 0;
    nonString = 0;
    for (i = 0; i < ap->length; i++) {
        sp = (EjsString*) ap->data[i];
        if (!ejsIs(ejs, sp, String)) {
            nonString = 1;
            continue;
        }
        len += sp->length;
    }
    if (sep) {
        len += (ap->length * sep->length);
    }
    if (nonString) {
        len += ME_MAX_BUFFER;
    }
    buf = mprCreateBuf(len + 1, -1);

    for (i = 0; i < ap->length; i++) {
        sp = (EjsString*) ap->data[i];
        if (!ejsIsDefined(ejs, sp)) {
            continue;
        }
        sp = ejsToString(ejs, sp);
        if (!ejsIsDefined(ejs, sp)) {
            continue;
        }
        if (i > 0 && sep) {
            mprPutBlockToBuf(buf, sep->value, sep->length);
        }
        mprPutBlockToBuf(buf, sp->value, sp->length);
    }
    mprAddNullToBuf(buf);
    return ejsCreateStringFromBytes(ejs, mprGetBufStart(buf), mprGetBufLength(buf));
}
예제 #20
0
static void setChunkPrefix(MaQueue *q, MaPacket *packet)
{
    if (packet->prefix) {
        return;
    }
    packet->prefix = mprCreateBuf(packet, 32, 32);
    /*
     *  NOTE: prefixes don't count in the queue length. No need to adjust q->count
     */
    if (maGetPacketLength(packet)) {
        mprPutFmtToBuf(packet->prefix, "\r\n%x\r\n", maGetPacketLength(packet));
    } else {
        mprPutStringToBuf(packet->prefix, "\r\n0\r\n\r\n");
    }
}
예제 #21
0
static void setChunkPrefix(MaQueue *q, MaPacket *packet)
{
    MaConn      *conn;

    conn = q->conn;

    if (packet->prefix) {
        return;
    }
    packet->prefix = mprCreateBuf(packet, 32, 32);
    if (packet->count) {
        mprPutFmtToBuf(packet->prefix, "\r\n%x\r\n", packet->count);
    } else {
        mprPutStringToBuf(packet->prefix, "\r\n0\r\n\r\n");
    }
}
예제 #22
0
파일: ejsXML.c 프로젝트: liexusong/ejs-2
/*
    Cast the object operand to a primitive type
 */
static EjsAny *castXml(Ejs *ejs, EjsXML *xml, EjsType *type)
{
    EjsXML      *item;
    EjsObj      *result;
    MprBuf      *buf;

    assert(ejsIsXML(ejs, xml));

    if (type == ESV(XMLList)) {
        return xml;
    }

    switch (type->sid) {
    case S_Object:

    case S_Boolean:
        return ejsCreateBoolean(ejs, 1);

    case S_Number:
        result = castXml(ejs, xml, ESV(String));
        return ejsToNumber(ejs, result);

    case S_String:
        if (xml->kind == EJS_XML_ELEMENT) {
            if (xml->elements == 0) {
                return ESV(empty);
            }
            if (xml->elements && mprGetListLength(xml->elements) == 1) {
                //  TODO - what about PI and comments?
                item = mprGetFirstItem(xml->elements);
                if (item->kind == EJS_XML_TEXT) {
                    return item->value;
                }
            }
        }
        buf = mprCreateBuf(BIT_MAX_BUFFER, -1);
        if (ejsXMLToBuf(ejs, buf, xml, -1) < 0) {
            return 0;
        }
        return ejsCreateStringFromAsc(ejs, (char*) buf->start);

    default:
        ejsThrowTypeError(ejs, "Cannot cast to this type");
        return 0;
    }
    return 0;
}
예제 #23
0
파일: string.c 프로젝트: embedthis/mpr
PUBLIC cchar *sjoinArgs(int argc, cchar **argv, cchar *sep)
{
    MprBuf  *buf;
    int     i;

    if (sep == 0) {
        sep = "";
    }
    buf = mprCreateBuf(0, 0);
    for (i = 0; i < argc; i++) {
        mprPutToBuf(buf, "%s%s", argv[i], sep);
    }
    if (argc > 0) {
        mprAdjustBufEnd(buf, -1);
    }
    return mprBufToString(buf);
}
예제 #24
0
파일: queue.c 프로젝트: gamman/appweb-3
/*
 *  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;
}
예제 #25
0
/*
    Put a string to the file. This will put the file into buffered mode.
 */
PUBLIC ssize mprPutFileString(MprFile *file, cchar *str)
{
    MprBuf  *bp;
    ssize   total, bytes, count;
    char    *buf;

    assert(file);
    count = slen(str);

    /*
        Buffer output and flush when full.
     */
    if (file->buf == 0) {
        file->buf = mprCreateBuf(ME_MAX_BUFFER, 0);
        if (file->buf == 0) {
            return MPR_ERR_CANT_ALLOCATE;
        }
    }
    bp = file->buf;

    if (mprGetBufLength(bp) > 0 && mprGetBufSpace(bp) < count) {
        mprFlushFile(file);
    }
    total = 0;
    buf = (char*) str;

    while (count > 0) {
        bytes = mprPutBlockToBuf(bp, buf, count);
        if (bytes < 0) {
            return MPR_ERR_CANT_ALLOCATE;

        } else if (bytes == 0) {
            if (mprFlushFile(file) < 0) {
                return MPR_ERR_CANT_WRITE;
            }
            continue;
        }
        count -= bytes;
        buf += bytes;
        total += bytes;
        file->pos += (MprOff) bytes;
    }
    return total;
}
예제 #26
0
파일: service.c 프로젝트: DavidQuan/http
PUBLIC int httpApplyUserGroup() 
{
#if ME_UNIX_LIKE
    Http    *http;

    http = HTTP;
    if (http->userChanged || http->groupChanged) {
        if (!smatch(MPR->logPath, "stdout") && !smatch(MPR->logPath, "stderr")) {
            if (chown(MPR->logPath, http->uid, http->gid) < 0) {
                mprLog("critical http", 0, "Cannot change ownership on %s", MPR->logPath);
            }
        }
    }
    if (httpApplyChangedGroup() < 0 || httpApplyChangedUser() < 0) {
        return MPR_ERR_CANT_COMPLETE;
    }
    if (http->userChanged || http->groupChanged) {
        struct group    *gp;
        gid_t           glist[64], gid;
        MprBuf          *gbuf = mprCreateBuf(0, 0);
        cchar           *groups;
        int             i, ngroup;

        gid = getgid();
        ngroup = getgroups(sizeof(glist) / sizeof(gid_t), glist);
        if (ngroup > 1) {
            mprPutStringToBuf(gbuf, ", groups: ");
            for (i = 0; i < ngroup; i++) {
                if (glist[i] == gid) continue;
                if ((gp = getgrgid(glist[i])) != 0) {
                    mprPutToBuf(gbuf, "%s (%d) ", gp->gr_name, glist[i]);
                } else {
                    mprPutToBuf(gbuf, "(%d) ", glist[i]);
                }
            }
        }
        groups = mprGetBufStart(gbuf);
        mprLog("info http", 2, "Running as user \"%s\" (%d), group \"%s\" (%d)%s", http->user, http->uid, 
            http->group, http->gid, groups);
    }
#endif
    return 0;
}
예제 #27
0
static int toStringMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
{
	MprBuf	*bp;
	int		saveMaxDepth, saveDepth, saveFlags;

	saveMaxDepth = ep->maxDepth;

	if (argc >= 1) {
		ep->maxDepth = ejsVarToInteger(argv[0]);
	} else if (ep->maxDepth == 0) {
		ep->maxDepth = MAXINT;
	}

	saveFlags = ep->flags;
	if (argc >= 2) {
		if (ejsVarToBoolean(argv[1])) {
			ep->flags |= EJS_FLAGS_ENUM_HIDDEN;
		}
	}
	if (argc == 3) {
		if (ejsVarToBoolean(argv[2])) {
			ep->flags |= EJS_FLAGS_ENUM_BASE;
		}
	}

	bp = mprCreateBuf(ep, 0, 0);

	saveDepth = ep->depth;

	formatVar(ep, bp, thisObj);

	ep->depth = saveDepth;
	ep->maxDepth = saveMaxDepth;

	mprAddNullToBuf(bp);

	ejsWriteVarAsString(ep, ep->result, mprGetBufStart(bp));
	mprFree(bp);

	ep->flags = saveFlags;

	return 0;
}
예제 #28
0
/*
    Get the SSL state of the socket in a buffer
 */
static char *getOssState(MprSocket *sp)
{
    OpenSocket      *osp;
    MprBuf          *buf;
    X509            *cert;
    char            subject[512], issuer[512];

    osp = sp->sslSocket;
    buf = mprCreateBuf(0, 0);

    mprPutToBuf(buf, "{\"provider\":\"openssl\",\"cipher\":\"%s\",\"session\":\"%s\",",
        SSL_get_cipher(osp->handle), sp->session);
    mprPutToBuf(buf, "\"peer\":\"%s\",", sp->peerName);
    mprPutToBuf(buf, "\"%s\":{", sp->acceptIp ? "client" : "server");

    if ((cert = SSL_get_peer_certificate(osp->handle)) != 0) {
        X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) -1);
        mprPutToBuf(buf, "\"issuer\": {");
        parseCertFields(buf, &issuer[1]);
        mprPutToBuf(buf, "},");

        X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) -1);
        mprPutToBuf(buf, "\"subject\": {");
        parseCertFields(buf, &subject[1]);
        mprPutToBuf(buf, "},");
        X509_free(cert);
    }
    if ((cert = SSL_get_certificate(osp->handle)) != 0) {
        mprPutToBuf(buf, "\"issuer\": {");
        X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) -1);
        parseCertFields(buf, &issuer[1]);
        mprPutToBuf(buf, "},");

        mprPutToBuf(buf, "\"subject\": {");
        X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) -1);
        parseCertFields(buf, &subject[1]);
        mprPutToBuf(buf, "},");
        /* Don't call X509_free on own cert */
    }
    mprAdjustBufEnd(buf, -1);
    mprPutToBuf(buf, "}}");
    return mprBufToString(buf);
}
예제 #29
0
파일: ejsZlib.c 프로젝트: monmarzia/ejs-2
/*
    compressString(data: String): String
 */
static EjsString *zlib_compressString(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsString       *in;
    MprBuf          *out;
    z_stream        zs;
    uchar           outbuf[ZBUFSIZE];
    ssize           size, nbytes;
    int             level, flush;

    in = (EjsString*) argv[0];
    if ((size = in->length) == 0) {
        return ESV(empty);
    }
    if ((out = mprCreateBuf(in->length, 0)) == 0) {
        return 0;
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    level = Z_DEFAULT_COMPRESSION;
    deflateInit(&zs, level);
    zs.next_in = (uchar*) in->value;
    zs.avail_in = (int) size;
    do {
        flush = (zs.avail_in == 0) ? Z_FINISH : Z_NO_FLUSH;
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = outbuf;
            deflate(&zs, flush);
            nbytes = ZBUFSIZE - zs.avail_out;
            if (mprPutBlockToBuf(out, (char*) outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to output buffer");
                deflateEnd(&zs);
                return 0;
            }
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (flush != Z_FINISH);

    deflateEnd(&zs);
    return ejsCreateStringFromBytes(ejs, mprGetBufStart(out), mprGetBufLength(out));
}
예제 #30
0
static char *hashToString(MprHash *hash, cchar *sep)
{
    MprBuf  *buf;
    cchar   *data;
    char    key[8];
    int     i, len;

    len = mprGetHashLength(hash);
    buf = mprCreateBuf(0, 0);
    mprPutCharToBuf(buf, '{');
    for (i = 0; i < len; ) {
        data = mprLookupKey(hash, itosbuf(key, sizeof(key), i, 10));
        mprPutStringToBuf(buf, data);
        if (++i < len) {
            mprPutStringToBuf(buf, sep ? sep : ",");
        }
    }
    mprPutCharToBuf(buf, '}');
    mprAddNullToBuf(buf);
    return mprGetBufStart(buf);
}