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