Exemple #1
0
/*
    Parse the cert info and write properties to the buffer. Modifies the info argument.
 */
static void parseCertFields(MprBuf *buf, char *info)
{
    char    c, *cp, *term, *key, *value;

    if (info) {
        key = 0;
        term = cp = info;
        do {
            c = *cp;
            if (c == '/' || c == '\0') {
                *cp = '\0';
                key = ssplit(term, "=", &value);
                if (smatch(key, "emailAddress")) {
                    key = "email";
                }
                mprPutToBuf(buf, "\"%s\":\"%s\",", key, value);
                term = &cp[1];
                *cp = c;
            }
        } while (*cp++ != '\0');
        if (key) {
            mprAdjustBufEnd(buf, -1);
        }
    }
}
Exemple #2
0
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;
}
Exemple #3
0
/*
    Create a final range packet that follows all the data
 */
static HttpPacket *createFinalRangePacket(HttpStream *stream)
{
    HttpPacket  *packet;
    HttpTx      *tx;

    tx = stream->tx;

    packet = httpCreatePacket(HTTP_RANGE_BUFSIZE);
    packet->flags |= HTTP_PACKET_RANGE | HTTP_PACKET_DATA;
    mprPutToBuf(packet->content, "\r\n--%s--\r\n", tx->rangeBoundary);
    return packet;
}
Exemple #4
0
/*
    Get the SSL state of the socket in a buffer
 */
static char *getOssState(MprSocket *sp)
{
    OpenSocket      *osp;
    MprBuf          *buf;
    X509_NAME       *xSubject;
    X509            *cert;
    char            *prefix, subject[512], issuer[512], peer[512];

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

    mprPutToBuf(buf, "PROVIDER=openssl,CIPHER=%s,SESSION=%s,", SSL_get_cipher(osp->handle), sp->session);

    if ((cert = SSL_get_peer_certificate(osp->handle)) == 0) {
        mprPutToBuf(buf, "%s=\"none\",", sp->acceptIp ? "CLIENT_CERT" : "SERVER_CERT");

    } else {
        xSubject = X509_get_subject_name(cert);
        X509_NAME_get_text_by_NID(xSubject, NID_commonName, peer, sizeof(peer) - 1);
        mprPutToBuf(buf, "PEER=\"%s\",", peer);

        prefix = sp->acceptIp ? "CLIENT_" : "SERVER_";
        X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) -1);
        parseCertFields(buf, prefix, "S_", &subject[1]);

        X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) -1);
        parseCertFields(buf, prefix, "I_", &issuer[1]);
        X509_free(cert);
    }
    if ((cert = SSL_get_certificate(osp->handle)) != 0) {
        prefix =  sp->acceptIp ? "SERVER_" : "CLIENT_";
        X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) -1);
        parseCertFields(buf, prefix, "S_", &subject[1]);

        X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) -1);
        parseCertFields(buf, prefix, "I_", &issuer[1]);
        /* Don't call X509_free on own cert */
    }
    return mprGetBufStart(buf);
}
Exemple #5
0
/*
    Map iana names to OpenSSL names so users can provide IANA names as well as OpenSSL cipher names
 */
static cchar *mapCipherNames(cchar *ciphers)
{
    MprBuf      *buf;
    CipherMap   *cp;
    char        *cipher, *next;

    if (!ciphers || *ciphers == 0) {
        return 0;
    }
    buf = mprCreateBuf(0, 0);
    for (next = sclone(ciphers); (cipher = stok(next, ":, \t", &next)) != 0; ) {
        for (cp = cipherMap; cp->name; cp++) {
            if (smatch(cp->name, cipher)) {
                mprPutToBuf(buf, "%s:", cp->ossName);
                break;
            }
        }
        if (cp->name == 0) {
            mprPutToBuf(buf, "%s:", cipher);
        }
    }
    return mprBufToString(buf);
}
Exemple #6
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);
}
Exemple #7
0
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);
}
Exemple #8
0
/*
    Create a range boundary packet
 */
