Пример #1
0
static liHandlerResult cache_etag_filter_miss(liVRequest *vr, liFilter *f) {
	cache_etag_file *cfile = (cache_etag_file*) f->param;
	ssize_t res;
	gchar *buf;
	off_t buflen;
	liChunkIter citer = li_chunkqueue_iter(f->in);
	UNUSED(vr);

	if (0 == f->in->length) return LI_HANDLER_GO_ON;

	if (!cfile) { /* somehow we lost the file */
		li_chunkqueue_steal_all(f->out, f->in);
		if (f->in->is_closed) f->out->is_closed = TRUE;
		return LI_HANDLER_GO_ON;
	}

	if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, citer, 0, 64*1024, &buf, &buflen)) {
		VR_ERROR(vr, "%s", "Couldn't read data from chunkqueue");
		cache_etag_file_free(cfile);
		f->param = NULL;
		li_chunkqueue_steal_all(f->out, f->in);
		if (f->in->is_closed) f->out->is_closed = TRUE;
		return LI_HANDLER_GO_ON;
	}

	res = write(cfile->fd, buf, buflen);
	if (res < 0) {
		switch (errno) {
		case EINTR:
		case EAGAIN:
			break; /* come back later */
		default:
			VR_ERROR(vr, "Couldn't write to temporary cache file '%s': %s",
				cfile->tmpfilename->str, g_strerror(errno));
			cache_etag_file_free(cfile);
			f->param = NULL;
			li_chunkqueue_steal_all(f->out, f->in);
			if (f->in->is_closed) f->out->is_closed = TRUE;
			return LI_HANDLER_GO_ON;
		}
	} else {
		li_chunkqueue_steal_len(f->out, f->in, res);
		if (f->in->length == 0 && f->in->is_closed) {
			cache_etag_file_finish(vr, cfile);
			f->param = NULL;
			f->out->is_closed = TRUE;
			return LI_HANDLER_GO_ON;
		}
	}

	return f->in->length ? LI_HANDLER_COMEBACK : LI_HANDLER_GO_ON;
}
Пример #2
0
static liHandlerResult cache_etag_filter_miss(liVRequest *vr, liFilter *f) {
	cache_etag_file *cfile = (cache_etag_file*) f->param;
	ssize_t res;
	gchar *buf;
	off_t buflen;
	liChunkIter citer;
	GError *err = NULL;

	if (NULL == f->in) {
		cache_etag_filter_free(vr, f);
		/* didn't handle f->in->is_closed? abort forwarding */
		if (!f->out->is_closed) li_stream_reset(&f->stream);
		return LI_HANDLER_GO_ON;
	}

	if (NULL == cfile) goto forward;

	if (f->in->length > 0) {
		citer = li_chunkqueue_iter(f->in);
		if (LI_HANDLER_GO_ON != li_chunkiter_read(citer, 0, 64*1024, &buf, &buflen, &err)) {
			if (NULL != err) {
				if (NULL != vr) VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message);
				g_error_free(err);
			} else {
				if (NULL != vr) VR_ERROR(vr, "%s", "Couldn't read data from chunkqueue");
			}
			cache_etag_filter_free(vr, f);
			goto forward;
		}

		res = write(cfile->fd, buf, buflen);
		if (res < 0) {
			switch (errno) {
			case EINTR:
			case EAGAIN:
				return LI_HANDLER_COMEBACK;
			default:
				if (NULL != vr) VR_ERROR(vr, "Couldn't write to temporary cache file '%s': %s",
					cfile->tmpfilename->str, g_strerror(errno));
				cache_etag_filter_free(vr, f);
				goto forward;
			}
		} else {
			if (!f->out->is_closed) {
				li_chunkqueue_steal_len(f->out, f->in, res);
			} else {
				li_chunkqueue_skip(f->in, res);
			}
		}
	}

	if (0 == f->in->length && f->in->is_closed) {
		f->out->is_closed = TRUE;
		f->param = NULL;
		cache_etag_file_finish(vr, cfile);
		return LI_HANDLER_GO_ON;
	}

	return LI_HANDLER_GO_ON;

forward:
	if (f->out->is_closed) {
		li_chunkqueue_skip_all(f->in);
		li_stream_disconnect(&f->stream);
	} else {
		li_chunkqueue_steal_all(f->out, f->in);
		if (f->in->is_closed) f->out->is_closed = f->in->is_closed;
	}
	return LI_HANDLER_GO_ON;
}