Beispiel #1
0
static void readBody(HttpConn *conn, MprFile *outFile)
{
    char        buf[BIT_MAX_BUFFER];
    cchar       *result;
    ssize       bytes;

    while (!conn->error && conn->sock && (bytes = httpRead(conn, buf, sizeof(buf))) > 0) {
        if (!app->noout) {
            result = formatOutput(conn, buf, &bytes);
            if (result) {
                mprWriteFile(outFile, result, bytes);
            }
        }
#if FUTURE
        //  This should be pushed into a range filter.
        //  Buffer all output and then parsing can work
        type = httpGetHeader(conn, "Content-Type");
        if (scontains(type, "multipart/byteranges")) {
            if ((boundary = scontains(type, "boundary=")) != 0) {
                boundary += 9;
                if (*boundary) {
                    boundary = sfmt("--%s\r\n", boundary);
                }
            }
        }
#endif
    }
}
Beispiel #2
0
static void showOutput(HttpConn *conn, cchar *buf, ssize count)
{
    HttpRx      *rx;
    int         i, c;
    
    rx = conn->rx;

    if (app->noout) {
        return;
    }
    if (rx->status == 401 || (conn->followRedirects && (301 <= rx->status && rx->status <= 302))) {
        return;
    }
    if (app->outFile == 0) {
        if (app->outFilename) {
            if ((app->outFile = mprOpenFile(app->outFilename, O_CREAT | O_WRONLY | O_TRUNC | O_TEXT, 0664)) == 0) {
                mprError("Can't open %s", app->outFile);
                return;
            }
        } else {
            app->outFile = mprGetStdout();
        }
    }
    if (!app->printable) {
        mprWriteFile(app->outFile, buf, count);
        return;
    }
    for (i = 0; i < count; i++) {
        if (!isprint((uchar) buf[i]) && buf[i] != '\n' && buf[i] != '\r' && buf[i] != '\t') {
            app->isBinary = 1;
            break;
        }
    }
    if (!app->isBinary) {
        mprWriteFile(app->outFile, buf, count);
        return;
    }
    for (i = 0; i < count; i++) {
        c = (uchar) buf[i];
        if (app->printable && app->isBinary) {
            mprFprintf(app->outFile, "%02x ", c & 0xff);
        } else {
            mprFprintf(app->outFile, "%c", (uchar) buf[i]);
        }
    }
}
Beispiel #3
0
PUBLIC void maWriteAccessLogEntry(HttpRoute *route, cchar *buf, int len)
{
    static int once = 0;

    if (mprWriteFile(route->log, (char*) buf, len) != len && once++ == 0) {
        mprError("Cannot write to access log %s", route->logPath);
    }
}
Beispiel #4
0
/*  
    Write data to the file
    function write(data: Object): Number
 */
PUBLIC EjsObj *writeFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *ap;
    EjsObj          *vp;
    EjsString       *str;
    cchar           *buf;
    ssize           len, written;
    int             i;

    assert(argc == 1 && ejsIs(ejs, argv[0], Array));

    args = (EjsArray*) argv[0];

    if (!(fp->mode & EJS_FILE_WRITE)) {
        ejsThrowStateError(ejs, "File not opened for writing");
        return 0;
    }
    written = 0;

    for (i = 0; i < args->length; i++) {
        vp = ejsGetProperty(ejs, (EjsObj*) args, i);
        assert(vp);
        switch (TYPE(vp)->sid) {
        case S_ByteArray:
            ap = (EjsByteArray*) vp;
            //  TODO UNICODE ENCODING
            buf = (cchar*) &ap->value[ap->readPosition];
            len = ap->writePosition - ap->readPosition;
            break;

        case S_String: // UNICODE
#if UNICODE && FUTURE
            buf = awtom(((EjsString*) vp)->value, &len);
#else
            buf = ((EjsString*) vp)->value;
            len = ((EjsString*) vp)->length;
#endif
            break;

        default:
            str = ejsToString(ejs, vp);
            buf = awtom(((EjsString*) str)->value, &len);
            break;
        }
        if (mprWriteFile(fp->file, buf, len) != len) {
            ejsThrowIOError(ejs, "Cannot write to %s", fp->path);
            return 0;
        }
        written += len;
        /* Use GC to free buf as it may not be allocated */
    }
    return (EjsObj*) ejsCreateNumber(ejs, (MprNumber) written);
}
Beispiel #5
0
static EjsObj *saveXml(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    MprBuf      *buf;
    MprFile     *file;
    char        *filename;
    ssize       bytes, len;

    if (argc != 1 || !ejsIs(ejs, argv[0], String)) {
        ejsThrowArgError(ejs, "Bad args. Usage: save(filename);");
        return 0;
    }
    filename = awtom(((EjsString*) argv[0])->value, NULL);

    /*
        Create a buffer to hold the output. All in memory.
     */
    buf = mprCreateBuf(ME_MAX_BUFFER, -1);
    mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>\n");

    if (ejsXMLToBuf(ejs, buf, xml, 0) < 0) {
        return 0;
    }
    file = mprOpenFile(filename,  O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664);
    if (file == 0) {
        ejsThrowIOError(ejs, "Cannot open: %s, %d", filename, mprGetOsError(ejs));
        return 0;
    }
    len = mprGetBufLength(buf);
    bytes = mprWriteFile(file, buf->start, len);
    if (bytes != len) {
        ejsThrowIOError(ejs, "Cannot write to: %s", filename);
        mprCloseFile(file);
        return 0;
    }
    mprWriteFile(file, "\n", 1);
    mprCloseFile(file);
    return 0;
}
Beispiel #6
0
static void readBody(HttpConn *conn, MprFile *outFile)
{
    char        buf[ME_MAX_BUFFER];
    cchar       *result;
    ssize       bytes;

    while (!conn->error && (bytes = httpRead(conn, buf, sizeof(buf))) > 0) {
        if (!app->noout) {
            result = formatOutput(conn, buf, &bytes);
            if (result) {
                mprWriteFile(outFile, result, bytes);
            }
        }
    }
}
Beispiel #7
0
/*
    Put a character to the file. This will put the file into buffered mode.
 */
