-/* ====================================================================
- * The Apache Software License, Version 1.1
+/* Copyright 2001-2004 The Apache Software Foundation
*
- * Copyright (c) 2000-2004 The Apache Software Foundation. All rights
- * reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * Portions of this software are based upon public domain software
- * originally written at the National Center for Supercomputing Applications,
- * University of Illinois, Urbana-Champaign.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
/*
/* Would this overrun our buffer? If so, we'll die. */
if (n < bytes_handled + len) {
*read = bytes_handled;
+ if (*s) {
+ /* ensure this string is NUL terminated */
+ if (bytes_handled > 0) {
+ (*s)[bytes_handled-1] = '\0';
+ }
+ else {
+ (*s)[0] = '\0';
+ }
+ }
return APR_ENOSPC;
}
/* Do we have enough space? We may be full now. */
if (bytes_handled >= n) {
*read = n;
+ /* ensure this string is terminated */
+ (*s)[n-1] = '\0';
return APR_ENOSPC;
}
else {
*s = new_buffer;
}
+ last_char += next_len;
bytes_handled += next_len;
}
}
* if there are empty lines
*/
r->the_request = NULL;
- rv = ap_rgetline(&(r->the_request), DEFAULT_LIMIT_REQUEST_LINE + 2,
+ rv = ap_rgetline(&(r->the_request), (apr_size_t)(r->server->limit_req_line + 2),
&len, r, 0, bb);
if (rv != APR_SUCCESS) {
r->request_time = apr_time_now();
+
+ /* ap_rgetline returns APR_ENOSPC if it fills up the
+ * buffer before finding the end-of-line. This is only going to
+ * happen if it exceeds the configured limit for a request-line.
+ */
+ if (rv == APR_ENOSPC) {
+ r->status = HTTP_REQUEST_URI_TOO_LARGE;
+ r->proto_num = HTTP_VERSION(1,0);
+ r->protocol = apr_pstrdup(r->pool, "HTTP/1.0");
+ }
+
return 0;
}
} while ((len <= 0) && (++num_blank_lines < max_blank_lines));
ap_parse_uri(r, uri);
- /* ap_getline returns (size of max buffer - 1) if it fills up the
- * buffer before finding the end-of-line. This is only going to
- * happen if it exceeds the configured limit for a request-line.
- * The cast is safe, limit_req_line cannot be negative
- */
- if (len > (apr_size_t)r->server->limit_req_line) {
- r->status = HTTP_REQUEST_URI_TOO_LARGE;
- r->proto_num = HTTP_VERSION(1,0);
- r->protocol = apr_pstrdup(r->pool, "HTTP/1.0");
- return 0;
- }
-
if (ll[0]) {
r->assbackwards = 0;
pro = ll;
* continuations that span many many lines.
*/
apr_size_t fold_len = last_len + len + 1; /* trailing null */
+
+ if (fold_len > r->server->limit_req_fieldsize + 1) {
+ r->status = HTTP_BAD_REQUEST;
+ /* report what we have accumulated so far before the
+ * overflow (last_field) as the field with the problem
+ */
+ apr_table_setn(r->notes, "error-notes",
+ apr_pstrcat(r->pool,
+ "Size of a request header field "
+ "after folding "
+ "exceeds server limit.<br />\n"
+ "<pre>\n",
+ ap_escape_html(r->pool, last_field),
+ "</pre>\n", NULL));
+ return;
+ }
+
if (fold_len > alloc_len) {
char *fold_buf;
alloc_len += alloc_len;
if (!read_request_line(r, tmp_bb)) {
if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "request failed: URI too long");
+ "request failed: URI too long (longer than %d)", r->server->limit_req_line);
ap_send_error_response(r, 0);
ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
ap_run_log_transaction(r);
* *someone* has to set the protocol-specific fields...
*/
-void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
+AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew,
+ const request_rec *r)
{
rnew->the_request = r->the_request; /* Keep original request-line */
ap_pass_brigade(r->output_filters, bb);
}
-void ap_finalize_sub_req_protocol(request_rec *sub)
+AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub)
{
/* tell the filter chain there is no more content coming */
if (!sub->eos_sent) {
*
* We can only set a C-L in the response header if we haven't already
* sent any buckets on to the next output filter for this request.
+ *
+ * Also check against cases of zero bytes sent, to avoid a bogus
+ * C-L on HEAD requests, or no-body GETs like 204s.
*/
- if (ctx->data_sent == 0 && eos) {
+ if (ctx->data_sent == 0 && eos && r->bytes_sent > 0 ) {
ap_set_content_length(r, r->bytes_sent);
}
return c;
}
-AP_DECLARE(int) ap_rputs(const char *str, request_rec *r)
+AP_DECLARE(apr_ssize_t) ap_rputs(const char *str, request_rec *r)
{
apr_size_t len;
return APR_SUCCESS;
}
-AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
+AP_DECLARE(apr_ssize_t) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
{
- apr_size_t written;
+ apr_ssize_t written;
struct ap_vrprintf_data vd;
char vrprintf_buf[AP_IOBUFSIZE];
*(vd.vbuff.curpos) = '\0';
if (written != -1) {
- int n = vd.vbuff.curpos - vrprintf_buf;
+ apr_size_t n = vd.vbuff.curpos - vrprintf_buf;
/* last call to buffer_output, to finish clearing the buffer */
if (buffer_output(r, vrprintf_buf,n) != APR_SUCCESS)
return written;
}
-AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt, ...)
+AP_DECLARE_NONSTD(apr_ssize_t) ap_rprintf(request_rec *r, const char *fmt, ...)
{
va_list va;
- int n;
+ apr_ssize_t n;
if (r->connection->aborted)
return -1;
return n;
}
-AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r, ...)
+AP_DECLARE_NONSTD(apr_ssize_t) ap_rvputs(request_rec *r, ...)
{
va_list va;
const char *s;