static HttpPacket *createRangePacket(HttpStream *stream, HttpRange *range)
{
    HttpPacket  *packet;
    HttpTx      *tx;
    char        *length;

    tx = stream->tx;

    length = (tx->entityLength >= 0) ? itos(tx->entityLength) : "*";
    packet = httpCreatePacket(HTTP_RANGE_BUFSIZE);
    packet->flags |= HTTP_PACKET_RANGE | HTTP_PACKET_DATA;
    mprPutToBuf(packet->content,
        "\r\n--%s\r\n"
        "Content-Range: bytes %lld-%lld/%s\r\n\r\n",
        tx->rangeBoundary, range->start, range->end - 1, length);
    return packet;
}
Exemple #9
0
/*  
    Prepare form data as a series of key-value pairs. Data is formatted according to www-url-encoded specs by 
    mprSetHttpFormData. Objects are flattened into a one level key/value pairs. Keys can have embedded "." separators.
    E.g.  name=value&address=77%20Park%20Lane
 */
static void prepForm(Ejs *ejs, EjsHttp *hp, cchar *prefix, EjsObj *data)
{
    EjsName     qname;
    EjsObj      *vp;
    EjsString   *value;
    cchar       *key, *sep, *vstr;
    char        *encodedKey, *encodedValue, *newPrefix, *newKey;
    int         i, count;

    count = ejsGetLength(ejs, data);
    for (i = 0; i < count; i++) {
        if (ejsIs(ejs, data, Array)) {
            key = itos(i);
        } else {
            qname = ejsGetPropertyName(ejs, data, i);
            key = ejsToMulti(ejs, qname.name);
        }
        vp = ejsGetProperty(ejs, data, i);
        if (vp == 0) {
            continue;
        }
        if (ejsGetLength(ejs, vp) > 0) {
            if (prefix) {
                newPrefix = sfmt("%s.%s", prefix, key);
                prepForm(ejs, hp, newPrefix, vp);
            } else {
                prepForm(ejs, hp, key, vp);
            }
        } else {
            value = ejsToString(ejs, vp);
            sep = (mprGetBufLength(hp->requestContent) > 0) ? "&" : "";
            if (prefix) {
                newKey = sjoin(prefix, ".", key, NULL);
                encodedKey = mprUriEncode(newKey, MPR_ENCODE_URI_COMPONENT); 
            } else {
                encodedKey = mprUriEncode(key, MPR_ENCODE_URI_COMPONENT);
            }
            vstr = ejsToMulti(ejs, value);
            encodedValue = mprUriEncode(vstr, MPR_ENCODE_URI_COMPONENT);
            mprPutToBuf(hp->requestContent, "%s%s=%s", sep, encodedKey, encodedValue);
        }
    }
}
Exemple #10
0
/*  
    Prepare form data using json encoding. The objects are json encoded then URI encoded to be safe. 
 */
static void prepForm(Ejs *ejs, EjsHttp *hp, char *prefix, EjsObj *data)
{
    EjsName     qname;
    EjsObj      *vp;
    EjsString   *value;
    cchar       *key, *sep;
    char        *encodedKey, *encodedValue, *newPrefix, *newKey;
    int         i, count;

    jdata = ejsToJSON(ejs, data, NULL);
    if (prefix) {
        newKey = sjoin(prefix, ".", key, NULL);
        encodedKey = mprUriEncode(newKey, MPR_ENCODE_URI_COMPONENT); 
    } else {
        encodedKey = mprUriEncode(key, MPR_ENCODE_URI_COMPONENT);
    }
    encodedValue = mprUriEncode(value->value, MPR_ENCODE_URI_COMPONENT);
    mprPutToBuf(hp->requestContent, "%s%s=%s", sep, encodedKey, encodedValue);
}
Exemple #11
0
/*
    Parse the cert info and write properties to the buffer. Modifies the info argument.
 */
