connection.c revision 43c3e6a4b559b76b750c245ee95e2782c15b4296
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
* applicable.
*
* 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
*
*
* 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.
*/
#include "apr.h"
#include "apr_strings.h"
#define CORE_PRIVATE
#include "ap_config.h"
#include "httpd.h"
#include "http_connection.h"
#include "http_request.h"
#include "http_protocol.h"
#include "ap_mpm.h"
#include "mpm_default.h"
#include "http_config.h"
#include "http_core.h"
#include "http_vhost.h"
#include "scoreboard.h"
#include "http_log.h"
#include "util_filter.h"
)
(apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc),
/*
* More machine-dependent networking gooo... on some systems,
* you've got to be *really* sure that all the packets are acknowledged
* before closing the connection, since the client will not be able
* to see the last response if their TCP buffer is flushed by a RST
* packet from us, which is what the server's TCP stack will send
* if it receives any request data after closing the connection.
*
* In an ideal world, this function would be accomplished by simply
* setting the socket option SO_LINGER and handling it within the
* server's TCP stack while the process continues on to the next request.
* Unfortunately, it seems that most (if not all) operating systems
* block the server process on close() when SO_LINGER is used.
* For those that don't, see USE_SO_LINGER below. For the rest,
* we have created a home-brew lingering_close.
*
* Many operating systems tend to block, puke, or otherwise mishandle
* calls to shutdown only half of the connection. You should define
* NO_LINGCLOSE in ap_config.h if such is the case for your system.
*/
#ifndef MAX_SECS_TO_LINGER
#define MAX_SECS_TO_LINGER 30
#endif
{
apr_bucket *b;
/* FLUSH bucket */
b = apr_bucket_flush_create(c->bucket_alloc);
/* End Of Connection bucket */
b = ap_bucket_eoc_create(c->bucket_alloc);
}
/* we now proceed to read from the client until we get EOF, or until
* MAX_SECS_TO_LINGER has passed. the reasons for doing this are
* documented in a draft:
*
*
* in a nutshell -- if we don't make this effort we risk causing
* TCP RST packets to be sent which can tear down a connection before
* all the response data has been sent to the client.
*/
#define SECONDS_TO_LINGER 2
{
char dummybuf[512];
apr_time_t timeup = 0;
if (!csd) {
return;
}
#ifdef NO_LINGCLOSE
ap_flush_conn(c); /* just close it */
return;
#endif
/* Close the connection, being careful to send out whatever is still
* in our buffers. If possible, try to avoid a hard close until the
*/
/* Send any leftover data to the client, but never try to again */
ap_flush_conn(c);
if (c->aborted) {
return;
}
/* Shut down the socket for write, which will send a FIN
* to the peer.
*/
|| c->aborted) {
return;
}
/* Read available data from the client whilst it continues sending
* it, for a maximum time of MAX_SECS_TO_LINGER. If the client
* does not send any data within 2 seconds (a value pulled from
* Apache 1.3 which seems to work well), give up.
*/
/* The common path here is that the initial apr_socket_recv() call
* will return 0 bytes read; so that case must avoid the expensive
* apr_time_now() call and time arithmetic. */
do {
break;
if (timeup == 0) {
/* First time through; calculate now + 30 seconds. */
continue;
}
} while (apr_time_now() < timeup);
return;
}
{
int rc;
c->aborted = 1;
}
if (!c->aborted) {
}
}