ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 

  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА














     АРХИВ :: Apache-Talk
Apache-Talk mailing list archive (apache-talk@lists.lexa.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[apache-talk] подсчет трафика


  • To: apache-talk@xxxxxxxxxxxxx
  • Subject: [apache-talk] подсчет трафика
  • From: Roman Listov <r2l@xxxxxxxx>
  • Date: Wed, 27 Oct 2004 12:23:59 +0400
  • Content-length: 5370
  • Organization: VAM Ltd

  ????? ????????, ???? ????????.
  ÷???? ??? ?????? ???????? ??????????? ???????. ????? ????????
  ??????? ???? ??????? ??? ?????? - mod_watch ?? snert.com ?
  mod_accounting. ?????? ?????? ?????????, ??, ????, ????????? ?
  ?????????? ???????... ? ??? ???????? ????????????????? ??????. ????
  ? ???, ??? ???????? ?? ????????? ??? ? ????, ? ??????? ???????
  ?????? (? ??????? ?????? ??? mod_geo). mod_accounting ???????
  ????????, ???? ? ???? ??????????? ???? ?????????? ????, ??... ????,
  ?????? ??? ? ???????? ? ????... ????, ?????? ???????. ÷ ????? ??
  ?????? mod_accounting ?????? ???????, ?????? ???????????? ??????????
  ????????? ??? ???????????? ????????????? ?? ? LogFormat.
  ?? ??? ??? ???????????????? ?? ? ? ???? ? ?????????? ?????????, ???
  ?? ??????????, ???? ?? ??? ?????????? ???? ???????? ? ?????? ??? ?
  ?????? (???? ?????? ? ????????, ?? ???? ?? ???). ? ????? ? ?? ??????
  ????????? ????? ?????? ????????.
  ???????!
//#define DEBUG

#include <stdio.h>
#include <stdlib.h>

#include "mod_bytess.h"

#define MOD_BYTESS_VERSION_INFO_STRING "mod_bytess/0.1"

module MODULE_VAR_EXPORT bytess_module;

// hook function pass to ap_table_do()
static int GetHeaderLen( long *count, const char *key, const char *val )
{
	*count += strlen( key ) + strlen( val ) + 4; // 4 for ": " + CR + LF

#ifdef DEBUG
	ap_log_error( APLOG_MARK, ERRLEVEL, rr->server, 
				  ap_pstrcat( rr->pool, key, ": ", val, NULL ));
#endif

	return( 1 );
}

// computes the length of a table
static long TableLen( request_rec *r, table *tab )
{
	long count = 0;

	if( tab )
		ap_table_do((int (*) (void *, const char *, const char *)) GetHeaderLen, (void *) &count, tab, NULL );

	return( count );
}

// computes the number of bytes sent
static long BytesSent( request_rec *r )
{
	long	sent, status_len = 0;
	char	*custom_response;

#ifdef DEBUG
	ap_log_error( APLOG_MARK, ERRLEVEL, rr->server, 
				  "BytesSent" );
#endif

	// let's see if it's a failed redirect
	// I'm using the same logic of ap_send_error_response()
	if( custom_response = (char *)ap_response_code_string( r, ap_index_of_response( r->status ))) {

		// if so, find the original request_rec
		if( custom_response[0] != '"' )
			while( r->prev && ( r->prev->status != HTTP_OK ))
				r = r->prev;
	}
		
	if( r->status_line )
		status_len = strlen( r->status_line );
	
	sent = TableLen( r, r->headers_out ) + TableLen( r, r->err_headers_out ) + 2 +	// 2 for CRLF
		   11 + status_len +														// HTTP/1.x nnn blah
		   10 + strlen( ap_get_server_version() ) +									// Server: line
		   8 + strlen( ap_gm_timestr_822( r->pool, r->request_time ));				// Date: line

    if(( sent >= 255 ) && ( sent <= 257 ))
        sent += sizeof( "X-Pad: avoid browser bug" ) + 1;

	if( r->sent_bodyct ) {

		if( r->connection )  {
			long int bs;

			// this is more accurate than bytes_sent in presence of modules
			// which manipulate the output (eg. mod_gzip)
			ap_bgetopt( r->connection->client, BO_BYTECT, &bs );
		
			sent += bs;

		} else
			sent += r->bytes_sent;
	}

	return( sent );
}

// computes the number of bytes received
static long BytesRecvd( request_rec *r )
{
	long		recvd;
	const char *len;

#ifdef DEBUG
	ap_log_error( APLOG_MARK, ERRLEVEL, rr->server, 
				  "BytesRecvd" );
#endif

	recvd = strlen( r->the_request ) + TableLen( r, r->headers_in ) + 4; // 2 for CRLF after the request, 2 for CRLF after all headers

	len = ap_table_get( r->headers_in, "Content-Length" );

	if( len )
		recvd += atol( len );

	return( recvd );
}


// typedef const char *(*hook_func)();


// ------------------- HOOKS -----------------
	
static int acct_transaction( request_rec *orig )
{
	request_rec			*r = orig;

	// get to the last of the chain, we need the correct byte counters ;-)
	while( r->next )
		r = r->next;

	ap_table_setn(r->subprocess_env, "BYTES_R", 
	     ap_psprintf(r->pool, "%ld", BytesRecvd( orig )) );
	ap_table_setn(r->subprocess_env, "BYTES_S", 
	     ap_psprintf(r->pool, "%ld", BytesSent( r )) );

	return( OK );
}

static void mod_acct_init( server_rec *server, pool *p )
{
	ap_add_version_component(MOD_BYTESS_VERSION_INFO_STRING);
}

// ------------------- MOD CONFIG -----------------

/* The configuration array that sets up the hooks into the module. */
module bytess_module = 
{
	STANDARD_MODULE_STUFF,
	mod_acct_init,			 	/* initializer */
	NULL,					 /* create per-dir config */
	NULL,					 /* merge per-dir config */
	NULL,					 /* server config */
	NULL,					 /* merge server config */
	NULL,					 /* command table */
	NULL,					 /* handlers */
	NULL,					 /* filename translation */
	NULL,					 /* check_user_id */
	NULL,					 /* check auth */
	NULL,					 /* check access */
	NULL,					 /* type_checker */
	NULL,					 /* fixups */
	acct_transaction,			 /* logger */
#if MODULE_MAGIC_NUMBER >= 19970103
	NULL,					 /* header parser */
#endif
#if MODULE_MAGIC_NUMBER >= 19970719
	NULL,                   		 /* child_init */
#endif
#if MODULE_MAGIC_NUMBER >= 19970728
	NULL,					/* process exit/cleanup */
#endif
#if MODULE_MAGIC_NUMBER >= 19970902
	NULL					 /* [#0] post read-request */
#endif  
};
#ifndef MOD_BYTESS_H
#define MOD_BYTESS_H

#include <time.h>

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_core.h"


#define ERRLEVEL	(APLOG_ERR|APLOG_NOERRNO)
#define DEBUGLEVEL	(APLOG_INFO|APLOG_NOERRNO)

#endif /* MOD_BYTESS_H */



 




Copyright © Lexa Software, 1996-2009.