1 #ifndef _HEADER_H
2 #define _HEADER_H
3
4 #include <string>
5 #include <unordered_set>
6 #include <map>
7 #include "meta.h"
8
9 namespace acng
10 {
11
12 class header {
13 public:
14 enum eHeadType : char
15 {
16 INVALID,
17 HEAD,
18 GET,
19 POST,
20 CONNECT,
21 ANSWER
22 };
23 enum eHeadPos : char
24 {
25 CONNECTION, // 0
26 CONTENT_LENGTH,
27 IF_MODIFIED_SINCE,
28 RANGE,
29 IFRANGE, // 4
30 CONTENT_RANGE,
31 LAST_MODIFIED,
32 PROXY_CONNECTION,
33 TRANSFER_ENCODING,
34 XORIG,
35 AUTHORIZATION, // 10
36 XFORWARDEDFOR,
37 LOCATION,
38 CONTENT_TYPE,
39 // unreachable entry and size reference
40 HEADPOS_MAX,
41 HEADPOS_NOTFORUS
42 };
43 #define ACNGFSMARK XORIG
44
45 eHeadType type = INVALID;
46 mstring frontLine;
47
48 char *h[HEADPOS_MAX] = {0};
49
header()50 inline header(){};
51 ~header();
52 header(const header &);
53 header& operator=(const header&);
54
55 static mstring GenInfoHeaders();
56 static bool ParseDate(const char *, struct tm*);
57
58 int LoadFromFile(const mstring & sPath);
59
60 //! returns byte count or negative errno value
61 int StoreToFile(cmstring &sPath) const;
62
63 void set(eHeadPos, const mstring &value);
64 void set(eHeadPos, const char *val);
65 void set(eHeadPos, const char *s, size_t len);
66 void set(eHeadPos, off_t nValue);
67 void prep(eHeadPos, size_t length);
68 void del(eHeadPos);
copy(const header & src,eHeadPos pos)69 inline void copy(const header &src, eHeadPos pos) { set(pos, src.h[pos]); };
70
getCodeMessage()71 inline const char * getCodeMessage() const {
72 return frontLine.length()>9 ? frontLine.c_str()+9 : "";
73 }
getStatus()74 inline int getStatus() const { int r=atoi(getCodeMessage()); return r ? r : 500; }
75 void clear();
76
77 tSS ToString() const;
78 static std::vector<tPtrLen> GetKnownHeaders();
79 /**
80 * Read buffer to parse one string. Optional offset where to begin to
81 * scan.
82 *
83 * @param src Pointer to raw input
84 * @param length Maximum considered input length
85 * @param unkFunc Optional callback for ignored headers (called with key name and rest of the line including CRLF)
86 * @return Length of processed data,
87 * 0: incomplete, needs more data
88 * <0: error
89 * >0: length of the processed data
90 */
91 // XXX: maybe redesign the unkFunc to just use pointer and length instead of strings
92 int Load(const char *src, unsigned length, const std::function<void(cmstring&, cmstring&)> &unkFunc = std::function<void(cmstring&, cmstring&)>());
93 };
94
BODYFREECODE(int status)95 inline bool BODYFREECODE(int status)
96 {
97 // no response if not-modified or similar, following http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
98 return (304 == status || (status>=100 && status<200) || 204==status);
99 }
100
101 }
102
103 #endif
104