|
|
| version 1.1, 2013/10/14 10:32:47 | version 1.1.1.3, 2016/11/02 10:35:00 |
|---|---|
| Line 1 | Line 1 |
| #include "first.h" | |
| #include "response.h" | #include "response.h" |
| #include "keyvalue.h" | #include "keyvalue.h" |
| #include "log.h" | #include "log.h" |
| Line 5 | Line 7 |
| #include "chunk.h" | #include "chunk.h" |
| #include "configfile.h" | #include "configfile.h" |
| #include "connections.h" | |
| #include "plugin.h" | #include "plugin.h" |
| Line 25 | Line 26 |
| #include <stdio.h> | #include <stdio.h> |
| #include "sys-socket.h" | #include "sys-socket.h" |
| #include "version.h" | |
| int http_response_write_header(server *srv, connection *con) { | int http_response_write_header(server *srv, connection *con) { |
| buffer *b; | buffer *b; |
| Line 33 int http_response_write_header(server *srv, connection | Line 33 int http_response_write_header(server *srv, connection |
| int have_date = 0; | int have_date = 0; |
| int have_server = 0; | int have_server = 0; |
| b = chunkqueue_get_prepend_buffer(con->write_queue); | b = buffer_init(); |
| if (con->request.http_version == HTTP_VERSION_1_1) { | if (con->request.http_version == HTTP_VERSION_1_1) { |
| buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 ")); | buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 ")); |
| } else { | } else { |
| buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 ")); | buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 ")); |
| } | } |
| buffer_append_long(b, con->http_status); | buffer_append_int(b, con->http_status); |
| buffer_append_string_len(b, CONST_STR_LEN(" ")); | buffer_append_string_len(b, CONST_STR_LEN(" ")); |
| buffer_append_string(b, get_http_status_name(con->http_status)); | buffer_append_string(b, get_http_status_name(con->http_status)); |
| Line 70 int http_response_write_header(server *srv, connection | Line 70 int http_response_write_header(server *srv, connection |
| ds = (data_string *)con->response.headers->data[i]; | ds = (data_string *)con->response.headers->data[i]; |
| if (ds->value->used && ds->key->used && | if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key) && |
| 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) && | 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) && |
| 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-Sendfile"))) { | 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-Sendfile"))) { |
| if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1; | if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1; |
| Line 97 int http_response_write_header(server *srv, connection | Line 97 int http_response_write_header(server *srv, connection |
| /* cache the generated timestamp */ | /* cache the generated timestamp */ |
| if (srv->cur_ts != srv->last_generated_date_ts) { | if (srv->cur_ts != srv->last_generated_date_ts) { |
| buffer_prepare_copy(srv->ts_date_str, 255); | buffer_string_prepare_copy(srv->ts_date_str, 255); |
| strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1, | buffer_append_strftime(srv->ts_date_str, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts))); |
| "%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; | srv->last_generated_date_ts = srv->cur_ts; |
| } | } |
| Line 111 int http_response_write_header(server *srv, connection | Line 108 int http_response_write_header(server *srv, connection |
| } | } |
| if (!have_server) { | if (!have_server) { |
| if (buffer_is_empty(con->conf.server_tag)) { | if (!buffer_string_is_empty(con->conf.server_tag)) { |
| buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_DESC)); | |
| } else if (con->conf.server_tag->used > 1) { | |
| buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: ")); | buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: ")); |
| buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER); | buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER); |
| } | } |
| Line 121 int http_response_write_header(server *srv, connection | Line 116 int http_response_write_header(server *srv, connection |
| buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); | buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); |
| con->bytes_header = buffer_string_length(b); | |
| con->bytes_header = b->used - 1; | |
| if (con->conf.log_response_header) { | if (con->conf.log_response_header) { |
| log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b); | log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b); |
| } | } |
| chunkqueue_prepend_buffer(con->write_queue, b); | |
| buffer_free(b); | |
| return 0; | return 0; |
| } | } |
| Line 167 static void https_add_ssl_entries(connection *con) { | Line 164 static void https_add_ssl_entries(connection *con) { |
| buffer_append_string(envds->key, xobjsn); | buffer_append_string(envds->key, xobjsn); |
| buffer_copy_string_len( | buffer_copy_string_len( |
| envds->value, | envds->value, |
| (const char *)xe->value->data, xe->value->length | (const char *)X509_NAME_ENTRY_get_data(xe)->data, |
| X509_NAME_ENTRY_get_data(xe)->length | |
| ); | ); |
| /* pick one of the exported values as "REMOTE_USER", for example | /* pick one of the exported values as "REMOTE_USER", for example |
| * ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID" or "SSL_CLIENT_S_DN_emailAddress" | * ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID" or "SSL_CLIENT_S_DN_emailAddress" |
| Line 181 static void https_add_ssl_entries(connection *con) { | Line 179 static void https_add_ssl_entries(connection *con) { |
| buffer_copy_string(ds->key, "REMOTE_USER"); | buffer_copy_string(ds->key, "REMOTE_USER"); |
| array_insert_unique(con->environment, (data_unset *)ds); | array_insert_unique(con->environment, (data_unset *)ds); |
| } | } |
| buffer_copy_string_buffer(ds->value, envds->value); | buffer_copy_buffer(ds->value, envds->value); |
| } | } |
| array_insert_unique(con->environment, (data_unset *)envds); | array_insert_unique(con->environment, (data_unset *)envds); |
| } | } |
| Line 199 static void https_add_ssl_entries(connection *con) { | Line 197 static void https_add_ssl_entries(connection *con) { |
| } | } |
| buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT")); | buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT")); |
| buffer_prepare_copy(envds->value, n+1); | buffer_string_prepare_copy(envds->value, n); |
| BIO_read(bio, envds->value->ptr, n); | BIO_read(bio, envds->value->ptr, n); |
| BIO_free(bio); | BIO_free(bio); |
| envds->value->ptr[n] = '\0'; | buffer_commit(envds->value, n); |
| envds->value->used = n+1; | |
| array_insert_unique(con->environment, (data_unset *)envds); | array_insert_unique(con->environment, (data_unset *)envds); |
| } | } |
| } | } |
| Line 227 handler_t http_response_prepare(server *srv, connectio | Line 224 handler_t http_response_prepare(server *srv, connectio |
| } | } |
| /* no decision yet, build conf->filename */ | /* no decision yet, build conf->filename */ |
| if (con->mode == DIRECT && con->physical.path->used == 0) { | if (con->mode == DIRECT && buffer_is_empty(con->physical.path)) { |
| char *qstr; | char *qstr; |
| /* we only come here when we have the parse the full request again | /* we only come here when we have the parse the full request again |
| Line 248 handler_t http_response_prepare(server *srv, connectio | Line 245 handler_t http_response_prepare(server *srv, connectio |
| if (con->conf.log_condition_handling) { | if (con->conf.log_condition_handling) { |
| log_error_write(srv, __FILE__, __LINE__, "s", "run condition"); | log_error_write(srv, __FILE__, __LINE__, "s", "run condition"); |
| } | } |
| config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */ | |
| /** | /** |
| * prepare strings | * prepare strings |
| Line 278 handler_t http_response_prepare(server *srv, connectio | Line 274 handler_t http_response_prepare(server *srv, connectio |
| } else { | } else { |
| buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http")); | buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http")); |
| } | } |
| buffer_copy_string_buffer(con->uri.authority, con->request.http_host); | buffer_copy_buffer(con->uri.authority, con->request.http_host); |
| buffer_to_lower(con->uri.authority); | 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_LANGUAGE); /* Accept-Language: */ | |
| 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 */ | /** their might be a fragment which has to be cut away */ |
| if (NULL != (qstr = strchr(con->request.uri->ptr, '#'))) { | if (NULL != (qstr = strchr(con->request.uri->ptr, '#'))) { |
| con->request.uri->used = qstr - con->request.uri->ptr; | buffer_string_set_length(con->request.uri, qstr - con->request.uri->ptr); |
| con->request.uri->ptr[con->request.uri->used++] = '\0'; | |
| } | } |
| /** extract query string from request.uri */ | /** extract query string from request.uri */ |
| Line 302 handler_t http_response_prepare(server *srv, connectio | Line 288 handler_t http_response_prepare(server *srv, connectio |
| buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr); | buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr); |
| } else { | } else { |
| buffer_reset (con->uri.query); | buffer_reset (con->uri.query); |
| buffer_copy_string_buffer(con->uri.path_raw, con->request.uri); | buffer_copy_buffer(con->uri.path_raw, con->request.uri); |
| } | } |
| /* decode url to path | |
| * | |
| * - 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_buffer(con->uri.path, con->uri.path_raw); | |
| } else { | |
| buffer_copy_buffer(srv->tmp_buf, con->uri.path_raw); | |
| buffer_urldecode_path(srv->tmp_buf); | |
| buffer_path_simplify(con->uri.path, srv->tmp_buf); | |
| } | |
| con->conditional_is_valid[COMP_SERVER_SOCKET] = 1; /* SERVERsocket */ | |
| con->conditional_is_valid[COMP_HTTP_SCHEME] = 1; /* Scheme: */ | |
| con->conditional_is_valid[COMP_HTTP_HOST] = 1; /* Host: */ | |
| con->conditional_is_valid[COMP_HTTP_REMOTE_IP] = 1; /* Client-IP */ | |
| con->conditional_is_valid[COMP_HTTP_REFERER] = 1; /* Referer: */ | |
| con->conditional_is_valid[COMP_HTTP_USER_AGENT] = /* User-Agent: */ | |
| con->conditional_is_valid[COMP_HTTP_LANGUAGE] = 1; /* Accept-Language: */ | |
| con->conditional_is_valid[COMP_HTTP_COOKIE] = 1; /* Cookie: */ | |
| con->conditional_is_valid[COMP_HTTP_REQUEST_METHOD] = 1; /* REQUEST_METHOD */ | |
| con->conditional_is_valid[COMP_HTTP_URL] = 1; /* HTTPurl */ | |
| con->conditional_is_valid[COMP_HTTP_QUERY_STRING] = 1; /* HTTPqs */ | |
| config_patch_connection(srv, con); | |
| #ifdef USE_OPENSSL | |
| if (con->srv_socket->is_ssl && con->conf.ssl_verifyclient) { | |
| https_add_ssl_entries(con); | |
| } | |
| #endif | |
| /* do we have to downgrade to 1.0 ? */ | |
| if (!con->conf.allow_http11) { | |
| con->request.http_version = HTTP_VERSION_1_0; | |
| } | |
| if (con->conf.log_request_handling) { | if (con->conf.log_request_handling) { |
| log_error_write(srv, __FILE__, __LINE__, "s", "-- splitting Request-URI"); | log_error_write(srv, __FILE__, __LINE__, "s", "-- splitting Request-URI"); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "Request-URI : ", con->request.uri); | log_error_write(srv, __FILE__, __LINE__, "sb", "Request-URI : ", con->request.uri); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "URI-scheme : ", con->uri.scheme); | log_error_write(srv, __FILE__, __LINE__, "sb", "URI-scheme : ", con->uri.scheme); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "URI-authority: ", con->uri.authority); | log_error_write(srv, __FILE__, __LINE__, "sb", "URI-authority : ", con->uri.authority); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path_raw); | log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path (raw) : ", con->uri.path_raw); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "URI-query : ", con->uri.query); | log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path (clean): ", con->uri.path); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "URI-query : ", con->uri.query); | |
| } | } |
| /* con->conf.max_request_size is in kBytes */ | |
| if (0 != con->conf.max_request_size && | |
| (off_t)con->request.content_length > ((off_t)con->conf.max_request_size << 10)) { | |
| log_error_write(srv, __FILE__, __LINE__, "sos", | |
| "request-size too long:", (off_t) con->request.content_length, "-> 413"); | |
| con->keep_alive = 0; | |
| con->http_status = 413; | |
| con->file_finished = 1; | |
| return HANDLER_FINISHED; | |
| } | |
| /** | /** |
| * | * |
| * call plugins | * call plugins |
| Line 336 handler_t http_response_prepare(server *srv, connectio | Line 375 handler_t http_response_prepare(server *srv, connectio |
| break; | 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) { | |
| log_error_write(srv, __FILE__, __LINE__, "s", "-- sanatising URI"); | |
| log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path); | |
| } | |
| #ifdef USE_OPENSSL | |
| if (con->srv_socket->is_ssl && con->conf.ssl_verifyclient) { | |
| https_add_ssl_entries(con); | |
| } | |
| #endif | |
| /** | /** |
| * | * |
| * call plugins | * call plugins |
| Line 373 handler_t http_response_prepare(server *srv, connectio | Line 383 handler_t http_response_prepare(server *srv, connectio |
| * | * |
| */ | */ |
| 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)) { | switch(r = plugins_call_handle_uri_clean(srv, con)) { |
| case HANDLER_GO_ON: | case HANDLER_GO_ON: |
| break; | break; |
| Line 436 handler_t http_response_prepare(server *srv, connectio | Line 438 handler_t http_response_prepare(server *srv, connectio |
| /* set a default */ | /* set a default */ |
| buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root); | buffer_copy_buffer(con->physical.doc_root, con->conf.document_root); |
| buffer_copy_string_buffer(con->physical.rel_path, con->uri.path); | buffer_copy_buffer(con->physical.rel_path, con->uri.path); |
| #if defined(__WIN32) || defined(__CYGWIN__) | #if defined(__WIN32) || defined(__CYGWIN__) |
| /* strip dots from the end and spaces | /* strip dots from the end and spaces |
| Line 455 handler_t http_response_prepare(server *srv, connectio | Line 457 handler_t http_response_prepare(server *srv, connectio |
| if (con->physical.rel_path->used > 1) { | if (con->physical.rel_path->used > 1) { |
| buffer *b = con->physical.rel_path; | buffer *b = con->physical.rel_path; |
| size_t i; | size_t len = buffer_string_length(b); |
| if (b->used > 2 && | /* strip trailing " /" or "./" once */ |
| b->ptr[b->used-2] == '/' && | if (len > 1 && |
| (b->ptr[b->used-3] == ' ' || | b->ptr[len - 1] == '/' && |
| b->ptr[b->used-3] == '.')) { | (b->ptr[len - 2] == ' ' || b->ptr[len - 2] == '.')) { |
| b->ptr[b->used--] = '\0'; | len -= 2; |
| } | } |
| /* strip all trailing " " and "." */ | |
| for (i = b->used - 2; b->used > 1; i--) { | while (len > 0 && ( ' ' == b->ptr[len-1] || '.' == b->ptr[len-1] ) ) --len; |
| if (b->ptr[i] == ' ' || | buffer_string_set_length(b, len); |
| b->ptr[i] == '.') { | |
| b->ptr[b->used--] = '\0'; | |
| } else { | |
| break; | |
| } | |
| } | |
| } | } |
| #endif | #endif |
| Line 506 handler_t http_response_prepare(server *srv, connectio | Line 502 handler_t http_response_prepare(server *srv, connectio |
| } | } |
| /* the docroot plugins might set the servername, if they don't we take http-host */ | /* the docroot plugins might set the servername, if they don't we take http-host */ |
| if (buffer_is_empty(con->server_name)) { | if (buffer_string_is_empty(con->server_name)) { |
| buffer_copy_string_buffer(con->server_name, con->uri.authority); | buffer_copy_buffer(con->server_name, con->uri.authority); |
| } | } |
| /** | /** |
| Line 516 handler_t http_response_prepare(server *srv, connectio | Line 512 handler_t http_response_prepare(server *srv, connectio |
| * | * |
| */ | */ |
| buffer_copy_string_buffer(con->physical.path, con->physical.doc_root); | buffer_copy_buffer(con->physical.basedir, con->physical.doc_root); |
| buffer_copy_string_buffer(con->physical.basedir, con->physical.path); | buffer_copy_buffer(con->physical.path, con->physical.doc_root); |
| BUFFER_APPEND_SLASH(con->physical.path); | buffer_append_slash(con->physical.path); |
| if (con->physical.rel_path->used && | if (!buffer_string_is_empty(con->physical.rel_path) && |
| con->physical.rel_path->ptr[0] == '/') { | con->physical.rel_path->ptr[0] == '/') { |
| buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2); | buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, buffer_string_length(con->physical.rel_path) - 1); |
| } else { | } else { |
| buffer_append_string_buffer(con->physical.path, con->physical.rel_path); | buffer_append_string_buffer(con->physical.path, con->physical.rel_path); |
| } | } |
| Line 549 handler_t http_response_prepare(server *srv, connectio | Line 545 handler_t http_response_prepare(server *srv, connectio |
| if (con->conf.log_request_handling) { | if (con->conf.log_request_handling) { |
| log_error_write(srv, __FILE__, __LINE__, "s", "-- logical -> physical"); | log_error_write(srv, __FILE__, __LINE__, "s", "-- logical -> physical"); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); | log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "Basedir :", con->physical.basedir); | |
| log_error_write(srv, __FILE__, __LINE__, "sb", "Rel-Path :", con->physical.rel_path); | log_error_write(srv, __FILE__, __LINE__, "sb", "Rel-Path :", con->physical.rel_path); |
| log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); |
| } | } |
| Line 592 handler_t http_response_prepare(server *srv, connectio | Line 589 handler_t http_response_prepare(server *srv, connectio |
| }; | }; |
| #endif | #endif |
| if (S_ISDIR(sce->st.st_mode)) { | if (S_ISDIR(sce->st.st_mode)) { |
| if (con->uri.path->ptr[con->uri.path->used - 2] != '/') { | if (con->uri.path->ptr[buffer_string_length(con->uri.path) - 1] != '/') { |
| /* redirect to .../ */ | /* redirect to .../ */ |
| http_response_redirect_to_directory(srv, con); | http_response_redirect_to_directory(srv, con); |
| Line 650 handler_t http_response_prepare(server *srv, connectio | Line 647 handler_t http_response_prepare(server *srv, connectio |
| /* not found, perhaps PATHINFO */ | /* not found, perhaps PATHINFO */ |
| buffer_copy_string_buffer(srv->tmp_buf, con->physical.path); | buffer_copy_buffer(srv->tmp_buf, con->physical.path); |
| do { | do { |
| if (slash) { | if (slash) { |
| buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr); | buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr); |
| } else { | } else { |
| buffer_copy_string_buffer(con->physical.path, srv->tmp_buf); | buffer_copy_buffer(con->physical.path, srv->tmp_buf); |
| } | } |
| if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { |
| Line 675 handler_t http_response_prepare(server *srv, connectio | Line 672 handler_t http_response_prepare(server *srv, connectio |
| } | } |
| if (slash) pathinfo = slash; | if (slash) pathinfo = slash; |
| } while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (con->physical.basedir->used - 2))); | } while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (buffer_string_length(con->physical.basedir) - 1))); |
| if (found == 0) { | if (found == 0) { |
| /* no it really doesn't exists */ | /* no it really doesn't exists */ |
| Line 708 handler_t http_response_prepare(server *srv, connectio | Line 705 handler_t http_response_prepare(server *srv, connectio |
| /* we have a PATHINFO */ | /* we have a PATHINFO */ |
| if (pathinfo) { | if (pathinfo) { |
| buffer_copy_string(con->request.pathinfo, pathinfo); | size_t len = strlen(pathinfo), reqlen; |
| if (con->conf.force_lowercase_filenames | |
| && len <= (reqlen = buffer_string_length(con->request.uri)) | |
| && 0 == strncasecmp(con->request.uri->ptr + reqlen - len, pathinfo, len)) { | |
| /* attempt to preserve case-insensitive PATH_INFO | |
| * (works in common case where mod_alias, mod_magnet, and other modules | |
| * have not modified the PATH_INFO portion of request URI, or did so | |
| * with exactly the PATH_INFO desired) */ | |
| buffer_copy_string_len(con->request.pathinfo, con->request.uri->ptr + reqlen - len, len); | |
| } else { | |
| buffer_copy_string_len(con->request.pathinfo, pathinfo, len); | |
| } | |
| /* | /* |
| * shorten uri.path | * shorten uri.path |
| */ | */ |
| con->uri.path->used -= strlen(pathinfo); | buffer_string_set_length(con->uri.path, buffer_string_length(con->uri.path) - len); |
| con->uri.path->ptr[con->uri.path->used - 1] = '\0'; | |
| } | } |
| if (con->conf.log_request_handling) { | if (con->conf.log_request_handling) { |