Exemplo n.º 1
0
static void bod_close(bod_state *state) {
	if (NULL != state->tempfile) {
		li_chunkfile_release(state->tempfile);
		state->tempfile = NULL;
	}
	state->flush_pos = state->write_pos = 0;
}
Exemplo n.º 2
0
static void chunk_free(liChunkQueue *cq, liChunk *c) {
	if (!c) return;
	if (cq) {
		g_queue_unlink(&cq->queue, &c->cq_link);
	}
	switch (c->type) {
	case UNUSED_CHUNK:
		break;
	case STRING_CHUNK:
		g_string_free(c->data.str, TRUE);
		c->data.str = NULL;
		break;
	case MEM_CHUNK:
		/* mem is handled extra below */
		break;
	case FILE_CHUNK:
		if (c->data.file.file) {
			li_chunkfile_release(c->data.file.file);
			c->data.file.file = NULL;
		}
		if (c->data.file.mmap.data != MAP_FAILED) {
			munmap(c->data.file.mmap.data, c->data.file.mmap.length);
			c->data.file.mmap.data = MAP_FAILED;
		}
		break;
	case BUFFER_CHUNK:
		li_buffer_release(c->data.buffer.buffer);
		break;
	}
	c->type = UNUSED_CHUNK;
	if (c->mem) {
		g_byte_array_free(c->mem, TRUE);
		c->mem = NULL;
	}
	g_slice_free(liChunk, c);
}
Exemplo 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;
}