+
+int Yaz_Proxy::file_access(Z_HTTP_Request *hreq)
+{
+ yaz_log(YLOG_LOG, "file_access");
+ if (strcmp(hreq->method, "GET"))
+ return 0;
+ struct stat sbuf;
+ if (hreq->path[0] != '/')
+ {
+ yaz_log(YLOG_WARN, "Path != /");
+ return 0;
+ }
+ const char *cp = hreq->path;
+ while (*cp)
+ {
+ if (*cp == '/' && strchr("/.", cp[1]))
+ return 0;
+ cp++;
+ }
+ const char *fname = hreq->path+1;
+ if (stat(fname, &sbuf))
+ {
+ yaz_log(YLOG_WARN, "stat %s failed", fname);
+ return 0;
+ }
+ if ((sbuf.st_mode & S_IFMT) != S_IFREG)
+ return 0;
+ if (sbuf.st_size > (off_t) 1000000)
+ return 0;
+
+ ODR o = odr_encode();
+ Yaz_ProxyConfig *cfg = check_reconfigure();
+ const char *ctype = cfg->check_mime_type(fname);
+ Z_GDU *gdu = z_get_HTTP_Response(o, 200);
+ Z_HTTP_Response *hres = gdu->u.HTTP_Response;
+ if (m_http_version)
+ hres->version = odr_strdup(o, m_http_version);
+ z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
+ if (m_http_keepalive)
+ z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive");
+ else
+ timeout(0);
+
+ hres->content_len = sbuf.st_size;
+ hres->content_buf = (char*) odr_malloc(o, hres->content_len);
+ FILE *f = fopen(fname, "rb");
+ if (f)
+ {
+ fread(hres->content_buf, 1, hres->content_len, f);
+ fclose(f);
+ }
+ else
+ {
+ return 0;
+ }
+ if (m_log_mask & PROXY_LOG_REQ_CLIENT)
+ {
+ yaz_log (YLOG_LOG, "%sSending file %s to client", m_session_str,
+ fname);
+ }
+ int len;
+ send_GDU(gdu, &len);
+ return 1;
+}