//--------------------------------------------------------------------- // 尽可能的接收数据 //--------------------------------------------------------------------- int apr_recvall(int sock, void *buf, long size) { unsigned char *lptr = (unsigned char*)buf; int total = 0, retval = 0, c; for (; size > 0; lptr += retval, size -= (long)retval) { retval = apr_recv(sock, lptr, size, 0); if (retval == 0) { retval = -1; break; } if (retval == -1) { c = apr_errno(); if (c != IEAGAIN) { retval = -1000 - c; break; } retval = 0; break; } total += retval; } return (retval < 0)? retval : total; }
static apr_status_t fill_input_buffer (apr_socket_t * socket) { input_buffer_t * buffer; apr_size_t length; RELAY_ERROR (get_input_buffer (socket, (&buffer))); #if (HAVE_APR_1_2_2) RELAY_ERROR (((length = (sizeof (buffer->data))), (apr_socket_recv (socket, (buffer->data), (&length))))); #else RELAY_ERROR (((length = (sizeof (buffer->data))), (apr_recv (socket, (buffer->data), (&length))))); #endif (buffer->start) = (buffer->data); (buffer->end) = ((buffer->data) + length); if (length == 0) (buffer->start) += 1; return (APR_SUCCESS); }
static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, server_rec *srv) { apr_port_t rmt_port, our_port; apr_port_t sav_rmt_port, sav_our_port; apr_size_t i; char *cp; char buffer[RFC1413_MAXDATA + 1]; char user[RFC1413_USERLEN + 1]; /* XXX */ apr_size_t buflen; apr_sockaddr_port_get(&sav_our_port, conn->local_addr); apr_sockaddr_port_get(&sav_rmt_port, conn->remote_addr); /* send the data */ buflen = apr_snprintf(buffer, sizeof(buffer), "%hu,%hu\r\n", sav_rmt_port, sav_our_port); ap_xlate_proto_to_ascii(buffer, buflen); /* send query to server. Handle short write. */ i = 0; while (i < buflen) { apr_size_t j = strlen(buffer + i); apr_status_t status; status = apr_send(sock, buffer+i, &j); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, "write: rfc1413: error sending request"); return status; } else if (j > 0) { i+=j; } } /* * Read response from server. - the response should be newline * terminated according to rfc - make sure it doesn't stomp its * way out of the buffer. */ i = 0; memset(buffer, '\0', sizeof(buffer)); /* * Note that the strchr function below checks for \012 instead of '\n' * this allows it to work on both ASCII and EBCDIC machines. */ while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) { apr_size_t j = sizeof(buffer) - 1 - i; apr_status_t status; status = apr_recv(sock, buffer+i, &j); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, "read: rfc1413: error reading response"); return status; } else if (j > 0) { i+=j; } else if (status == APR_SUCCESS && j == 0) { /* Oops... we ran out of data before finding newline */ return APR_EINVAL; } } /* RFC1413_USERLEN = 512 */ ap_xlate_proto_from_ascii(buffer, i); if (sscanf(buffer, "%hu , %hu : USERID :%*[^:]:%512s", &rmt_port, &our_port, user) != 3 || sav_rmt_port != rmt_port || sav_our_port != our_port) return APR_EINVAL; /* * Strip trailing carriage return. It is part of the * protocol, not part of the data. */ if ((cp = strchr(user, '\r'))) *cp = '\0'; conn->remote_logname = apr_pstrdup(conn->pool, user); return APR_SUCCESS; }
AP_DECLARE(void) ap_lingering_close(conn_rec *c) { char dummybuf[512]; apr_size_t nbytes = sizeof(dummybuf); apr_status_t rc; apr_int32_t timeout; apr_int32_t total_linger_time = 0; apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module); if (!csd) { return; } ap_update_child_status(c->sbh, SERVER_CLOSING, NULL); #ifdef NO_LINGCLOSE ap_flush_conn(c); /* just close it */ apr_socket_close(csd); 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 * client has ACKed our FIN and/or has stopped sending us data. */ /* Send any leftover data to the client, but never try to again */ ap_flush_conn(c); if (c->aborted) { apr_socket_close(csd); return; } /* Shut down the socket for write, which will send a FIN * to the peer. */ if (apr_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS || c->aborted) { apr_socket_close(csd); return; } /* Read all data from the peer until we reach "end-of-file" (FIN * from peer) or we've exceeded our overall timeout. If the client does * not send us bytes within 2 seconds (a value pulled from Apache 1.3 * which seems to work well), close the connection. */ timeout = apr_time_from_sec(SECONDS_TO_LINGER); apr_socket_timeout_set(csd, timeout); apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1); while (1) { nbytes = sizeof(dummybuf); rc = apr_recv(csd, dummybuf, &nbytes); if (rc != APR_SUCCESS || nbytes == 0) break; total_linger_time += SECONDS_TO_LINGER; if (total_linger_time >= MAX_SECS_TO_LINGER) { break; } } apr_socket_close(csd); return; }