Lines 22-27
Link Here
|
22 |
#include "util_filter.h" |
22 |
#include "util_filter.h" |
23 |
#include "util_script.h" |
23 |
#include "util_script.h" |
24 |
#include "util_charset.h" |
24 |
#include "util_charset.h" |
|
|
25 |
#include "ap_mpm.h" |
26 |
|
25 |
|
27 |
|
26 |
/* |
28 |
/* |
27 |
* mod_disk_cache: Disk Based HTTP 1.1 Cache. |
29 |
* mod_disk_cache: Disk Based HTTP 1.1 Cache. |
Lines 1677-1682
static apr_status_t copy_body(apr_pool_t
Link Here
|
1677 |
} |
1679 |
} |
1678 |
|
1680 |
|
1679 |
|
1681 |
|
|
|
1682 |
/* Provide srcfile and srcinfo containing |
1683 |
APR_FINFO_INODE|APR_FINFO_MTIME to make sure we have opened the right file |
1684 |
(someone might have just replaced it which messes up things). |
1685 |
*/ |
1686 |
static apr_status_t copy_body_nofd(apr_pool_t *p, const char *srcfile, |
1687 |
apr_off_t srcoff, apr_finfo_t *srcinfo, |
1688 |
const char *destfile, apr_off_t destoff, |
1689 |
apr_off_t len) |
1690 |
{ |
1691 |
apr_status_t rc; |
1692 |
apr_file_t *srcfd, *destfd; |
1693 |
apr_finfo_t finfo; |
1694 |
|
1695 |
rc = apr_file_open(&srcfd, srcfile, APR_READ | APR_BINARY, 0, p); |
1696 |
if(rc != APR_SUCCESS) { |
1697 |
return rc; |
1698 |
} |
1699 |
rc = apr_file_info_get(&finfo, APR_FINFO_INODE|APR_FINFO_MTIME, srcfd); |
1700 |
if(rc != APR_SUCCESS) { |
1701 |
return rc; |
1702 |
} |
1703 |
if(srcinfo->inode != finfo.inode || srcinfo->mtime < finfo.mtime) { |
1704 |
return APR_EGENERAL; |
1705 |
} |
1706 |
|
1707 |
rc = apr_file_open(&destfd, destfile, APR_WRITE | APR_BINARY, 0, p); |
1708 |
if(rc != APR_SUCCESS) { |
1709 |
return rc; |
1710 |
} |
1711 |
|
1712 |
rc = copy_body(p, srcfd, srcoff, destfd, destoff, len); |
1713 |
apr_file_close(srcfd); |
1714 |
if(rc != APR_SUCCESS) { |
1715 |
apr_file_close(destfd); |
1716 |
return rc; |
1717 |
} |
1718 |
|
1719 |
return apr_file_close(destfd); |
1720 |
} |
1721 |
|
1722 |
|
1723 |
#if APR_HAS_THREADS |
1724 |
static apr_status_t bgcopy_thread_cleanup(void *data) |
1725 |
{ |
1726 |
copyinfo *ci = data; |
1727 |
apr_status_t rc, ret; |
1728 |
apr_pool_t *p; |
1729 |
|
1730 |
/* FIXME: Debug */ |
1731 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s, |
1732 |
"disk_cache: bgcopy_thread_cleanup: %s -> %s", |
1733 |
ci->srcfile, ci->destfile); |
1734 |
|
1735 |
rc = apr_thread_join(&ret, ci->t); |
1736 |
if(rc != APR_SUCCESS) { |
1737 |
ap_log_error(APLOG_MARK, APLOG_ERR, rc, ci->s, |
1738 |
"disk_cache: bgcopy_thread_cleanup: apr_thread_join " |
1739 |
"failed %s -> %s", ci->srcfile, ci->destfile); |
1740 |
return rc; |
1741 |
} |
1742 |
if(ret != APR_SUCCESS) { |
1743 |
ap_log_error(APLOG_MARK, APLOG_ERR, ret, ci->s, |
1744 |
"disk_cache: Background caching body %s -> %s failed", |
1745 |
ci->srcfile, ci->destfile); |
1746 |
} |
1747 |
|
1748 |
/* FIXME: Debug */ |
1749 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s, |
1750 |
"disk_cache: bgcopy_thread_cleanup: SUCCESS %s -> %s", |
1751 |
ci->srcfile, ci->destfile); |
1752 |
|
1753 |
/* Destroy our private pool */ |
1754 |
p = ci->pool; |
1755 |
apr_pool_destroy(p); |
1756 |
|
1757 |
return APR_SUCCESS; |
1758 |
} |
1759 |
|
1760 |
|
1761 |
static void *bgcopy_thread(apr_thread_t *t, void *data) |
1762 |
{ |
1763 |
copyinfo *ci = data; |
1764 |
apr_pool_t *p; |
1765 |
apr_status_t rc; |
1766 |
|
1767 |
p = apr_thread_pool_get(t); |
1768 |
|
1769 |
/* FIXME: Debug */ |
1770 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s, |
1771 |
"disk_cache: bgcopy_thread: start %s -> %s", |
1772 |
ci->srcfile, ci->destfile); |
1773 |
|
1774 |
rc = copy_body_nofd(p, ci->srcfile, ci->srcoff, &(ci->srcinfo), |
1775 |
ci->destfile, ci->destoff, ci->len); |
1776 |
|
1777 |
if(rc != APR_SUCCESS) { |
1778 |
apr_file_remove(ci->destfile, p); |
1779 |
} |
1780 |
|
1781 |
/* FIXME: Debug */ |
1782 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s, |
1783 |
"disk_cache: bgcopy_thread: done %s -> %s", |
1784 |
ci->srcfile, ci->destfile); |
1785 |
|
1786 |
apr_thread_exit(t, rc); |
1787 |
return NULL; |
1788 |
} |
1789 |
#endif /* APR_HAS_THREADS */ |
1790 |
|
1791 |
|
1792 |
#if APR_HAS_FORK |
1793 |
static apr_status_t bgcopy_child_cleanup(void *data) { |
1794 |
copyinfo *ci = data; |
1795 |
int status; |
1796 |
apr_exit_why_e why; |
1797 |
apr_pool_t *p; |
1798 |
|
1799 |
apr_proc_wait(ci->proc, &status, &why, APR_WAIT); |
1800 |
if(why == APR_PROC_EXIT) { |
1801 |
if(status != APR_SUCCESS) { |
1802 |
ap_log_error(APLOG_MARK, APLOG_ERR, status, ci->s, |
1803 |
"disk_cache: Background caching body %s -> %s failed", |
1804 |
ci->srcfile, ci->destfile); |
1805 |
return APR_SUCCESS; |
1806 |
} |
1807 |
} |
1808 |
else if(status & (APR_PROC_SIGNAL | APR_PROC_SIGNAL_CORE) ) { |
1809 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ci->s, |
1810 |
"disk_cache: Background caching body %s -> %s failed, " |
1811 |
"caught signal %d", ci->srcfile, ci->destfile, status); |
1812 |
return APR_SUCCESS; |
1813 |
} |
1814 |
|
1815 |
/* Destroy our private pool */ |
1816 |
p = ci->pool; |
1817 |
apr_pool_destroy(p); |
1818 |
|
1819 |
return APR_SUCCESS; |
1820 |
} |
1821 |
#endif /* APR_HAS_FORK */ |
1822 |
|
1823 |
|
1824 |
static apr_status_t do_bgcopy(apr_file_t *srcfd, apr_off_t srcoff, |
1825 |
apr_file_t *destfd, apr_off_t destoff, |
1826 |
apr_off_t len, conn_rec *c) |
1827 |
{ |
1828 |
copyinfo *ci; |
1829 |
apr_status_t rv; |
1830 |
apr_pool_t *newpool; |
1831 |
const char *srcfile, *destfile; |
1832 |
int mpm_query_info; |
1833 |
|
1834 |
/* It seems pool gets destroyed (ie. fd's closed) before our cleanup |
1835 |
function is called when an error occurs (a dropped connection, for |
1836 |
example), so we need a pool of our own. |
1837 |
*/ |
1838 |
rv = apr_pool_create(&newpool, NULL); |
1839 |
if (rv != APR_SUCCESS) { |
1840 |
return rv; |
1841 |
} |
1842 |
|
1843 |
ci = apr_palloc(newpool, sizeof(*ci)); |
1844 |
if(ci == NULL) { |
1845 |
apr_pool_destroy(newpool); |
1846 |
return APR_ENOMEM; |
1847 |
} |
1848 |
|
1849 |
rv = apr_file_name_get(&srcfile, srcfd); |
1850 |
if(rv != APR_SUCCESS) { |
1851 |
return rv; |
1852 |
} |
1853 |
rv = apr_file_info_get(&(ci->srcinfo), APR_FINFO_INODE|APR_FINFO_MTIME, |
1854 |
srcfd); |
1855 |
if(rv != APR_SUCCESS) { |
1856 |
return rv; |
1857 |
} |
1858 |
|
1859 |
rv = apr_file_name_get(&destfile, destfd); |
1860 |
if(rv != APR_SUCCESS) { |
1861 |
return rv; |
1862 |
} |
1863 |
|
1864 |
ci->pool = newpool; |
1865 |
ci->srcfile = apr_pstrdup(newpool, srcfile); |
1866 |
ci->srcoff = srcoff; |
1867 |
ci->destfile = apr_pstrdup(newpool, destfile); |
1868 |
ci->destoff = destoff; |
1869 |
ci->len = len; |
1870 |
ci->s = c->base_server; |
1871 |
|
1872 |
#if APR_HAS_THREADS |
1873 |
if(ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info) == APR_SUCCESS) { |
1874 |
apr_threadattr_t *ta; |
1875 |
apr_thread_t *t; |
1876 |
rv = apr_threadattr_create(&ta, newpool); |
1877 |
if(rv != APR_SUCCESS) { |
1878 |
apr_pool_destroy(newpool); |
1879 |
return rv; |
1880 |
} |
1881 |
|
1882 |
apr_threadattr_detach_set(ta, FALSE); |
1883 |
|
1884 |
/* FIXME: This makes module unloadable on AIX */ |
1885 |
#if 0 |
1886 |
#ifdef AP_MPM_WANT_SET_STACKSIZE |
1887 |
if (ap_thread_stacksize != 0) { |
1888 |
apr_threadattr_stacksize_set(ta, ap_thread_stacksize); |
1889 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, |
1890 |
"disk_cache: BG thread stacksize set to %" |
1891 |
APR_SIZE_T_FMT, ap_thread_stacksize); |
1892 |
} |
1893 |
#endif /* AP_MPM_WANT_SET_STACKSIZE */ |
1894 |
#endif /* 0 */ |
1895 |
|
1896 |
rv = apr_thread_create (&t, ta, bgcopy_thread, ci, newpool); |
1897 |
if (rv != APR_SUCCESS) { |
1898 |
apr_pool_destroy(newpool); |
1899 |
return rv; |
1900 |
} |
1901 |
ci->t = t; |
1902 |
|
1903 |
apr_pool_cleanup_register(c->pool, ci, |
1904 |
bgcopy_thread_cleanup, apr_pool_cleanup_null); |
1905 |
} |
1906 |
else |
1907 |
#endif /* APR_HAS_THREADS */ |
1908 |
#if APR_HAS_FORK |
1909 |
if(ap_mpm_query(AP_MPMQ_IS_FORKED, &mpm_query_info) == APR_SUCCESS) { |
1910 |
ci->proc = apr_palloc(newpool, sizeof(apr_proc_t)); |
1911 |
if(ci->proc == NULL) { |
1912 |
apr_pool_destroy(newpool); |
1913 |
return APR_ENOMEM; |
1914 |
} |
1915 |
rv = apr_proc_fork(ci->proc, newpool); |
1916 |
if(rv == APR_INCHILD) { |
1917 |
/* Child */ |
1918 |
rv = copy_body_nofd(ci->pool, ci->srcfile, ci->srcoff, |
1919 |
&(ci->srcinfo), ci->destfile, ci->destoff, |
1920 |
ci->len); |
1921 |
if(rv != APR_SUCCESS) { |
1922 |
apr_file_remove(ci->destfile, ci->pool); |
1923 |
} |
1924 |
exit(rv); |
1925 |
} |
1926 |
else if(rv == APR_INPARENT) { |
1927 |
apr_pool_cleanup_register(c->pool, ci, |
1928 |
bgcopy_child_cleanup, |
1929 |
apr_pool_cleanup_null); |
1930 |
} |
1931 |
else { |
1932 |
return rv; |
1933 |
} |
1934 |
} |
1935 |
else |
1936 |
#endif /* APR_HAS_FORK */ |
1937 |
if(1) |
1938 |
{ |
1939 |
rv = copy_body(newpool, srcfd, ci->srcoff, destfd, ci->destoff, |
1940 |
ci->len); |
1941 |
apr_pool_destroy(newpool); |
1942 |
} |
1943 |
|
1944 |
return rv; |
1945 |
} |
1946 |
|
1947 |
|
1680 |
static apr_status_t replace_brigade_with_cache(cache_handle_t *h, |
1948 |
static apr_status_t replace_brigade_with_cache(cache_handle_t *h, |
1681 |
request_rec *r, |
1949 |
request_rec *r, |
1682 |
apr_bucket_brigade *bb) |
1950 |
apr_bucket_brigade *bb) |
Lines 1828-1835
static apr_status_t store_body(cache_han
Link Here
|
1828 |
e = APR_BRIGADE_FIRST(bb); |
2096 |
e = APR_BRIGADE_FIRST(bb); |
1829 |
a = e->data; |
2097 |
a = e->data; |
1830 |
|
2098 |
|
1831 |
rv = copy_body(r->pool, a->fd, e->start, dobj->fd, 0, |
2099 |
if(dobj->file_size > conf->minbgsize) { |
1832 |
dobj->file_size); |
2100 |
rv = do_bgcopy(a->fd, e->start, dobj->fd, 0, dobj->file_size, |
|
|
2101 |
r->connection); |
2102 |
} |
2103 |
else { |
2104 |
rv = copy_body(r->pool, a->fd, e->start, dobj->fd, 0, |
2105 |
dobj->file_size); |
2106 |
} |
1833 |
if(rv != APR_SUCCESS) { |
2107 |
if(rv != APR_SUCCESS) { |
1834 |
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, |
2108 |
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, |
1835 |
"disk_cache: Copying body failed, " |
2109 |
"disk_cache: Copying body failed, " |
Lines 1963-1968
static void *create_config(apr_pool_t *p
Link Here
|
1963 |
conf->maxfs = DEFAULT_MAX_FILE_SIZE; |
2237 |
conf->maxfs = DEFAULT_MAX_FILE_SIZE; |
1964 |
conf->minfs = DEFAULT_MIN_FILE_SIZE; |
2238 |
conf->minfs = DEFAULT_MIN_FILE_SIZE; |
1965 |
conf->updtimeout = DEFAULT_UPDATE_TIMEOUT; |
2239 |
conf->updtimeout = DEFAULT_UPDATE_TIMEOUT; |
|
|
2240 |
conf->minbgsize = DEFAULT_MIN_BACKGROUND_SIZE; |
1966 |
|
2241 |
|
1967 |
conf->cache_root = NULL; |
2242 |
conf->cache_root = NULL; |
1968 |
conf->cache_root_len = 0; |
2243 |
conf->cache_root_len = 0; |
Lines 2065-2070
static const char
Link Here
|
2065 |
} |
2340 |
} |
2066 |
|
2341 |
|
2067 |
|
2342 |
|
|
|
2343 |
static const char |
2344 |
*set_cache_minbgsize(cmd_parms *parms, void *in_struct_ptr, const char *arg) |
2345 |
{ |
2346 |
disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, |
2347 |
&disk_cache_module); |
2348 |
|
2349 |
if (apr_strtoff(&conf->minbgsize, arg, NULL, 0) != APR_SUCCESS || |
2350 |
conf->minbgsize < 0) |
2351 |
{ |
2352 |
return "CacheMinBGSize argument must be a non-negative integer representing the min size in bytes for a file to be eligable for background caching"; |
2353 |
} |
2354 |
|
2355 |
return NULL; |
2356 |
} |
2357 |
|
2358 |
|
2068 |
static const command_rec disk_cache_cmds[] = |
2359 |
static const command_rec disk_cache_cmds[] = |
2069 |
{ |
2360 |
{ |
2070 |
AP_INIT_TAKE1("CacheRoot", set_cache_root, NULL, RSRC_CONF, |
2361 |
AP_INIT_TAKE1("CacheRoot", set_cache_root, NULL, RSRC_CONF, |
Lines 2079-2084
static const command_rec disk_cache_cmds
Link Here
|
2079 |
"The maximum file size to cache a document"), |
2370 |
"The maximum file size to cache a document"), |
2080 |
AP_INIT_TAKE1("CacheUpdateTimeout", set_cache_updtimeout, NULL, RSRC_CONF, |
2371 |
AP_INIT_TAKE1("CacheUpdateTimeout", set_cache_updtimeout, NULL, RSRC_CONF, |
2081 |
"Timeout in ms for cache updates"), |
2372 |
"Timeout in ms for cache updates"), |
|
|
2373 |
AP_INIT_TAKE1("CacheMinBGSize", set_cache_minbgsize, NULL, RSRC_CONF, |
2374 |
"The minimum file size for background caching"), |
2082 |
{NULL} |
2375 |
{NULL} |
2083 |
}; |
2376 |
}; |
2084 |
|
2377 |
|