PUBLIC ssize mprPutFileChar(MprFile *file, int c)
{
    assert(file);

    if (file == 0) {
        return -1;
    }
    if (file->buf) {
        if (mprPutCharToBuf(file->buf, c) != 1) {
            return MPR_ERR_CANT_WRITE;
        }
        file->pos++;
        return 1;

    }
    return mprWriteFile(file, &c, 1);
}
Beispiel #8
0
/*
    The incoming callback is invoked to receive body data 
 */
static void incomingFile(HttpQueue *q, HttpPacket *packet)
{
    HttpConn    *conn;
    HttpTx      *tx;
    HttpRx      *rx;
    HttpRange   *range;
    MprBuf      *buf;
    MprFile     *file;
    ssize       len;

    conn = q->conn;
    tx = conn->tx;
    rx = conn->rx;
    file = (MprFile*) q->queueData;
    
    if (file == 0) {
        /*  Not a PUT so just ignore the incoming data.  */
        return;
    }
    if (httpGetPacketLength(packet) == 0) {
        /* End of input */
        if (file) {
            mprCloseFile(file);
        }
        q->queueData = 0;
        if (!tx->etag) {
            /* Set the etag for caching in the client */
            mprGetPathInfo(tx->filename, &tx->fileInfo);
            tx->etag = sfmt("\"%llx-%llx-%llx\"", tx->fileInfo.inode, tx->fileInfo.size, tx->fileInfo.mtime);
        }
        return;
    }
    buf = packet->content;
    len = mprGetBufLength(buf);
    assert(len > 0);

    range = rx->inputRange;
    if (range && mprSeekFile(file, SEEK_SET, range->start) != range->start) {
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot seek to range start to %lld", range->start);

    } else if (mprWriteFile(file, mprGetBufStart(buf), len) != len) {
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot PUT to %s", tx->filename);
    }
}
Beispiel #9
0
/*
    uncompress(src: Path, dest: Path = null)
 */
