-
Notifications
You must be signed in to change notification settings - Fork 13
/
spiderapache.pas
179 lines (145 loc) · 4.6 KB
/
spiderapache.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
unit SpiderApache;
{
*******************************************************************************************************************
SpiderApache: Contains TSpiderApache engine for Apache module
Author: Motaz Abdel Azeem
email: motaz@code.sd
Home page: http://code.sd
License: LGPL
Last modified: 12.July.2012
*******************************************************************************************************************
}
{$mode objfpc}{$h+}
interface
uses
Classes, SysUtils, ApacheUtils, SpiderUtils, SpiderAction;
type
{ TSpiderApache }
TSpiderApache = class(TComponent)
private
fOnRequest: TSpiderEvent;
fRequest: TSpiderRequest;
fResponse: TSpiderResponse;
fPath: string;
fPathInfo: string;
fModules: array of String;
fPathList: array of TStringList;
function SearchActionInModule(APath: string; AModule: TDataModule): Boolean;
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(TheOwner: TComponent); override;
procedure Init(PathInfo, ContentType, RequestMethod, Query, Cookies, UserAgent, PostedData,
ContentLength, Referer, RemoteIP, URI, ServerSoftware, Host: string);
destructor Destroy; override;
function Execute: TSpiderResponse;
procedure AddDataModule(const ADataModuleClassName: string; APaths: array of string);
{ Public declarations }
published
property OnRequest: TSpiderEvent read FOnRequest write FOnRequest;
{ Published declarations }
end;
implementation
{ TSpiderApache }
function TSpiderApache.Execute: TSpiderResponse;
var
Found: Boolean;
i: Integer;
dmc: TDataModuleClass;
DataMod: TDataModule;
begin
// Search path in main module actions
Found:= False;
if fPathInfo <> '' then
begin
Found:= SearchActionInModule(fPathInfo, TDataModule(Owner));
end;
DataMod:= nil;
// Search path in other additional modules
if (not Found) then
for i:= 0 to High(fModules) do
if fPathList[i].IndexOf(fPathInfo) <> -1 then
begin
dmc:= TDataModuleClass(FindClass(fModules[i]));
if dmc <> nil then
begin
DataMod:= dmc.Create(nil);
Found:= SearchActionInModule(fPathInfo, DataMod);
end;
if Found then
Break;
end;
// Default path /
if (not Found) and (fPathInfo = '') and (Assigned(fOnRequest)) then
begin
Found:= True;
if fRequest = nil then
raise Exception.Create('TSpiderApache: Request object is not initialized');
if fResponse = nil then
raise Exception.Create('TSpiderApache: Response object is not initialized');
fOnRequest(Self, fRequest, fResponse);
Result:= fResponse;
end;
if not Found then
fResponse.Add(fPathInfo + ' not found');
Result:= fResponse;
if Assigned(DataMod) then
DataMod.Free;
end;
constructor TSpiderApache.Create(TheOwner: TComponent);
begin
fResponse:= TSpiderResponse.Create;
fPath:= '/';
fRequest:= nil;
inherited Create(TheOwner);
end;
procedure TSpiderApache.Init(PathInfo, ContentType, RequestMethod, Query,
Cookies, UserAgent, PostedData, ContentLength, Referer, RemoteIP, URI,
ServerSoftware, Host: string);
begin
if (PathInfo <> '') and (PathInfo[Length(PathInfo)] = '/') then
PathInfo:= Copy(PathInfo, 1, Length(PathInfo) - 1);
fPathInfo:= Trim(PathInfo);
if Assigned(fRequest) then
fRequest.Free;
if Assigned(fResponse) then
fResponse.Content.Clear;
fRequest:= TApacheRequest.Create(PathInfo, ContentType, RequestMethod, Query, Cookies, UserAgent, PostedData,
ContentLength, Referer, RemoteIP, URI, ServerSoftware, Host);
end;
destructor TSpiderApache.Destroy;
begin
fRequest.Free;
fResponse.Free;
inherited Destroy;
end;
function TSpiderApache.SearchActionInModule(APath: string; AModule: TDataModule): Boolean;
var
i: Integer;
begin
if AModule = nil then
raise Exception.Create('error: Nil module passed');
Result:= False;
APath:= LowerCase(APath);
for i:= 0 to AModule.ComponentCount - 1 do
if AModule.Components[i] is TSpiderAction then
if LowerCase(TSpiderAction(AModule.Components[i]).Path) = APath then
begin
TSpiderAction(AModule.Components[i]).DoRequest(fRequest, fResponse);
Result:= True;
Break;
end;
end;
procedure TSpiderApache.AddDataModule(const ADataModuleClassName: string; APaths: array of string);
var
i: Integer;
begin
SetLength(fModules, Length(fModules) + 1);
fModules[High(fModules)]:= ADataModuleClassName;
SetLength(fPathList, Length(fPathList) + 1);
fPathList[High(fPathList)]:= TStringList.Create;
for i:= 0 to High(APaths) do
fPathList[High(fPathList)].Add(LowerCase(APaths[i]));
end;
end.