static void parseCertFields(MprBuf *buf, char *prefix, char *prefix2, char *info)
{
    char    c, *cp, *term, *key, *value;

    if (info) {
        term = cp = info;
        do {
            c = *cp;
            if (c == '/' || c == '\0') {
                *cp = '\0';
                key = ssplit(term, "=", &value);
                if (smatch(key, "emailAddress")) {
                    key = "EMAIL";
                }
                mprPutToBuf(buf, "%s%s%s=%s,", prefix, prefix2, key, value);
                term = &cp[1];
                *cp = c;
            }
        } while (*cp++ != '\0');
    }
}
Exemple #12
0
static char *getOssSession(MprSocket *sp)
{
    SSL_SESSION     *sess;
    OpenSocket      *osp;
    MprBuf          *buf;
    int             i;

    osp = sp->sslSocket;

    if ((sess = SSL_get0_session(osp->handle)) != 0) {
        if (sess->session_id_length == 0 && osp->handle->tlsext_ticket_expected) {
            return sclone("ticket");
        }
        buf = mprCreateBuf((sess->session_id_length * 2) + 1, 0);
        assert(buf->start);
        for (i = 0; i < (int) sess->session_id_length; i++) {
            mprPutToBuf(buf, "%02X", (uchar) sess->session_id[i]);
        }
        return mprBufToString(buf);
    }
    return 0;
}
Exemple #13
0
static EjsString *serialize(Ejs *ejs, EjsAny *vp, Json *json)
{
    EjsName     qname;
    EjsFunction *fn;
    EjsString   *result, *sv;
    EjsTrait    *trait;
    EjsObj      *pp, *obj, *replacerArgs[2];
    wchar       *cp;
    cchar       *key;
    int         c, isArray, i, count, slotNum, quotes;

    /*
        The main code below can handle Arrays, Objects, objects derrived from Object and also native classes with properties.
        All others just use toString.
     */
    count = ejsIsPot(ejs, vp) ? ejsGetLength(ejs, vp) : 0;
    if (count == 0 && TYPE(vp) != ESV(Object) && TYPE(vp) != ESV(Array)) {
        //  OPT - need some flag for this test.
        if (!ejsIsDefined(ejs, vp) || ejsIs(ejs, vp, Boolean) || ejsIs(ejs, vp, Number)) {
            return ejsToString(ejs, vp);
        } else if (json->regexp) {
            return ejsToString(ejs, vp);
        } else {
            return ejsToLiteralString(ejs, vp);
        }
    }
    obj = vp;
    json->nest++;
    if (json->buf == 0) {
        json->buf = mprCreateBuf(0, 0);
        mprAddRoot(json->buf);
    }
    isArray = ejsIs(ejs, vp, Array);
    mprPutCharToWideBuf(json->buf, isArray ? '[' : '{');
    if (json->pretty) {
        mprPutCharToWideBuf(json->buf, '\n');
    }
    if (++ejs->serializeDepth <= json->depth && !VISITED(obj)) {
        SET_VISITED(obj, 1);
        for (slotNum = 0; slotNum < count && !ejs->exception; slotNum++) {
            trait = ejsGetPropertyTraits(ejs, obj, slotNum);
            if (trait && (trait->attributes & (EJS_TRAIT_HIDDEN | EJS_TRAIT_DELETED | EJS_FUN_INITIALIZER | 
                    EJS_FUN_MODULE_INITIALIZER)) && !json->hidden) {
                continue;
            }
            pp = ejsGetProperty(ejs, obj, slotNum);
            if (ejs->exception) {
                SET_VISITED(obj, 0);
                json->nest--;
                return 0;
            }
            if (pp == 0) {
                continue;
            }
            if (isArray) {
                key = itos(slotNum);
                qname.name = ejsCreateStringFromAsc(ejs, key);
                qname.space = ESV(empty);
            } else {
                qname = ejsGetPropertyName(ejs, vp, slotNum);
            }

            quotes = json->quotes;
            if (!quotes) {
                //  UNICODE
                for (cp = qname.name->value; cp < &qname.name->value[qname.name->length]; cp++) {
                    if (!isalnum((uchar) *cp) && *cp != '_') {
                        quotes = 1;
                        break;
                    }
                }
            }
            if (json->pretty) {
                for (i = 0; i < ejs->serializeDepth; i++) {
                    mprPutStringToWideBuf(json->buf, json->indent);
                }
            }
            if (!isArray) {
                if (json->namespaces) {
                    if (qname.space != ESV(empty)) {
                        mprPutToBuf(json->buf, "\"%@\"::", qname.space);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                for (cp = qname.name->value; cp && *cp; cp++) {
                    c = *cp;
                    if (c == '"' || c == '\\') {
                        mprPutCharToWideBuf(json->buf, '\\');
                        mprPutCharToWideBuf(json->buf, c);
                    } else {
                        mprPutCharToWideBuf(json->buf, c);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                mprPutCharToWideBuf(json->buf, ':');
                if (json->pretty) {
                    mprPutCharToWideBuf(json->buf, ' ');
                }
            }
            fn = (EjsFunction*) ejsGetPropertyByName(ejs, TYPE(pp)->prototype, N(NULL, "toJSON"));
            // OPT - check that this is going directly to serialize most of the time
            if (!ejsIsFunction(ejs, fn) || (fn->isNativeProc && fn->body.proc == (EjsProc) ejsObjToJSON)) {
                sv = serialize(ejs, pp, json);
            } else {
                sv = (EjsString*) ejsRunFunction(ejs, fn, pp, 1, &json->options);
            }
            if (sv == 0 || !ejsIs(ejs, sv, String)) {
                if (ejs->exception) {
                    ejsThrowTypeError(ejs, "Cannot serialize property %@", qname.name);
                    SET_VISITED(obj, 0);
                    return 0;
                }
            } else {
                if (json->replacer) {
                    replacerArgs[0] = (EjsObj*) qname.name; 
                    replacerArgs[1] = (EjsObj*) sv; 

                    /* function replacer(key: String, value: String): String */
                    sv = ejsRunFunction(ejs, json->replacer, obj, 2, (EjsObj**) replacerArgs);
                }
                mprPutBlockToBuf(json->buf, sv->value, sv->length * sizeof(wchar));
            }
            if ((slotNum + 1) < count || json->commas) {
                mprPutCharToWideBuf(json->buf, ',');
            }
            if (json->pretty) {
                mprPutCharToWideBuf(json->buf, '\n');
            }
        }
        SET_VISITED(obj, 0);
    }
    --ejs->serializeDepth; 
    if (json->pretty) {
        for (i = ejs->serializeDepth; i > 0; i--) {
            mprPutStringToWideBuf(json->buf, json->indent);
        }
    }
    mprPutCharToWideBuf(json->buf, isArray ? ']' : '}');
    mprAddNullToWideBuf(json->buf);

    if (--json->nest == 0) {
        result = ejsCreateString(ejs, mprGetBufStart(json->buf), mprGetBufLength(json->buf) / sizeof(wchar));
        mprRemoveRoot(json->buf);
    } else {
        result = 0;
    }
    return result;
}
Exemple #14
0
PUBLIC void httpWriteHeaders(HttpQueue *q, HttpPacket *packet)
{
    Http        *http;
    HttpConn    *conn;
    HttpTx      *tx;
    HttpUri     *parsedUri;
    MprKey      *kp;
    MprBuf      *buf;
    int         level;

    assert(packet->flags == HTTP_PACKET_HEADER);

    conn = q->conn;
    http = conn->http;
    tx = conn->tx;
    buf = packet->content;

    if (tx->flags & HTTP_TX_HEADERS_CREATED) {
        return;
    }
    tx->flags |= HTTP_TX_HEADERS_CREATED;
    tx->responded = 1;
    if (conn->headersCallback) {
        /* Must be before headers below */
        (conn->headersCallback)(conn->headersCallbackArg);
    }
    if (tx->flags & HTTP_TX_USE_OWN_HEADERS && !conn->error) {
        conn->keepAliveCount = 0;
        return;
    }
    setHeaders(conn, packet);

    if (conn->endpoint) {
        mprPutStringToBuf(buf, conn->protocol);
        mprPutCharToBuf(buf, ' ');
        mprPutIntToBuf(buf, tx->status);
        mprPutCharToBuf(buf, ' ');
        mprPutStringToBuf(buf, httpLookupStatus(http, tx->status));
    } else {
        mprPutStringToBuf(buf, tx->method);
        mprPutCharToBuf(buf, ' ');
        parsedUri = tx->parsedUri;
        if (http->proxyHost && *http->proxyHost) {
            if (parsedUri->query && *parsedUri->query) {
                mprPutToBuf(buf, "http://%s:%d%s?%s %s", http->proxyHost, http->proxyPort, 
                    parsedUri->path, parsedUri->query, conn->protocol);
            } else {
                mprPutToBuf(buf, "http://%s:%d%s %s", http->proxyHost, http->proxyPort, parsedUri->path,
                    conn->protocol);
            }
        } else {
            if (parsedUri->query && *parsedUri->query) {
                mprPutToBuf(buf, "%s?%s %s", parsedUri->path, parsedUri->query, conn->protocol);
            } else {
                mprPutStringToBuf(buf, parsedUri->path);
                mprPutCharToBuf(buf, ' ');
                mprPutStringToBuf(buf, conn->protocol);
            }
        }
    }
    if ((level = httpShouldTrace(conn, HTTP_TRACE_TX, HTTP_TRACE_FIRST, tx->ext)) >= mprGetLogLevel(tx)) {
        mprAddNullToBuf(buf);
        mprLog(level, "  %s", mprGetBufStart(buf));
    }
    mprPutStringToBuf(buf, "\r\n");

    /* 
        Output headers
     */
    kp = mprGetFirstKey(conn->tx->headers);
    while (kp) {
        mprPutStringToBuf(packet->content, kp->key);
        mprPutStringToBuf(packet->content, ": ");
        if (kp->data) {
            mprPutStringToBuf(packet->content, kp->data);
        }
        mprPutStringToBuf(packet->content, "\r\n");
        kp = mprGetNextKey(conn->tx->headers, kp);
    }
    /* 
        By omitting the "\r\n" delimiter after the headers, chunks can emit "\r\nSize\r\n" as a single chunk delimiter
     */
    if (tx->length >= 0 || tx->chunkSize <= 0) {
        mprPutStringToBuf(buf, "\r\n");
    }
    if (tx->altBody) {
        /* Error responses are emitted here */
        mprPutStringToBuf(buf, tx->altBody);
        httpDiscardQueueData(tx->queue[HTTP_QUEUE_TX]->nextQ, 0);
    }
    tx->headerSize = mprGetBufLength(buf);
    tx->flags |= HTTP_TX_HEADERS_CREATED;
    q->count += httpGetPacketLength(packet);
}
Exemple #15
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);
}
Exemple #16
0
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));
}
Exemple #17
0
/*
    Process the content data.
    Returns < 0 on error
            == 0 when more data is needed
            == 1 when data successfully written
 */
