Ejemplo n.º 1
0
/* flush current tempfile chunk. ignores out->is_closed. */
static void bod_flush(bod_state *state) {
	liChunkQueue *out = state->stream.out;
	if (NULL != out && NULL != state->tempfile && state->write_pos > state->flush_pos) {
		li_chunkqueue_append_chunkfile(out, state->tempfile, state->flush_pos, state->write_pos - state->flush_pos);
		state->flush_pos = state->write_pos;
		li_stream_notify(&state->stream);
	}
}
Ejemplo n.º 2
0
static void bod_autoflush(liChunkQueue *out, bod_state *state) {
	if (-1 != state->flush_limit && state->tempfile && state->write_pos - state->flush_pos > state->flush_limit) {
		li_chunkqueue_append_chunkfile(out, state->tempfile, state->flush_pos, state->write_pos - state->flush_pos);
		state->flush_pos = state->write_pos;
	}
}
Ejemplo n.º 3
0
static liHandlerResult flv(liVRequest *vr, gpointer param, gpointer *context) {
    gchar *start;
    guint len;
    goffset pos;
    liHandlerResult res;
    gboolean cachable;
    struct stat st;
    int err;
    int fd = -1;

    UNUSED(context);
    UNUSED(param);

    if (li_vrequest_is_handled(vr))
        return LI_HANDLER_GO_ON;

    res = li_stat_cache_get(vr, vr->physical.path, &st, &err, &fd);

    if (res == LI_HANDLER_WAIT_FOR_EVENT)
        return res;

    if (res == LI_HANDLER_ERROR) {
        /* open or fstat failed */

        if (fd != -1)
            close(fd);

        if (!li_vrequest_handle_direct(vr))
            return LI_HANDLER_ERROR;

        switch (err) {
        case ENOENT:
        case ENOTDIR:
            vr->response.http_status = 404;
            return LI_HANDLER_GO_ON;
        case EACCES:
            vr->response.http_status = 403;
            return LI_HANDLER_GO_ON;
        default:
            VR_ERROR(vr, "stat() or open() for '%s' failed: %s", vr->physical.path->str, g_strerror(err));
            return LI_HANDLER_ERROR;
        }
    } else if (S_ISDIR(st.st_mode)) {
        if (fd != -1)
            close(fd);

        return LI_HANDLER_GO_ON;
    } else if (!S_ISREG(st.st_mode)) {
        if (fd != -1)
            close(fd);

        if (!li_vrequest_handle_direct(vr))
            return LI_HANDLER_ERROR;

        vr->response.http_status = 403;
    } else {
        liChunkFile *cf;

#ifdef FD_CLOEXEC
        fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif

        if (!li_vrequest_handle_direct(vr)) {
            close(fd);
            return LI_HANDLER_ERROR;
        }

        if (li_querystring_find(vr->request.uri.query, CONST_STR_LEN("start"), &start, &len)) {
            guint i;
            pos = 0;

            for (i = 0; i < len; i++) {
                if (start[i] >= '0' && start[i] <= '9') {
                    pos *= 10;
                    pos += start[i] - '0';
                }
            }
        } else {
            pos = 0;
        }

        li_etag_set_header(vr, &st, &cachable);
        if (cachable) {
            vr->response.http_status = 304;
            close(fd);
            return LI_HANDLER_GO_ON;
        }


        vr->response.http_status = 200;
        li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));

        if (pos < 0 || pos > st.st_size)
            pos = 0;

        if (pos != 0)
            li_chunkqueue_append_mem(vr->direct_out, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));

        cf = li_chunkfile_new(NULL, fd, FALSE);
        li_chunkqueue_append_chunkfile(vr->direct_out, cf, pos, st.st_size - pos);
        li_chunkfile_release(cf);
    }

    return LI_HANDLER_GO_ON;
}