DCL 3.7.4
Loading...
Searching...
No Matches
ServletMain.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4#include <windows.h>
5#endif
6
7#include <wctype.h>
8
9#include <dcl/Exception.h>
10#include <dcl/StringReader.h>
11#include <dcl/BufferedReader.h>
12#include <dcl/FileReader.h>
13#include <dcl/DateTime.h>
14#include <dcl/IniFile.h>
15#include <dcl/TextTemplate.h>
16
17#include "ServletMain.h"
18#include "Session.h"
19#include "User.h"
20#include "HtmlPage.h"
21
22#if __DCL_HAVE_THIS_FILE__
23#undef __THIS_FILE__
24static const char_t __THIS_FILE__[] = __T("fastpage/ServletMain.cpp");
25#endif
26
27__DCL_BEGIN_NAMESPACE
28
30{
32public:
34
35 virtual String getMessage() const;
36};
37
39
40ScriptException::ScriptException(Exception* pCause)
41 : Exception(pCause)
42{
43}
44
45String ScriptException::getMessage() const
46{
47 return L"Invalid Script Contents";
48}
49
51{
52 uPostMaxLength = 1024 * 1024; // 1 MBytes
53 nErrorPageID = 1;
55}
56
70
73 L"DCL World-Wide-Web Components - Database based Html Page Assistant"
74)
75
77
78FastPageServlet::FastPageServlet()
79{
80}
81
84{
86
87#ifdef __WINNT__
88 #define INI_FILENAME L"HSAFastPage_w.ini"
89#else
90 #define INI_FILENAME L"HSAFastPage.ini"
91#endif
92 String strIniFile = getIniFileName(INI_FILENAME);
93 __DCL_TRACE1(L"%ls\n", strIniFile.data());
94
95 SiteContext* pSite = NULL;
96 BufferedReader in(new FileReader(strIniFile, new UTF8Decoder()));
97 String strLine;
98 while(in.readLine(strLine)) {
99 strLine = strLine.trim();
100 if (strLine.isEmpty())
101 continue;
102
103 if (strLine[0] == L';' || strLine[0] == L'#')
104 continue;
105 else if (strLine[0] == '[') {
106 strLine = strLine.trim(L"[] ");
107
108 pSite = new SiteContext();
109 pSite->strSiteID = strLine;
110
111 __listSiteCtx.addTail(pSite);
112 __mapSiteCtx[pSite->strSiteID] = pSite;
113 }
114 else {
115 if (pSite == NULL) {
116 // invalid section
117 continue;
118 }
119 // key = value
120 size_t nPos = strLine.indexOf(L'=');
121 if (nPos == (size_t) -1) {
122 // invalid line
123 continue;
124 }
125
126 String strName = strLine.left(nPos).trim();
127 String strValue = strLine.right(strLine.length() - nPos - 1).trim();
128 if (strName.isEmpty() || strValue.isEmpty()) {
129 // ignore
130 continue;
131 }
132
133 if (!strName.compareNoCase(L"POST_MAX_LENGTH")) {
134 size_t nMul = 1;
135 wchar_t chMul = strValue[strValue.length() - 1];
136 if (!iswdigit((wint_t)chMul)) {
137 if (chMul == L'k' || chMul == L'K')
138 nMul = 1024;
139 else if (chMul == L'm' || chMul == L'M')
140 nMul = 1024 * 1024;
141 String strMul = chMul;
142 strValue = strValue.trimRight(strMul);
143 }
144 try {
145 size_t n = UInteger::parse(strValue, 10);
146 pSite->uPostMaxLength = n * nMul;
147 }
148 catch (Exception* e) {
149 e->destroy();
150 }
151 }
152 else if (!strName.compareNoCase(L"SERVER_NAMES")) {
153 StringArray list;
154 if (strValue.split(L' ', list)) {
155 StringArray::Iterator itList = list.begin();
156 for( ; itList != list.end(); ++itList)
157 __mapSiteCtx[*itList] = pSite;
158 }
159 }
160 else if (!strName.compareNoCase(L"DATABASE_DRIVER")) {
161 pSite->strDbDriver = strValue;
162 }
163 else if (!strName.compareNoCase(L"DATABASE_CONNECT")) {
164 pSite->strDbConnect = strValue;
165 }
166 else if (!strName.compareNoCase(L"ERROR_PAGE")) {
167 pSite->nErrorPageID = Integer::parse(strValue, 10,
168 pSite->nErrorPageID);
169 }
170 else if (!strName.compareNoCase(L"PERM_DENIED_PAGE")) {
171 pSite->nPermDeniedPageID = Integer::parse(strValue, 10,
172 pSite->nPermDeniedPageID);
173 }
174 else if (!strName.compareNoCase(L"SKIN_DIR")) {
175 pSite->strSkinDir = strValue;
176 }
177 else if (!strName.compareNoCase(L"ATTACHMENT_DIR")) {
178 pSite->strAttachmentDir = strValue;
179 }
180 else if (!strName.compareNoCase(L"THUMBNAIL_DIR")) {
181 pSite->strThumbnailDir = strValue;
182 }
183 else {
184 __DCL_TRACE1(L"Invalid Line: [%ls]\n", strLine.data());
185 }
186 }
187 }
188}
189
192{
193
194 for(PointerList::Iterator itList = __listSiteCtx.begin();
195 itList != __listSiteCtx.end(); itList++
196 ) {
197 SiteContext* pSite = (SiteContext*)(*itList);
198 delete (pSite);
199 }
201}
202
205{
207
208 const SiteContext* pSite = NULL;
209 int nPageID = -1;
210 int nServiceUserID = Session::SYSTEM_USER_ID;
211
212 // SERVER_NAME 이 구성되어 있지 않으면 404
213 {
214 String strServerName = AsciiDecoder::decode(
215 ctx.getCgiVariable("SERVER_NAME"));
216 __DCL_TRACE1(L"SERVER_NAME: [%ls]\n", strServerName.data());
217 StringToPointerMap::ConstIterator itMap = __mapSiteCtx.find(strServerName);
218 if (itMap == __mapSiteCtx.end()) {
219 __DCL_TRACE0(L"404:\n");
220 ctx.setStatusCode(HTTP_STATUS_NOT_FOUND);
221 return;
222 }
223 pSite = (SiteContext*)(*itMap).value;
224
225 __DCL_TRACE1(L"HOST ID: [%ls]\n", pSite->strSiteID.data());
226 __DCL_TRACE1(L"POST_MAX_LENGTH: [%u]\n", pSite->uPostMaxLength);
227 __DCL_TRACE1(L"DATABASE_DRIVER: [%ls]\n", pSite->strDbDriver.data());
228 __DCL_TRACE1(L"DATABASE_CONNECT: [%ls]\n", pSite->strDbConnect.data());
229 __DCL_TRACE1(L"ERROR_PAGE_ID: [%d]\n", pSite->nErrorPageID);
230 __DCL_TRACE1(L"PERM_DENIED_PAGE_ID: [%d]\n", pSite->nPermDeniedPageID);
231 __DCL_TRACE1(L"SKIN_DIR: [%ls]\n", pSite->strSkinDir.data());
232 __DCL_TRACE1(L"ATTACHMENT_DIR: [%ls]\n", pSite->strAttachmentDir.data());
233 __DCL_TRACE1(L"THUMBNAIL_DIR: [%ls]\n", pSite->strThumbnailDir.data());
234 }
235
236 // GET, POST 메소드만 서비스 한다.
237 if (!(ctx.methodNo() == HTTP_METHOD_GET || ctx.methodNo() == HTTP_METHOD_POST)) {
238 ctx.setStatusCode(HTTP_STATUS_NOT_IMPLEMENTED);
239 return;
240 }
241
242 // 스크립트에서 PAGE_ID, SERVICE_USER_ID를 읽는다.
243 try {
244 String script = ctx.scriptData();
245 __DCL_TRACE1(L"script data[%ls]\n", script.data());
246
247 StringArray lines;
248 script.split_r(L"\r?\n", true, lines);
249 for (size_t i = 0; i < lines.size(); i++) {
250 String strLine = lines[i];
251 StringArray list;
252 if (strLine.split(L'=', list) == 2) {
253 StringArray::Iterator itList = list.begin();
254 (*itList).trim();
255 if (!(*itList).compareNoCase(L"PAGE")) {
256 ++itList;
257 nPageID = Integer::parse(*itList, 10);
258 }
259 else if (!(*itList).compareNoCase(L"SERVICE_USER")) {
260 ++itList;
261 nServiceUserID = Integer::parse(*itList, 10);
262 }
263 }
264 }
265 __DCL_TRACE2(L"SCRIPT PAGE_ID=%d, SERVICE_USER_ID=%d\n",
266 nPageID, nServiceUserID);
267 }
268 catch(Exception* _cause) {
269 throw new ScriptException(_cause);
270 }
271
272 // QUERY_STRING에 page파라미터가 있으면 PAGE_ID를 오버라이드 한다.
273 {
274 ListedStringToStringArrayMap& mapQuery = ctx.__queryMap;
275 ListedStringToStringArrayMap::ConstIterator itMap
276 = mapQuery.find(L"page");
277 if (itMap != mapQuery.end() && (*itMap).value.size() > 0) {
278 nPageID = Integer::parse((*itMap).value[0], 10, nPageID);
279 }
280 }
281
282 SQLConnection conn(pSite->strDbDriver);
283 conn.open(pSite->strDbConnect);
284 __DCL_TRACE1(L"database server info: %ls\n",
285 conn.getServerInfo().data());
286 try {
287 if (conn.canTransact()) {
288 conn.startTrans();
289 }
290
291 SQLQuery query(&conn);
292
293 Session session(ctx, query, nServiceUserID);
294 session.check();
295
296 HtmlPage page(nPageID, pSite);
297
299 L"nPageID: %d, nPermID: %d, RoleID: %d\n",
300 page.__nPageID,
301 page.__nPermID,
302 session.__nRoleID
303 );
304
305 if (page.init(query)) {
306#define __PERMITTED 0
307#define __DENIED 1
308#define __YET_GROUP 2
309#define __PENDING_GROUP 3
310
311 //int fAuth = __PERMITTED;
312 int fAuth = __DENIED;
313
315 fAuth = __PERMITTED;
316 else if (session.__nRoleID != Session::GUEST_ROLE_ID) {
317 if (nServiceUserID == Session::SYSTEM_USER_ID) {
318 if (page.__nPermID >= session.__nRoleID)
319 fAuth = __PERMITTED;
320 }
321 else {
322 if (session.getMemberRole(nServiceUserID)) {
323 if (page.__nPermID >= session.__nMemberRoleID)
324 fAuth = __PERMITTED;
325 else if (session.__nMemberRoleID == Session::GUEST_ROLE_ID)
326 fAuth = __PENDING_GROUP;
327 }
328 else
329 fAuth = __YET_GROUP;
330 }
331 }
332
333 switch (fAuth) {
334 case __PERMITTED: {
335 page.invoke(session);
336 break;
337 }
338 case __YET_GROUP:
339 case __PENDING_GROUP:
340 case __DENIED:
341 default: {
342 HtmlPage permDenied(
343 pSite->nPermDeniedPageID,
344 pSite
345 );
346 permDenied.init(query);
347 permDenied.print(session);
348 }
349 }
350 }
351 else {
352 page.printError(session, L"페이지 없음", L"요청하신 페이지가 없습니다.");
353 }
354
355 if (conn.inTransaction()) {
356 conn.commitTrans();
357 }
358 }
359 catch (Exception* _e) {
360 if (conn.inTransaction()) {
361 conn.rollbackTrans();
362 }
363 throw _e;
364 }
365
367
368 if (ctx.resContentType().compareNoCase(L"text", 4) == 0) {
369 ctx.writer() << L"<div>Elapsed Time: "
370 << (dtEnd - dtStart).toString()
371 << L"</div>\n";
372 }
373}
374
375__DCL_END_NAMESPACE
376
377#ifdef __WINNT_NEW_DELETE_OVERRIDE
378#undef new
379__WINNT_NEW_DELETE_OVERRIDE
380#endif
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
#define INI_FILENAME
@ HTTP_METHOD_POST
@ HTTP_METHOD_GET
@ HTTP_STATUS_NOT_IMPLEMENTED
@ HTTP_STATUS_NOT_FOUND
#define HTTP_SERVLET_INSTANCE(ServletClass, Description)
#define __DCL_TRACE0(psz)
Definition Object.h:398
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
Definition Object.h:401
#define DECLARE_CLASSINFO(class_name)
Definition Object.h:227
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __DCL_TRACE2(fmt, arg1, arg2)
Definition Object.h:400
#define __DENIED
#define __YET_GROUP
#define __PERMITTED
#define __PENDING_GROUP
static String decode(const char *_mbs, size_t _mbslen=(size_t) -1)
static DateTime getCurrentLocalTime()
Definition DateTime.cpp:954
virtual void destroy()
Definition Exception.cpp:74
Exception(Exception *_cause=NULL)
__DCL_THROWS1(Exception *)
virtual void onCleanup()
StringToPointerMap __mapSiteCtx
Definition ServletMain.h:55
virtual void onInitialize()
PointerList __listSiteCtx
Definition ServletMain.h:54
virtual void onService(HttpServletContextEx &ctx)
int __nPermID
Definition HtmlPage.h:33
void invoke(Session &session) __DCL_THROWS1(Exception *)
Definition HtmlPage.cpp:154
void print(Session &session) __DCL_THROWS1(Exception *)
Definition HtmlPage.cpp:101
int __nPageID
Definition HtmlPage.h:32
void printError(Session &session, const String &strTitle, const String &strMessage)
Definition HtmlPage.cpp:218
bool init(SQLQuery &q) __DCL_THROWS1(SQLException *)
Definition HtmlPage.cpp:40
virtual void onInitialize() __DCL_THROWS1(Exception *)
virtual void onCleanup() __DCL_THROWS1(Exception *)
static int parse(const wchar_t *_number, unsigned _base=10) __DCL_THROWS1(NumericConvertException *)
Definition Numeric.inl:36
virtual String toString() const
Definition Object.cpp:187
void open(const String &_connstr) __DCL_THROWS1(SQLException *)
String getServerInfo() __DCL_THROWS1(SQLException *)
bool canTransact() const
void rollbackTrans() __DCL_THROWS1(SQLException *)
bool inTransaction() const
void commitTrans() __DCL_THROWS1(SQLException *)
void startTrans() __DCL_THROWS1(SQLException *)
bool getMemberRole(int nServiceUserID)
Definition Session.cpp:223
@ GUEST_ROLE_ID
Definition Session.h:28
@ SYSTEM_USER_ID
Definition Session.h:20
int __nRoleID
Definition Session.h:35
void check()
Definition Session.cpp:106
int __nMemberRoleID
Definition Session.h:39
static unsigned int parse(const wchar_t *_number, unsigned _base=10) __DCL_THROWS1(NumericConvertException *)
Definition Numeric.inl:72
String strSkinDir
Definition ServletMain.h:31
String strAttachmentDir
Definition ServletMain.h:32
size_t uPostMaxLength
Definition ServletMain.h:23
String strDbConnect
Definition ServletMain.h:26
String strThumbnailDir
Definition ServletMain.h:33
String strDbDriver
Definition ServletMain.h:25
const SiteContext & operator=(const SiteContext &src)
String strSiteID
Definition ServletMain.h:22
int nPermDeniedPageID
Definition ServletMain.h:29