static int processUploadData(HttpQueue *q)
{
    HttpConn        *conn;
    HttpPacket      *packet;
    MprBuf          *content;
    Upload          *up;
    ssize           size, dataLen;
    bool            pureData;
    char            *data, *bp, *key;

    conn = q->conn;
    up = q->queueData;
    content = q->first->content;
    packet = 0;

    size = mprGetBufLength(content);
    if (size < up->boundaryLen) {
        /*  Incomplete boundary. Return and get more data */
        return 0;
    }
    bp = getBoundary(mprGetBufStart(content), size, up->boundary, up->boundaryLen, &pureData);
    if (bp == 0) {
        if (up->clientFilename) {
            /*
                No signature found yet. probably more data to come. Must handle split boundaries.
             */
            data = mprGetBufStart(content);
            dataLen = pureData ? size : (size - (up->boundaryLen - 1));
            if (dataLen > 0) {
                if (writeToFile(q, mprGetBufStart(content), dataLen) < 0) {
                    return MPR_ERR_CANT_WRITE;
                }
            }
            mprAdjustBufStart(content, dataLen);
            return 0;       /* Get more data */
        }
    }
    data = mprGetBufStart(content);
    dataLen = (bp) ? (bp - data) : mprGetBufLength(content);

    if (dataLen > 0) {
        mprAdjustBufStart(content, dataLen);
        /*
            This is the CRLF before the boundary
         */
        if (dataLen >= 2 && data[dataLen - 2] == '\r' && data[dataLen - 1] == '\n') {
            dataLen -= 2;
        }
        if (up->clientFilename) {
            /*
                Write the last bit of file data and add to the list of files and define environment variables
             */
            if (writeToFile(q, data, dataLen) < 0) {
                return MPR_ERR_CANT_WRITE;
            }
            defineFileFields(q, up);

        } else {
            /*
                Normal string form data variables
             */
            data[dataLen] = '\0';
#if KEEP
            httpTrace(conn, "request.upload.variables", "context", "'%s':'%s'", up->name, data);
#endif
            key = mprUriDecode(up->name);
            data = mprUriDecode(data);
            httpSetParam(conn, key, data);

            if (packet == 0) {
                packet = httpCreatePacket(ME_MAX_BUFFER);
            }
            if (httpGetPacketLength(packet) > 0) {
                /*
                    Need to add www-form-urlencoding separators
                 */
                mprPutCharToBuf(packet->content, '&');
            } else {
                conn->rx->mimeType = sclone("application/x-www-form-urlencoded");

            }
            mprPutToBuf(packet->content, "%s=%s", up->name, data);
        }
    }
    if (up->clientFilename) {
        /*
            Now have all the data (we've seen the boundary)
         */
        mprCloseFile(up->file);
        up->file = 0;
        up->clientFilename = 0;
    }
    if (packet) {
        httpPutPacketToNext(q, packet);
    }
    up->contentState = HTTP_UPLOAD_BOUNDARY;
    return 0;
}
Exemple #18
0
PUBLIC void maLogRequest(HttpConn *conn)
{
    HttpHost    *host;
    HttpRx      *rx;
    HttpTx      *tx;
    HttpRoute   *route;
    MprBuf      *buf;
    char        keyBuf[80], *timeText, *fmt, *cp, *qualifier, *value, c;
    int         len;

    rx = conn->rx;
    tx = conn->tx;
    route = rx->route;
    host = httpGetConnContext(conn);
    if (host == 0) {
        return;
    }
    fmt = route->logFormat;
    if (fmt == 0) {
        return;
    }
    if (rx->method == 0) {
        return;
    }
    len = BIT_MAX_URI + 256;
    buf = mprCreateBuf(len, len);

    while ((c = *fmt++) != '\0') {
        if (c != '%' || (c = *fmt++) == '%') {
            mprPutCharToBuf(buf, c);
            continue;
        }
        switch (c) {
        case 'a':                           /* Remote IP */
            mprPutStringToBuf(buf, conn->ip);
            break;

        case 'A':                           /* Local IP */
            mprPutStringToBuf(buf, conn->sock->listenSock->ip);
            break;

        case 'b':
            if (tx->bytesWritten == 0) {
                mprPutCharToBuf(buf, '-');
            } else {
                mprPutIntToBuf(buf, tx->bytesWritten);
            } 
            break;

        case 'B':                           /* Bytes written (minus headers) */
            mprPutIntToBuf(buf, (tx->bytesWritten - tx->headerSize));
            break;

        case 'h':                           /* Remote host */
            mprPutStringToBuf(buf, conn->ip);
            break;

        case 'n':                           /* Local host */
            mprPutStringToBuf(buf, rx->parsedUri->host);
            break;

        case 'O':                           /* Bytes written (including headers) */
            mprPutIntToBuf(buf, tx->bytesWritten);
            break;

        case 'r':                           /* First line of request */
            mprPutToBuf(buf, "%s %s %s", rx->method, rx->uri, conn->protocol);
            break;

        case 's':                           /* Response code */
            mprPutIntToBuf(buf, tx->status);
            break;

        case 't':                           /* Time */
            mprPutCharToBuf(buf, '[');
            timeText = mprFormatLocalTime(MPR_DEFAULT_DATE, mprGetTime());
            mprPutStringToBuf(buf, timeText);
            mprPutCharToBuf(buf, ']');
            break;

        case 'u':                           /* Remote username */
            mprPutStringToBuf(buf, conn->username ? conn->username : "******");
            break;

        case '{':                           /* Header line */
            qualifier = fmt;
            if ((cp = strchr(qualifier, '}')) != 0) {
                fmt = &cp[1];
                *cp = '\0';
                c = *fmt++;
                scopy(keyBuf, sizeof(keyBuf), "HTTP_");
                scopy(&keyBuf[5], sizeof(keyBuf) - 5, qualifier);
                switch (c) {
                case 'i':
                    value = (char*) mprLookupKey(rx->headers, supper(keyBuf));
                    mprPutStringToBuf(buf, value ? value : "-");
                    break;
                default:
                    mprPutStringToBuf(buf, qualifier);
                }
                *cp = '}';

            } else {
                mprPutCharToBuf(buf, c);
            }
            break;

        case '>':
            if (*fmt == 's') {
                fmt++;
                mprPutIntToBuf(buf, tx->status);
            }
            break;

        default:
            mprPutCharToBuf(buf, c);
            break;
        }
    }
    mprPutCharToBuf(buf, '\n');
    mprAddNullToBuf(buf);
    mprWriteFile(route->log, mprGetBufStart(buf), mprGetBufLength(buf));
}