static EjsObj *zlib_uncompress(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    MprFile     *out;
    gzFile      in;
    cchar       *src, *dest;
    uchar       inbuf[MPR_BUFSIZE];
    ssize       nbytes;

    src = ((EjsPath*) argv[0])->value;
    dest = (argc >= 2) ? ejsToMulti(ejs, argv[1]) : 0;
    if (!dest) {
        dest = sjoin(src, ".gz", NULL);
    }
    if ((in = gzopen(src, "rb")) == 0) {
        ejsThrowIOError(ejs, "Cannot open from %s", src);
        return 0;
    }
    if ((out = mprOpenFile(dest, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644)) == 0) {
        ejsThrowIOError(ejs, "Cannot open destination %s", dest);
        return 0;
    }
    while (1) {
        if ((nbytes = gzread(in, inbuf, sizeof(inbuf))) < 0) {
            ejsThrowIOError(ejs, "Cannot read from %s", src);
            return 0;
        } else if (nbytes == 0) {
            break;
        }
        if (mprWriteFile(out, inbuf, (int) nbytes) != nbytes) {
            ejsThrowIOError(ejs, "Cannot write to %s", dest);
            return 0;
        }
    }
    mprCloseFile(out);
    gzclose(in);
    return 0;
}
Beispiel #10
0
static int writeToFile(HttpQueue *q, char *data, ssize len)
{
    HttpConn        *conn;
    HttpUploadFile  *file;
    HttpLimits      *limits;
    Upload          *up;
    ssize           rc;

    conn = q->conn;
    limits = conn->limits;
    up = q->queueData;
    file = up->currentFile;

    if ((file->size + len) > limits->uploadSize) {
        /*
            Abort the connection as we don't want the load of receiving the entire body
         */
        httpLimitError(conn, HTTP_ABORT | HTTP_CODE_REQUEST_TOO_LARGE, "Uploaded file exceeds maximum %lld", 
            limits->uploadSize);
        return MPR_ERR_CANT_WRITE;
    }
    if (len > 0) {
        /*
            File upload. Write the file data.
         */
        rc = mprWriteFile(up->file, data, len);
        if (rc != len) {
            httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR,
                "Cannot write to upload temp file %s, rc %zd, errno %d", up->tmpPath, rc, mprGetOsError());
            return MPR_ERR_CANT_WRITE;
        }
        file->size += len;
        conn->rx->bytesUploaded += len;
    }
    return 0;
}
Beispiel #11
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));
}
Beispiel #12
0
/*
    Compile a view or controller

    cacheName   MD5 cache name (not a full path)
    source      ESP source file name
    module      Module file name
 */
bool espCompile(HttpConn *conn, cchar *source, cchar *module, cchar *cacheName, int isView)
{
    MprFile     *fp;
    HttpRx      *rx;
    HttpRoute   *route;
    EspRoute    *eroute;
    cchar       *csource;
    char        *layout, *script, *page, *err;
    ssize       len;

    rx = conn->rx;
    route = rx->route;
    eroute = route->eroute;
    layout = 0;

    if (isView) {
        if ((page = mprReadPathContents(source, &len)) == 0) {
            httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't read %s", source);
            return 0;
        }
        /*
            Use layouts iff there is a source defined on the route. Only MVC/controllers based apps do this.
         */
        if (eroute->layoutsDir) {
#if UNUSED
        layout = mprSamePath(eroute->layoutsDir, route->dir) ? 0 : mprJoinPath(eroute->layoutsDir, "default.esp");
#else
        layout = mprJoinPath(eroute->layoutsDir, "default.esp");
#endif
        }
        if ((script = espBuildScript(route, page, source, cacheName, layout, &err)) == 0) {
            httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't build %s, error %s", source, err);
            return 0;
        }
        csource = mprJoinPathExt(mprTrimPathExt(module), ".c");
        if ((fp = mprOpenFile(csource, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0664)) == 0) {
            httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't open compiled script file %s", csource);
            return 0;
        }
        len = slen(script);
        if (mprWriteFile(fp, script, len) != len) {
            httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't write compiled script file %s", csource);
            mprCloseFile(fp);
            return 0;
        }
        mprCloseFile(fp);
    } else {
        csource = source;
    }
    mprMakeDir(eroute->cacheDir, 0775, -1, -1, 1);
    /*
        WARNING: GC yield here
     */
    if (runCommand(conn, eroute->compile, csource, module) < 0) {
        return 0;
    }
    if (eroute->link) {
        /*
            WARNING: GC yield here
         */
        if (runCommand(conn, eroute->link, csource, module) < 0) {
            return 0;
        }
#if !(BLD_DEBUG && MACOSX)
        /*
            MAC needs the object for debug information
         */
        mprDeletePath(mprJoinPathExt(mprTrimPathExt(module), BLD_OBJ));
#endif
    }
#if BLD_WIN_LIKE
    {
        /*
            Windows leaves intermediate object in the current directory
         */
        cchar   *obj;
        obj = mprReplacePathExt(mprGetPathBase(csource), BLD_OBJ);
        if (mprPathExists(obj, F_OK)) {
            mprDeletePath(obj);
        }
    }
#endif
    if (!eroute->keepSource && isView) {
        mprDeletePath(csource);
    }
    return 1;
}
Beispiel #13
0
PUBLIC ssize mprWriteFileString(MprFile *file, cchar *str)
{
    return mprWriteFile(file, str, slen(str));
}