📄 u_connectionhttp.pas
字号:
(*
* One Way Network Sniffer (OWNS)
* Copyright (C) 2001-2002 OWNS
*
* http://owns.sourceforge.net/
* http://www.owns.st
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)
(*
* $Id: u_ConnectionHTTP.pas,v 1.7 2001/08/18 18:06:52 owns Exp $
* represents a HTTP Connection
* An HTTP connection consists on one or more HTTP Messages
* You can naviguate from one message to the next with nextMessage
*)
unit u_ConnectionHTTP;
interface
uses classes, sysUtils,
u_messageHTTP, u_Filter,u_IPPacket, u_MimeTypes, u_DebugPacket, u_Debug,u_FileStreamCapture,u_Statistics;
// cf RFC2068
type
TConnectionHTTP = class
private
FData : PChar; // data from TCP Stream
FSize : LongInt; // Size of FData
FIPSource : IP_ADDR;
FSourcePort : Word;
FIPDest : IP_ADDR;
FDestPort : Word;
FNumConnection : LongInt;
FDamaged : boolean;
FCurrentMessage : THTTPMessage; // current message
FPositionMessage : Longint; // position of currentMessage in FData
FNumMessage : Integer;
procedure guessContentType;
public
constructor create(p_Data : PChar; p_Size : LongInt;p_NumConnection : LongInt;
p_IPSourceAddr : PIP_ADDR; p_SourcePort : Word;
p_IPDestAddr : PIP_ADDR; p_DestPort : Word;p_Damaged : boolean);
function firstMessage : THTTPMessage;
function nextMessage : THTTPMessage;
function saveMessage : boolean;
function saveMessages : integer;
procedure saveBody(p_FilePath : String);
procedure saveHeader(p_FilePath : String);
destructor destroy; override;
property IPSource : IP_ADDR read FIPSource;
property SourcePort : Word read FSourcePort;
property IPDest : IP_ADDR read FIPDest;
property DestPort : Word read FDestPort;
property NumMessage : Integer read FNumMessage;
property CurrentMessage : THTTPMessage read FCurrentMessage;
end;
implementation
destructor TConnectionHTTP.destroy;
begin
if FCurrentMessage <> nil then FCurrentMessage.free;
inherited;
end;
// go to the first message of the HTTP connection
function TConnectionHTTP.firstMessage : THTTPMessage;
begin
FPositionMessage := 0;
FNumMessage := 0;
FCurrentMessage := THTTPMessage.create(@(FData[FPositionMessage]),FSize);
FCurrentMessage.processMessage;
guessContentType;
result := FCurrentMessage;
end;
// guess the content-type of the current message from the content of the message
// and from the "COntent-Type" header of the message
procedure TConnectionHTTP.guessContentType;
var
l_ContentType : String;
begin
// content-type is given by Content-Type field but often we have something like
// text/html whereas in fact the file is a rar file or a gif file
if (FCurrentMessage.ContentLength > 8) then
begin
l_ContentType := guessContentTypeFromContent(FCurrentMessage.content);
if ((l_ContentType <> '') and (l_ContentType <> FCurrentMessage.HeaderContentType.Text)) then
FCurrentMessage.HeaderContentType.ContentType := l_ContentType;
end;
end;
// go to the next message of the HTTP connection
// free the current message before
// with HTTP 1.1, there can be several messages
function TConnectionHTTP.nextMessage : THTTPMessage;
begin
FPositionMessage := FPositionMessage + FCurrentMessage.BodyLength+FCurrentMessage.HeaderLength;
FCurrentMessage.free;
if (FPositionMessage < FSize) then
begin
FCurrentMessage := THTTPMessage.create(@(FData[FPositionMessage]),FSize-FPositionMessage);
FCurrentMessage.processMessage;
guessContentType;
Inc(FNumMessage);
end
else
begin
FCurrentMessage := nil;
FNumMessage := -1;
end;
result := FCurrentMessage;
end;
// save the body of the current message in the following file
procedure TConnectionHTTP.saveBody(p_FilePath : String);
var
l_FileStream : TFileStreamCapture;
begin
// SizeBody peut 阾re 0 pour toutes les r閜onses 304,204 (pas de body)
if (FCurrentMessage.ContentLength > 0) then
begin
l_FileStream := TFileStreamCapture.create(p_FilePath);
l_FileStream.write(FCurrentMessage.Content^,FCurrentMessage.ContentLength);
l_FileStream.free;
end;
end;
// save the http header of the current message in a file
procedure TConnectionHTTP.saveHeader(p_FilePath : String);
var
l_FileStream : TFileStreamCapture;
l_Header : String;
begin
l_Header := FCurrentMessage.Header.Text;
l_FileStream := TFileStreamCapture.create(p_FilePath);
l_FileStream.write(l_Header[1],length(l_Header));
l_FileStream.free;
end;
// save the current message
// The filter gives the name of the message
// returns true if message has been saved (it passes filters)
function TConnectionHTTP.saveMessage : boolean;
var
l_SaveBody : Boolean;
l_SaveHeader : Boolean;
l_UniqueId : String;
l_FilePath : String;
begin
result := false;
// we apply the filter
if (g_Filter.filterHttp.filterMessage(FCurrentMessage,l_SaveBody,l_SaveHeader)) then
begin
l_UniqueId := IntToStr(FNumConnection)+'-'+IntToStr(NumMessage);
if FDamaged then l_UniqueId := l_UniqueId + ' DAMAGED ';
l_FilePath := g_Filter.getFilePath(
l_UniqueId,
FCurrentMessage.HeaderContentType,
@(IPSource[0]),SourcePort,
@(IPDest[0]),DestPort);
// we do not handle multiple encodings like FIRSTENCODING,GZIP
if (FCurrentMessage.HeaderContentEncoding = 'GZIP') then
l_FilePath := l_FilePath+'.gz';
// we save the file
if l_SaveBody then
begin
saveBody(l_FilePath);
result := true;
end;
// we save the header if necessary. Header a the same name with an extension of ".header"
if l_SaveHeader then
saveHeader(l_FilePath+'.header');
end;
end;
// Save all the messages of this HTTP Connection
// Generally, there is only one message per HTTP Connection but with HTTP 1.1,
// there can be more
// returns the number of messages that have been saved (pass filter)
function TConnectionHTTP.saveMessages : integer;
begin
// if (FDestPort = 1641) then asm int 3 end;
result := 0;
try
firstMessage;
while(FCurrentMessage <> nil) do
begin
if (saveMessage) then result := result+1;
nextMessage;
end;
except
on e : exception do
begin
g_Debug.debug(e.Message+'('+IntToStr(FNumConnection)+'-'+IntToStr(FNumMessage)+')','TConnectionHTTP.saveMessages');
g_DebugPacket.writeData('Error in TConnectionHTTP.saveMessages', FData, FSize);
end;
end;
end;
// p_Data : data for this connection (all the content of the TCP Stream)
constructor TConnectionHTTP.create(p_Data : PChar; p_Size : LongInt;p_NumConnection : LongInt;
p_IPSourceAddr : PIP_ADDR; p_SourcePort : Word;
p_IPDestAddr : PIP_ADDR; p_DestPort : Word; p_Damaged : Boolean);
var
i : Integer;
begin
(* if (p_IPDestAddr[0] = 193) and (p_IPDestAddr[1] = 226) and (p_IPDestAddr[2] = 118) and (p_IPDestAddr[3] = 26) and
(p_DestPort = 2568) then
asm
int 3
end;
*)
g_CurrentProc := 'TConnectionHTTP.create';
FDestPort := p_DestPort;
FSourcePort := p_SourcePort;
for i := 0 to 3 do
begin
FIPDest[i] := p_IPDestAddr[i];
FIPSource[i] := p_IPSourceAddr[i];
end;
FNumConnection := p_NumConnection;
FDamaged := p_Damaged;
FData := p_Data;
FSize := p_Size;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -