~ubuntu-branches/ubuntu/maverick/znc/maverick

« back to all changes in this revision

Viewing changes to HTTPSock.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Matthäi
  • Date: 2010-05-24 18:05:44 UTC
  • mfrom: (1.3.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100524180544-8e4s3f4nj0lhyw7n
Tags: 0.090~rc1-1
* New upstream release candidate.
  - Drop znc-webadmin package. It is now provided in the core source code.
  - Rename discon_kick module to disconkick.
  - Add charset and notes module.
* Add missing dependency on libc-ares-dev to znc-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 * by the Free Software Foundation.
7
7
 */
8
8
 
9
 
#ifdef _MODULES
10
 
 
11
9
#include "Modules.h"
12
10
#include "HTTPSock.h"
13
11
#include "znc.h"
36
34
 
37
35
CHTTPSock::~CHTTPSock() {}
38
36
 
39
 
void CHTTPSock::ReadData(const char* data, int len) {
 
37
void CHTTPSock::ReadData(const char* data, size_t len) {
40
38
        if (!m_bDone && m_bGotHeader && m_bPost) {
41
39
                m_sPostData.append(data, len);
42
40
                CheckPost();
43
41
        }
44
42
}
45
43
 
 
44
bool CHTTPSock::SendCookie(const CString& sKey, const CString& sValue) {
 
45
        if (!sKey.empty() && !sValue.empty()) {
 
46
                if (m_msRequestCookies.find(sKey) == m_msRequestCookies.end() ||
 
47
                        m_msRequestCookies[sKey].StrCmp(sValue) != 0)
 
48
                {
 
49
                        m_msResponseCookies[sKey] = sValue;
 
50
                }
 
51
                return true;
 
52
        }
 
53
 
 
54
        return false;
 
55
}
 
56
 
 
57
const MCString& CHTTPSock::GetRequestCookies() const {
 
58
        return m_msRequestCookies;
 
59
}
 
60
 
 
61
CString CHTTPSock::GetRequestCookie(const CString& sKey) const {
 
62
        MCString::const_iterator it = m_msRequestCookies.find(sKey);
 
63
 
 
64
        return it != m_msRequestCookies.end() ? it->second : "";
 
65
}
 
66
 
46
67
void CHTTPSock::CheckPost() {
47
68
        if (m_sPostData.size() >= m_uPostLen) {
48
 
                ParseParams(m_sPostData.Left(m_uPostLen));
 
69
                ParseParams(m_sPostData.Left(m_uPostLen), m_msvsPOSTParams);
49
70
                GetPage();
50
71
                m_sPostData.clear();
51
72
                m_bDone = true;
52
 
                Close(Csock::CLT_AFTERWRITE);
53
73
        }
54
74
}
55
75
 
72
92
                m_bPost = true;
73
93
                m_sURI = sLine.Token(1);
74
94
                ParseURI();
 
95
        } else if (sName.Equals("Cookie:")) {
 
96
                VCString vsNV;
 
97
 
 
98
                sLine.Token(1, true).Split(";", vsNV, false, "", "", true, true);
 
99
 
 
100
                for (unsigned int a = 0; a < vsNV.size(); a++) {
 
101
                        CString s(vsNV[a]);
 
102
 
 
103
                        m_msRequestCookies[s.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII)] =
 
104
                                s.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII);
 
105
                }
75
106
        } else if (sName.Equals("Authorization:")) {
76
107
                CString sUnhashed;
77
108
                sLine.Token(2).Base64Decode(sUnhashed);
99
130
}
100
131
 
101
132
void CHTTPSock::GetPage() {
102
 
        CString sPage;
103
 
 
104
133
        DEBUG("Page Request [" << m_sURI << "] ");
105
134
 
106
 
        if (!OnPageRequest(m_sURI, sPage)) {
107
 
                PrintNotFound();
108
 
                return;
109
 
        }
 
135
        OnPageRequest(m_sURI);
 
136
}
110
137
 
 
138
void CHTTPSock::PrintPage(const CString& sPage) {
111
139
        if (!SentHeader()) {
112
140
                PrintHeader(sPage.length());
 
141
        } else {
 
142
                DEBUG("PrintPage(): Header was already sent");
113
143
        }
114
144
 
115
145
        Write(sPage);
215
245
}
216
246
 
217
247
void CHTTPSock::ParseURI() {
218
 
        ParseParams(m_sURI.Token(1, true, "?"));
 
248
        ParseParams(m_sURI.Token(1, true, "?"), m_msvsGETParams);
219
249
        m_sURI = m_sURI.Token(0, false, "?");
220
250
}
221
251
 
223
253
        return m_sURI.Token(0, false, "?");
224
254
}
225
255
 
226
 
void CHTTPSock::ParseParams(const CString& sParams) {
227
 
        m_msvsParams.clear();
 
256
void CHTTPSock::ParseParams(const CString& sParams, map<CString, VCString> &msvsParams) {
 
257
        msvsParams.clear();
228
258
 
229
259
        VCString vsPairs;
230
260
        sParams.Split("&", vsPairs, true);
234
264
                CString sName = sPair.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII);
235
265
                CString sValue = sPair.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII);
236
266
 
237
 
                m_msvsParams[sName].push_back(sValue);
 
267
                msvsParams[sName].push_back(sValue);
238
268
        }
239
269
}
240
270
 
263
293
        return m_sPostData;
264
294
}
265
295
 
266
 
bool CHTTPSock::HasParam(const CString& sName) const {
267
 
        return (m_msvsParams.find(sName) != m_msvsParams.end());
268
 
}
269
 
 
270
 
CString CHTTPSock::GetRawParam(const CString& sName) const {
 
296
bool CHTTPSock::HasParam(const CString& sName, bool bPost) const {
 
297
        if (bPost)
 
298
                return (m_msvsPOSTParams.find(sName) != m_msvsPOSTParams.end());
 
299
        return (m_msvsGETParams.find(sName) != m_msvsGETParams.end());
 
300
}
 
301
 
 
302
CString CHTTPSock::GetRawParam(const CString& sName, bool bPost) const {
 
303
        if (bPost)
 
304
                return GetRawParam(sName, m_msvsPOSTParams);
 
305
        return GetRawParam(sName, m_msvsGETParams);
 
306
}
 
307
 
 
308
CString CHTTPSock::GetRawParam(const CString& sName, const map<CString, VCString>& msvsParams) {
271
309
        CString sRet;
272
310
 
273
 
        map<CString, VCString>::const_iterator it = m_msvsParams.find(sName);
 
311
        map<CString, VCString>::const_iterator it = msvsParams.find(sName);
274
312
 
275
 
        if (it != m_msvsParams.end() && it->second.size() > 0) {
 
313
        if (it != msvsParams.end() && it->second.size() > 0) {
276
314
                sRet = it->second[0];
277
315
        }
278
316
 
279
317
        return sRet;
280
318
}
281
319
 
282
 
CString CHTTPSock::GetParam(const CString& sName, const CString& sFilter) const {
283
 
        CString sRet = GetRawParam(sName);
 
320
CString CHTTPSock::GetParam(const CString& sName, bool bPost, const CString& sFilter) const {
 
321
        if (bPost)
 
322
                return GetParam(sName, m_msvsPOSTParams, sFilter);
 
323
        return GetParam(sName, m_msvsGETParams, sFilter);
 
324
}
 
325
 
 
326
CString CHTTPSock::GetParam(const CString& sName, const map<CString, VCString>& msvsParams, const CString& sFilter) {
 
327
        CString sRet = GetRawParam(sName, msvsParams);
 
328
        sRet.Trim();
284
329
 
285
330
        for (size_t i = 0; i < sFilter.length(); i++) {
286
331
                sRet.Replace(CString(sFilter.at(i)), "");
289
334
        return sRet;
290
335
}
291
336
 
292
 
unsigned int CHTTPSock::GetParamValues(const CString& sName, set<CString>& ssRet, const CString& sFilter) const {
 
337
unsigned int CHTTPSock::GetParamValues(const CString& sName, set<CString>& ssRet, bool bPost, const CString& sFilter) const {
 
338
        if (bPost)
 
339
                return GetParamValues(sName, ssRet, m_msvsPOSTParams, sFilter);
 
340
        return GetParamValues(sName, ssRet, m_msvsGETParams, sFilter);
 
341
}
 
342
 
 
343
unsigned int CHTTPSock::GetParamValues(const CString& sName, set<CString>& ssRet, const map<CString, VCString>& msvsParams, const CString& sFilter) {
293
344
        ssRet.clear();
294
345
 
295
 
        map<CString, VCString>::const_iterator it = m_msvsParams.find(sName);
 
346
        map<CString, VCString>::const_iterator it = msvsParams.find(sName);
296
347
 
297
 
        if (it != m_msvsParams.end()) {
 
348
        if (it != msvsParams.end()) {
298
349
                for (unsigned int a = 0; a < it->second.size(); a++) {
299
350
                        CString sParam = it->second[a];
 
351
                        sParam.Trim();
300
352
 
301
353
                        for (size_t i = 0; i < sFilter.length(); i++) {
302
354
                                sParam.Replace(CString(sFilter.at(i)), "");
308
360
        return ssRet.size();
309
361
}
310
362
 
311
 
unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const CString& sFilter) const {
 
363
unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, bool bPost, const CString& sFilter) const {
 
364
        if (bPost)
 
365
                return GetParamValues(sName, vsRet, m_msvsPOSTParams, sFilter);
 
366
        return GetParamValues(sName, vsRet, m_msvsGETParams, sFilter);
 
367
}
 
368
 
 
369
unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const map<CString, VCString>& msvsParams, const CString& sFilter) {
312
370
        vsRet.clear();
313
371
 
314
 
        map<CString, VCString>::const_iterator it = m_msvsParams.find(sName);
 
372
        map<CString, VCString>::const_iterator it = msvsParams.find(sName);
315
373
 
316
 
        if (it != m_msvsParams.end()) {
 
374
        if (it != msvsParams.end()) {
317
375
                for (unsigned int a = 0; a < it->second.size(); a++) {
318
376
                        CString sParam = it->second[a];
 
377
                        sParam.Trim();
319
378
 
320
379
                        for (size_t i = 0; i < sFilter.length(); i++) {
321
380
                                sParam.Replace(CString(sFilter.at(i)), "");
327
386
        return vsRet.size();
328
387
}
329
388
 
330
 
const map<CString, VCString>& CHTTPSock::GetParams() const {
331
 
        return m_msvsParams;
 
389
const map<CString, VCString>& CHTTPSock::GetParams(bool bPost) const {
 
390
        if (bPost)
 
391
                return m_msvsPOSTParams;
 
392
        return m_msvsGETParams;
 
393
}
 
394
 
 
395
bool CHTTPSock::IsPost() const {
 
396
        return m_bPost;
332
397
}
333
398
 
334
399
bool CHTTPSock::PrintNotFound() {
337
402
 
338
403
bool CHTTPSock::PrintErrorPage(unsigned int uStatusId, const CString& sStatusMsg, const CString& sMessage) {
339
404
        if (SentHeader()) {
 
405
                DEBUG("PrintErrorPage(): Header was already sent");
340
406
                return false;
341
407
        }
342
408
 
353
419
                "<html><head>\r\n<title>" + CString(uStatusId) + " " + sStatusMsg.Escape_n(CString::EHTML) + "</title>\r\n"
354
420
                "</head><body>\r\n<h1>" + sStatusMsg.Escape_n(CString::EHTML) + "</h1>\r\n"
355
421
                "<p>" + sMessage.Escape_n(CString::EHTML) + "</p>\r\n"
356
 
                "<hr>\r\n<address>" + CZNC::GetTag().Escape_n(CString::EHTML) + " at " + GetLocalIP().Escape_n(CString::EHTML) + " Port " + CString(GetLocalPort()) + "</address>\r\n"
 
422
                "<hr />\r\n<address>" + CZNC::GetTag(false).Escape_n(CString::EHTML) + " at " + GetLocalIP().Escape_n(CString::EHTML) + " Port " + CString(GetLocalPort()) + "</address>\r\n"
357
423
                "</body></html>\r\n";
358
424
}
359
425
 
363
429
        }
364
430
 
365
431
        if (SentHeader()) {
 
432
                DEBUG("ForceLogin(): Header was already sent!");
366
433
                return false;
367
434
        }
368
435
 
385
452
 
386
453
bool CHTTPSock::PrintHeader(off_t uContentLength, const CString& sContentType, unsigned int uStatusId, const CString& sStatusMsg) {
387
454
        if (SentHeader()) {
388
 
                DEBUG("- Header already sent!");
 
455
                DEBUG("PrintHeader(): Header was already sent!");
389
456
                return false;
390
457
        }
391
458
 
401
468
 
402
469
        Write("HTTP/" + CString(m_bHTTP10Client ? "1.0 " : "1.1 ") + CString(uStatusId) + " " + sStatusMsg + "\r\n");
403
470
        //Write("Date: Tue, 28 Jun 2005 20:45:36 GMT\r\n");
404
 
        Write("Server: " + CZNC::GetTag() + "\r\n");
 
471
        Write("Server: " + CZNC::GetTag(false) + "\r\n");
405
472
        if (uContentLength > 0) {
406
473
                Write("Content-Length: " + CString(uContentLength) + "\r\n");
407
474
        }
408
475
        Write("Content-Type: " + m_sContentType + "\r\n");
409
476
 
410
 
        for (MCString::iterator it = m_msHeaders.begin(); it != m_msHeaders.end(); it++) {
 
477
        MCString::iterator it;
 
478
 
 
479
        for (it = m_msResponseCookies.begin(); it != m_msResponseCookies.end(); ++it) {
 
480
                Write("Set-Cookie: " + it->first.Escape_n(CString::EURL) + "=" + it->second.Escape_n(CString::EURL) + "; path=/;\r\n");
 
481
        }
 
482
 
 
483
        for (it = m_msHeaders.begin(); it != m_msHeaders.end(); ++it) {
411
484
                Write(it->first + ": " + it->second + "\r\n");
412
485
        }
413
486
 
429
502
 
430
503
bool CHTTPSock::Redirect(const CString& sURL) {
431
504
        if (SentHeader()) {
 
505
                DEBUG("Redirect() - Header was already sent");
432
506
                return false;
433
507
        }
434
508
 
459
533
        DEBUG(GetSockName() << " == ReachedMaxBuffer()");
460
534
        Close();
461
535
}
462
 
 
463
 
#endif // _MODULES