MCPcopy Create free account
hub / github.com/apache/httpd / cache_save_store

Function cache_save_store

modules/cache/mod_cache.c:702–772  ·  view source on GitHub ↗

* Having jumped through all the hoops and decided to cache the * response, call store_body() for each brigade, handling the * case where the provider can't swallow the full brigade. In this * case, we write the brigade we were passed out downstream, and * loop around to try and cache some more until the in brigade is * completely empty. As soon as the out brigade contains eos, call * commit_

Source from the content-addressed store, hash-verified

700 * commit_entity() to finalise the cached element.
701 */
702static int cache_save_store(ap_filter_t *f, apr_bucket_brigade *in,
703 cache_server_conf *conf, cache_request_rec *cache)
704{
705 int rv = APR_SUCCESS;
706 apr_bucket *e;
707
708 /* pass the brigade in into the cache provider, which is then
709 * expected to move cached buckets to the out brigade, for us
710 * to pass up the filter stack. repeat until in is empty, or
711 * we fail.
712 */
713 while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(in)) {
714
715 rv = cache->provider->store_body(cache->handle, f->r, in, cache->out);
716 if (rv != APR_SUCCESS) {
717 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, f->r, APLOGNO(00765)
718 "cache: Cache provider's store_body failed for URI %s", f->r->uri);
719 ap_remove_output_filter(f);
720
721 /* give someone else the chance to cache the file */
722 cache_remove_lock(conf, cache, f->r, NULL);
723
724 /* give up trying to cache, just step out the way */
725 APR_BRIGADE_PREPEND(in, cache->out);
726 return ap_pass_brigade(f->next, in);
727
728 }
729
730 /* does the out brigade contain eos? if so, we're done, commit! */
731 for (e = APR_BRIGADE_FIRST(cache->out);
732 e != APR_BRIGADE_SENTINEL(cache->out);
733 e = APR_BUCKET_NEXT(e))
734 {
735 if (APR_BUCKET_IS_EOS(e)) {
736 rv = cache->provider->commit_entity(cache->handle, f->r);
737 break;
738 }
739 }
740
741 /* conditionally remove the lock as soon as we see the eos bucket */
742 cache_remove_lock(conf, cache, f->r, cache->out);
743
744 if (APR_BRIGADE_EMPTY(cache->out)) {
745 if (APR_BRIGADE_EMPTY(in)) {
746 /* cache provider wants more data before passing the brigade
747 * upstream, oblige the provider by leaving to fetch more.
748 */
749 break;
750 }
751 else {
752 /* oops, no data out, but not all data read in either, be
753 * safe and stand down to prevent a spin.
754 */
755 ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, f->r, APLOGNO(00766)
756 "cache: Cache provider's store_body returned an "
757 "empty brigade, but didn't consume all of the "
758 "input brigade, standing down to prevent a spin");
759 ap_remove_output_filter(f);

Callers 1

cache_save_filterFunction · 0.85

Calls 3

ap_remove_output_filterFunction · 0.85
cache_remove_lockFunction · 0.85
ap_pass_brigadeFunction · 0.85

Tested by

no test coverage detected