summaryrefslogtreecommitdiff
path: root/src/response.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/response.c')
-rw-r--r--src/response.c794
1 files changed, 0 insertions, 794 deletions
diff --git a/src/response.c b/src/response.c
deleted file mode 100644
index 6dfc4e62..00000000
--- a/src/response.c
+++ /dev/null
@@ -1,794 +0,0 @@
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <limits.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include <stdio.h>
-
-#include "settings.h"
-
-#include "response.h"
-#include "keyvalue.h"
-#include "log.h"
-#include "stat_cache.h"
-#include "chunk.h"
-
-#include "connections.h"
-
-#include "plugin.h"
-
-#include "sys-socket.h"
-#include "sys-files.h"
-#include "sys-strings.h"
-
-int http_response_write_header(server *srv, connection *con, chunkqueue *raw) {
- buffer *b;
- size_t i;
- int have_date = 0;
- int have_server = 0;
- int allow_keep_alive = 0;
-
- b = chunkqueue_get_prepend_buffer(raw);
-
- if (con->request.http_version == HTTP_VERSION_1_1) {
- buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 "));
- } else {
- buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
- }
- buffer_append_long(b, con->http_status);
- buffer_append_string_len(b, CONST_STR_LEN(" "));
- buffer_append_string(b, get_http_status_name(con->http_status));
-
- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
- response_header_overwrite(srv, con, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN("chunked"));
- allow_keep_alive = 1;
- } else if ((con->http_status >= 100 && con->http_status < 200) ||
- con->http_status == 204 ||
- con->http_status == 304) {
- /* 1xx, 204 and 304 never have a content-body ->
- * never have a Content-Length and are always
- * able to do keep-alive
- */
- allow_keep_alive = 1;
- } else if (con->response.content_length >= 0) {
- buffer_copy_off_t(srv->tmp_buf, con->response.content_length);
- response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
-
- allow_keep_alive = 1;
- }
-
- /* keep-alive needs Content-Length or chunked encoding. */
- if (!allow_keep_alive) con->keep_alive = 0;
-
- /* disable keep-alive if requested */
- if (con->request_count > con->conf.max_keep_alive_requests || 0 == con->conf.max_keep_alive_idle) {
- con->keep_alive = 0;
- } else {
- con->keep_alive_idle = con->conf.max_keep_alive_idle;
- }
-
- if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
- if (con->keep_alive) {
- response_header_overwrite(srv, con, CONST_STR_LEN("Connection"), CONST_STR_LEN("keep-alive"));
- } else {
- response_header_overwrite(srv, con, CONST_STR_LEN("Connection"), CONST_STR_LEN("close"));
- }
- }
-
-
- /* add all headers */
- for (i = 0; i < con->response.headers->used; i++) {
- data_string *ds;
-
- ds = (data_string *)con->response.headers->data[i];
-
- if (ds->value->used && ds->key->used &&
- 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) &&
- 0 != strcasecmp(ds->key->ptr, "X-Sendfile")) {
- if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1;
- if (0 == strcasecmp(ds->key->ptr, "Server")) have_server = 1;
-
- buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
- buffer_append_string_buffer(b, ds->key);
- buffer_append_string_len(b, CONST_STR_LEN(": "));
- buffer_append_string_buffer(b, ds->value);
-#if 0
- log_error_write(srv, __FILE__, __LINE__, "bb",
- ds->key, ds->value);
-#endif
- }
- }
-
- if (!have_date) {
- /* HTTP/1.1 requires a Date: header */
- buffer_append_string_len(b, CONST_STR_LEN("\r\nDate: "));
-
- /* cache the generated timestamp */
- if (srv->cur_ts != srv->last_generated_date_ts) {
- buffer_prepare_copy(srv->ts_date_str, 255);
-
- strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
- "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
-
- srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
-
- srv->last_generated_date_ts = srv->cur_ts;
- }
-
- buffer_append_string_buffer(b, srv->ts_date_str);
- }
-
- if (!have_server) {
- if (buffer_is_empty(con->conf.server_tag)) {
- buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION));
- } else {
- buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: "));
- buffer_append_string_buffer(b, con->conf.server_tag);
- }
- }
-
- buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
-
-
- con->bytes_header = b->used - 1;
- raw->bytes_in += b->used - 1;
-
- if (con->conf.log_response_header) {
- log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
- }
-
- return 0;
-}
-
-#ifdef USE_OPENSSL
-static void https_add_ssl_entries(connection *con) {
- X509 *xs;
- X509_NAME *xn;
- X509_NAME_ENTRY *xe;
- if (
- SSL_get_verify_result(con->sock->ssl) != X509_V_OK
- || !(xs = SSL_get_peer_certificate(con->sock->ssl))
- ) {
- return;
- }
-
- xn = X509_get_subject_name(xs);
- for (int i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
- int xobjnid;
- const char * xobjsn;
- data_string *envds;
-
- if (!(xe = X509_NAME_get_entry(xn, i))) {
- continue;
- }
- xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
- xobjsn = OBJ_nid2sn(xobjnid);
- if (!xobjsn) {
- continue;
- }
-
- if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
- envds = data_string_init();
- }
- buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
- buffer_append_string(envds->key, xobjsn);
- buffer_copy_string_len(
- envds->value,
- (const char *)xe->value->data, xe->value->length
- );
- /* pick one of the exported values as "authed user", for example
- * ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID" or "SSL_CLIENT_S_DN_emailAddress"
- */
- if (buffer_is_equal(con->conf.ssl_verifyclient_username, envds->key)) {
- buffer_copy_string_buffer(con->authed_user, envds->value);
- }
- array_insert_unique(con->environment, (data_unset *)envds);
- }
- if (con->conf.ssl_verifyclient_export_cert) {
- BIO *bio;
- if (NULL != (bio = BIO_new(BIO_s_mem()))) {
- data_string *envds;
- int n;
-
- PEM_write_bio_X509(bio, xs);
- n = BIO_pending(bio);
-
- if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
- envds = data_string_init();
- }
-
- buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
- buffer_prepare_copy(envds->value, n+1);
- BIO_read(bio, envds->value->ptr, n);
- BIO_free(bio);
- envds->value->ptr[n] = '\0';
- envds->value->used = n+1;
- array_insert_unique(con->environment, (data_unset *)envds);
- }
- }
- X509_free(xs);
-}
-#endif
-
-
-handler_t handle_get_backend(server *srv, connection *con) {
- handler_t r;
-
- /* looks like someone has already made a decision */
- if (con->mode == DIRECT &&
- (con->http_status != 0 && con->http_status != 200)) {
- /* remove a packets in the queue */
-
- return HANDLER_FINISHED;
- }
-
- /* no decision yet, build conf->filename */
- if (con->mode == DIRECT && con->physical.path->used == 0) {
- char *qstr;
-
- /* we only come here when we have to parse the full request again
- *
- * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a
- * problem here as mod_setenv might get called multiple times
- *
- * fastcgi-auth might lead to a COMEBACK too
- * fastcgi again dead server too
- *
- * mod_compress might add headers twice too
- *
- * */
-
- if (con->conf.log_condition_handling) {
- TRACE("run condition: %s", "");
- }
- config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */
-
- /**
- * prepare strings
- *
- * - uri.path_raw
- * - uri.path (secure)
- * - uri.query
- *
- */
-
- /**
- * Name according to RFC 2396
- *
- * - scheme
- * - authority
- * - path
- * - query
- *
- * (scheme)://(authority)(path)?(query)#fragment
- *
- *
- */
-
- if (con->conf.is_ssl) {
- buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https"));
- } else {
- buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
- }
- buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
- buffer_to_lower(con->uri.authority);
-
- config_patch_connection(srv, con, COMP_HTTP_SCHEME); /* Scheme: */
- config_patch_connection(srv, con, COMP_HTTP_HOST); /* Host: */
- config_patch_connection(srv, con, COMP_HTTP_REMOTE_IP); /* Client-IP */
- config_patch_connection(srv, con, COMP_HTTP_REFERER); /* Referer: */
- config_patch_connection(srv, con, COMP_HTTP_USER_AGENT);/* User-Agent: */
- config_patch_connection(srv, con, COMP_HTTP_COOKIE); /* Cookie: */
- config_patch_connection(srv, con, COMP_HTTP_REQUEST_METHOD); /* REQUEST_METHOD */
-
- /** their might be a fragment which has to be cut away */
- if (NULL != (qstr = strchr(con->request.uri->ptr, '#'))) {
- con->request.uri->used = qstr - con->request.uri->ptr;
- con->request.uri->ptr[con->request.uri->used++] = '\0';
- }
-
- /** extract query string from request.uri */
- if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) {
- buffer_copy_string (con->uri.query, qstr + 1);
- buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr);
- } else {
- buffer_reset (con->uri.query);
- buffer_copy_string_buffer(con->uri.path_raw, con->request.uri);
- }
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "splitting Request-URI");
- TRACE("Request-URI : %s", SAFE_BUF_STR(con->request.uri));
- TRACE("URI-scheme : %s", SAFE_BUF_STR(con->uri.scheme));
- TRACE("URI-authority: %s", SAFE_BUF_STR(con->uri.authority));
- TRACE("URI-path : %s", SAFE_BUF_STR(con->uri.path_raw));
- TRACE("URI-query : %s", SAFE_BUF_STR(con->uri.query));
- }
-
- if (srv->sockets_disabled) {
- con->keep_alive = 0;
- }
-
-
- /**
- *
- * call plugins
- *
- * - based on the raw URL
- *
- */
-
- switch(r = plugins_call_handle_uri_raw(srv, con)) {
- case HANDLER_GO_ON:
- break;
- case HANDLER_FINISHED:
- case HANDLER_COMEBACK:
- case HANDLER_WAIT_FOR_EVENT:
- case HANDLER_ERROR:
- return r;
- default:
- ERROR("plugins_call_handle_uri_raw() returned unexpected: %d", r);
- break;
- }
-
- /* build filename
- *
- * - decode url-encodings (e.g. %20 -> ' ')
- * - remove path-modifiers (e.g. /../)
- */
-
-
-
- if (con->request.http_method == HTTP_METHOD_OPTIONS &&
- con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
- /* OPTIONS * ... */
- buffer_copy_string_buffer(con->uri.path, con->uri.path_raw);
- } else {
- buffer_copy_string_buffer(srv->tmp_buf, con->uri.path_raw);
- buffer_urldecode_path(srv->tmp_buf);
- buffer_path_simplify(con->uri.path, srv->tmp_buf);
- }
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "sanitizing URI");
- TRACE("URI-path : %s", SAFE_BUF_STR(con->uri.path));
- }
-
-#ifdef USE_OPENSSL
- if (con->conf.is_ssl && con->conf.ssl_verifyclient) {
- https_add_ssl_entries(con);
- }
-#endif
-
- /**
- *
- * call plugins
- *
- * - based on the clean URL
- *
- */
-
- config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
- config_patch_connection(srv, con, COMP_HTTP_QUERY_STRING); /* HTTPqs */
-
- /* do we have to downgrade to 1.0 ? */
- if (!con->conf.allow_http11) {
- con->request.http_version = HTTP_VERSION_1_0;
- }
-
- switch(r = plugins_call_handle_uri_clean(srv, con)) {
- case HANDLER_GO_ON:
- break;
- case HANDLER_FINISHED:
- case HANDLER_COMEBACK:
- case HANDLER_WAIT_FOR_EVENT:
- case HANDLER_ERROR:
- return r;
- default:
- ERROR("plugins_call_handle_uri_clean() returned unexpected: %d", r);
- break;
- }
-
- if (con->request.http_method == HTTP_METHOD_OPTIONS &&
- con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
- /* option requests are handled directly without checking the path */
-
- response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
-
- con->http_status = 200;
- /* no more content to send */
- con->send->is_closed = 1;
-
- return HANDLER_FINISHED;
- }
-
- /***
- *
- * border
- *
- * logical filename (URI) becomes a physical filename here
- *
- *
- *
- */
-
-
-
-
- /* 1. stat()
- * ... ISREG() -> ok, go on
- * ... ISDIR() -> index-file -> redirect
- *
- * 2. pathinfo()
- * ... ISREG()
- *
- * 3. -> 404
- *
- */
-
- /*
- * SEARCH DOCUMENT ROOT
- */
-
- /* set a default */
-
- buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
- buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
-
- filename_unix2local(con->physical.rel_path);
-#if defined(_WIN32) || defined(__CYGWIN__)
- /* strip dots and spaces from the end
- *
- * windows/dos handle those filenames as the same file
- *
- * foo == foo. == foo..... == "foo... " == "foo.. ./"
- *
- * This will affect PATHINFO in some cases
- *
- * on native windows we could prepend the filename with \\?\ to circumvent
- * this behaviour. I have no idea how to push this through cygwin
- *
- * */
-
- if (con->physical.rel_path->used > 1) {
- buffer *b = con->physical.rel_path;
- size_t i;
-
- if (b->used > 2 &&
- b->ptr[b->used-2] == '/' &&
- (b->ptr[b->used-3] == ' ' ||
- b->ptr[b->used-3] == '.')) {
- b->ptr[b->used--] = '\0';
- }
-
- for (i = b->used - 2; b->used > 1; i--) {
- if (b->ptr[i] == ' ' ||
- b->ptr[i] == '.') {
- b->ptr[b->used--] = '\0';
- } else {
- break;
- }
- }
- }
-#endif
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "before doc_root");
- TRACE("Doc-Root : %s", SAFE_BUF_STR(con->physical.doc_root));
- TRACE("Rel-Path : %s", SAFE_BUF_STR(con->physical.rel_path));
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
- /* the docroot plugin should set the doc_root and might also set the physical.path
- * for us (all vhost-plugins are supposed to set the doc_root)
- * */
- switch(r = plugins_call_handle_docroot(srv, con)) {
- case HANDLER_GO_ON:
- break;
- case HANDLER_FINISHED:
- case HANDLER_COMEBACK:
- case HANDLER_WAIT_FOR_EVENT:
- case HANDLER_ERROR:
- return r;
- default:
- ERROR("plugins_call_handle_docroot() returned unexpected: %d", r);
- break;
- }
-
- /* The default Mac OS X and Windows filesystems can't distiguish between
- * upper- and lowercase, so convert to lowercase
- */
- if (con->conf.force_lowercase_filenames) {
- buffer_to_lower(con->physical.rel_path);
- }
-
- /* the docroot plugins might set the servername; if they don't we take http-host */
- if (buffer_is_empty(con->server_name)) {
- buffer_copy_string_buffer(con->server_name, con->uri.authority);
- }
-
- /**
- * create physical filename
- * -> physical.path = docroot + rel_path
- *
- */
-
- buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
- PATHNAME_APPEND_SLASH(con->physical.path);
- buffer_copy_string_buffer(con->physical.basedir, con->physical.path);
- if (con->physical.rel_path->used &&
- con->physical.rel_path->ptr[0] == DIR_SEPERATOR) {
- buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
- } else {
- buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
- }
-
- /* win32: directories can't have a trailing slash */
- if (con->physical.path->ptr[con->physical.path->used - 2] == DIR_SEPERATOR) {
- con->physical.path->ptr[con->physical.path->used - 2] = '\0';
- con->physical.path->used--;
- }
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "after doc_root");
- TRACE("Doc-Root : %s", SAFE_BUF_STR(con->physical.doc_root));
- TRACE("Rel-Path : %s", SAFE_BUF_STR(con->physical.rel_path));
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
- switch(r = plugins_call_handle_physical(srv, con)) {
- case HANDLER_GO_ON:
- break;
- case HANDLER_FINISHED:
- case HANDLER_COMEBACK:
- case HANDLER_WAIT_FOR_EVENT:
- case HANDLER_ERROR:
- return r;
- default:
- ERROR("plugins_call_handle_physical() returned unexpected: %d", r);
- break;
- }
-
- config_patch_connection(srv, con, COMP_PHYSICAL_PATH); /* physical-path */
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "logical -> physical");
- TRACE("Doc-Root : %s", SAFE_BUF_STR(con->physical.doc_root));
- TRACE("Rel-Path : %s", SAFE_BUF_STR(con->physical.rel_path));
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
- }
-
- /*
- * No one took the file away from the normal path of execution yet (like mod_access)
- *
- * we don't have a backend yet, try to resolve the physical path and go on
- *
- */
-
- if (con->mode == DIRECT) {
- char *slash = NULL;
- char *pathinfo = NULL;
- int found = 0;
- stat_cache_entry *sce = NULL;
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "handling physical path");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
- switch ((r = stat_cache_get_entry_async(srv, con, con->physical.path, &sce))) {
- case HANDLER_GO_ON:
- /* file exists */
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "file found");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
-#ifdef HAVE_LSTAT
- if ((sce->is_symlink != 0) && !con->conf.follow_symlink) {
- con->http_status = 403;
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "access denied due symlink restriction");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
- buffer_reset(con->physical.path);
- return HANDLER_FINISHED;
- };
-#endif
-
- if (S_ISDIR(sce->st.st_mode)) {
- if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
- /* redirect to .../ */
-
- http_response_redirect_to_directory(srv, con);
-
- return HANDLER_FINISHED;
- }
-#ifdef HAVE_LSTAT
- } else if (!S_ISREG(sce->st.st_mode) && !sce->is_symlink) {
-#else
- } else if (!S_ISREG(sce->st.st_mode)) {
-#endif
- /* any special handling of non-reg files ?*/
-
-
- }
- break;
- case HANDLER_WAIT_FOR_EVENT:
- return HANDLER_WAIT_FOR_EVENT;
- case HANDLER_ERROR:
- switch (errno) {
- case EACCES:
- con->http_status = 403;
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "access denied");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
- buffer_reset(con->physical.path);
- return HANDLER_FINISHED;
- case ENOENT:
- con->http_status = 404;
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "file not found");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
- buffer_reset(con->physical.path);
- return HANDLER_FINISHED;
- case ENOTDIR:
- /* PATH_INFO ! :) */
- break;
- case EMFILE:
- return HANDLER_WAIT_FOR_FD;
- default:
- /* we have no idea what happened, so tell the user. */
- con->http_status = 500;
-
- ERROR("checking file '%s' (%s) failed: %d (%s) -> sending status 500",
- SAFE_BUF_STR(con->uri.path),
- SAFE_BUF_STR(con->physical.path),
- errno, strerror(errno));
-
- buffer_reset(con->physical.path);
-
- return HANDLER_FINISHED;
- }
-
- /* not found, perhaps PATHINFO */
-
- buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
-
- do {
- if (slash) {
- buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
- } else {
- buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
- }
-
- if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
- found = S_ISREG(sce->st.st_mode);
- break;
- }
-
- if (pathinfo != NULL) {
- *pathinfo = '\0';
- }
- slash = strrchr(srv->tmp_buf->ptr, '/');
-
- if (pathinfo != NULL) {
- /* restore '/' */
- *pathinfo = '/';
- }
-
- if (slash) pathinfo = slash;
- } while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (con->physical.basedir->used - 2)));
-
- if (found == 0) {
- /* no, it really doesn't exists */
- con->http_status = 404;
-
- if (con->conf.log_file_not_found) {
- TRACE("file not found: %s -> %s",
- SAFE_BUF_STR(con->uri.path),
- SAFE_BUF_STR(con->physical.path));
- }
-
- buffer_reset(con->physical.path);
-
- return HANDLER_FINISHED;
- }
-
-#ifdef HAVE_LSTAT
- if ((sce->is_symlink != 0) && !con->conf.follow_symlink) {
- con->http_status = 403;
-
- if (con->conf.log_request_handling) {
- log_error_write(srv, __FILE__, __LINE__, "s", "-- access denied due symlink restriction");
- log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
- }
-
- buffer_reset(con->physical.path);
- return HANDLER_FINISHED;
- };
-#endif
-
- /* we have a PATHINFO */
- if (pathinfo) {
- buffer_copy_string(con->request.pathinfo, pathinfo);
-
- /*
- * shorten uri.path
- */
-
- con->uri.path->used -= strlen(pathinfo);
- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
- }
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "after pathinfo check");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- TRACE("URI : %s", SAFE_BUF_STR(con->uri.path));
- TRACE("Pathinfo : %s", SAFE_BUF_STR(con->request.pathinfo));
- }
- break;
- default:
- ERROR("stat_cache_get_entry_async() returned unexpected: %d", r);
- break;
- }
-
- config_patch_connection(srv, con, COMP_PHYSICAL_PATH_EXISTS); /* physical-path */
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "handling subrequest");
- TRACE("Path : %s", SAFE_BUF_STR(con->physical.path));
- }
-
- /* call the handlers */
- switch(r = plugins_call_handle_start_backend(srv, con)) {
- case HANDLER_GO_ON:
- break;
- case HANDLER_FINISHED:
- case HANDLER_COMEBACK:
- case HANDLER_WAIT_FOR_EVENT:
- case HANDLER_ERROR:
- return r;
-
- default:
- ERROR("plugins_call_handle_start_backend() returned unexpected: %d", r);
- return r;
- }
-
- if (con->conf.log_request_handling) {
- TRACE("-- %s", "subrequest finished");
- }
- }
-
- if (con->mode == DIRECT) {
- /* if we are still here, no one wanted the file; status 403 is ok I think */
- con->http_status = 403;
-
- if (con->conf.log_request_handling) {
- TRACE("%s", "aaaaaaah, sending 403");
- }
-
- return HANDLER_FINISHED;
- } else {
- return HANDLER_GO_ON;
- }
-}
-
-
-