# $Id: http-rewriter.bro,v 1.8 2003/01/22 09:22:52 vern Exp $

# We can't do HTTP rewriting unless we process everything in the connection.
@load http-reply
@load http-entity

redef rewriting_http_trace = T;
redef http_entity_data_delivery_size = 4096;

const rewrite_header_in_position = T;

event http_request(c: connection, method: string,
		   original_URI: string, unescaped_URI: string, version: string)
	{
	rewrite_http_request(c, method, original_URI, version);
	}

event http_reply(c: connection, version: string, code: count, reason: string)
	{
	rewrite_http_reply(c, version, code, reason);
	}

event http_header(c: connection, is_orig: bool, name: string, value: string)
	{
	# Only rewrite top-level headers.
	local s = lookup_http_request_stream(c);
	local msg = get_http_message(s, is_orig);

	if ( msg$entity_level == 1 )
		{
		if ( name == "CONTENT-LENGTH" )
			rewrite_http_header(c, is_orig,
					"X-Original-Content-Length", value);

		else if ( name == "TRANSFER-ENCODING" )
			rewrite_http_header(c, is_orig,
					"X-Original-Transfer-Encoding", value);

		else
			rewrite_http_header(c, is_orig, name, value);
		}
	}

event http_all_headers(c: connection, is_orig: bool, hlist: mime_header_list)
	{
	if ( rewrite_header_in_position )
		{
		local p = current_packet(c);
		if ( p$is_orig == is_orig )
			{
			local s = lookup_http_request_stream(c);
			local msg = get_http_message(s, is_orig);
			msg$header_slot = reserve_rewrite_slot(c);
			}
		else
			print fmt("cannot reserve a slot at %.6f", network_time());
		}
	}

event http_message_done(c: connection, is_orig: bool, stat: http_message_stat)
	{
	local s = lookup_http_request_stream(c);
	local msg = get_http_message(s, is_orig);
	local data_length = 0;

	if ( stat$interrupted )
		{
		print http_log, 
			fmt("%.6f %s message interrupted at length=%d \"%s\"",
				network_time(), id_string(c$id),
				stat$body_length, stat$finish_msg);
		}

	if ( msg$header_slot > 0 )
		seek_rewrite_slot(c, msg$header_slot);

	if ( ! is_orig || stat$body_length > 0 )
		{
		if ( include_HTTP_abstract )
			data_length = byte_len(msg$abstract);

		data_length = data_length + stat$content_gap_length;

		rewrite_http_header(c, is_orig, "Content-Length",
					fmt(" %d", data_length));
		}

	rewrite_http_header(c, is_orig, "X-Actual-Data-Length",
				fmt(" %d; gap=%d, content-length=%s",
					stat$body_length,
					stat$content_gap_length,
					msg$content_length));
	rewrite_http_data(c, is_orig, "\r\n");

	if ( msg$header_slot > 0 )
		release_rewrite_slot(c, msg$header_slot);

	if ( data_length > 0 )
		rewrite_http_data(c, is_orig, msg$abstract);
	}
