xref: /haiku/headers/private/netservices/HttpForm.h (revision 52c4471a3024d2eb81fe88e2c3982b9f8daa5e56)
1 /*
2  * Copyright 2010-2013 Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _B_HTTP_FORM_H_
6 #define _B_HTTP_FORM_H_
7 
8 
9 #include <Path.h>
10 #include <String.h>
11 
12 #include <map>
13 
14 
15 namespace BPrivate {
16 
17 namespace Network {
18 
19 
20 enum form_type {
21 	B_HTTP_FORM_URL_ENCODED,
22 	B_HTTP_FORM_MULTIPART
23 };
24 
25 
26 enum form_content_type {
27 	B_HTTPFORM_UNKNOWN,
28 	B_HTTPFORM_STRING,
29 	B_HTTPFORM_FILE,
30 	B_HTTPFORM_BUFFER
31 };
32 
33 
34 class BHttpFormData {
35 private:
36 	// Empty constructor is only kept for compatibility with map<>::operator[],
37 	// but never used (see BHttpForm::operator[] which does the necessary
38 	// check up)
39 								BHttpFormData();
40 #if (__GNUC__ >= 6) || defined(__clang__)
41 	friend class std::pair<const BString, BHttpFormData>;
42 #else
43 	friend class std::map<BString, BHttpFormData>;
44 #endif
45 
46 public:
47 								BHttpFormData(const BString& name,
48 									const BString& value);
49 								BHttpFormData(const BString& name,
50 									const BPath& file);
51 								BHttpFormData(const BString& name,
52 									const void* buffer, ssize_t size);
53 								BHttpFormData(const BHttpFormData& other);
54 								~BHttpFormData();
55 
56 	// Retrieve data informations
57 			bool				InitCheck() const;
58 
59 			const BString&		Name() const;
60 			const BString&		String() const;
61 			const BPath&		File() const;
62 			const void*			Buffer() const;
63 			ssize_t				BufferSize() const;
64 
65 			bool				IsFile() const;
66 			const BString&		Filename() const;
67 			const BString&		MimeType() const;
68 			form_content_type	Type() const;
69 
70 	// Change behavior
71 			status_t			MarkAsFile(const BString& filename,
72 									const BString& mimeType = "");
73 			void				UnmarkAsFile();
74 			status_t			CopyBuffer();
75 
76 	// Overloaded operators
77 			BHttpFormData&		operator=(const BHttpFormData& other);
78 
79 private:
80 			form_content_type	fDataType;
81 			bool				fCopiedBuffer;
82 			bool				fFileMark;
83 
84 			BString				fName;
85 			BString				fStringValue;
86 			BPath				fPathValue;
87 			const void*			fBufferValue;
88 			ssize_t				fBufferSize;
89 
90 			BString				fFilename;
91 			BString				fMimeType;
92 };
93 
94 
95 class BHttpForm {
96 public:
97 	// Nested types
98 	class Iterator;
99 	typedef std::map<BString, BHttpFormData> FormStorage;
100 
101 public:
102 								BHttpForm();
103 								BHttpForm(const BHttpForm& other);
104 								BHttpForm(const BString& formString);
105 								~BHttpForm();
106 
107 	// Form string parsing
108 			void				ParseString(const BString& formString);
109 			BString				RawData() const;
110 
111 	// Form add
112 			status_t			AddString(const BString& name,
113 									const BString& value);
114 			status_t			AddInt(const BString& name, int32 value);
115 			status_t			AddFile(const BString& fieldName,
116 									const BPath& file);
117 			status_t			AddBuffer(const BString& fieldName,
118 									const void* buffer, ssize_t size);
119 			status_t			AddBufferCopy(const BString& fieldName,
120 									const void* buffer, ssize_t size);
121 
122 	// Mark a field as a filename
123 			void				MarkAsFile(const BString& fieldName,
124 									const BString& filename,
125 									const BString& mimeType);
126 			void				MarkAsFile(const BString& fieldName,
127 									const BString& filename);
128 			void				UnmarkAsFile(const BString& fieldName);
129 
130 	// Change form type
131 			void				SetFormType(form_type type);
132 
133 	// Form test
134 			bool				HasField(const BString& name) const;
135 
136 	// Form retrieve
137 			BString				GetMultipartHeader(const BString& fieldName) const;
138 			form_content_type	GetType(const BString& fieldname) const;
139 
140 	// Form informations
141 			form_type			GetFormType() const;
142 			const BString&		GetMultipartBoundary() const;
143 			BString				GetMultipartFooter() const;
144 			ssize_t				ContentLength() const;
145 
146 	// Form iterator
147 			Iterator			GetIterator();
148 
149 	// Form clear
150 			void				Clear();
151 
152 	// Overloaded operators
153 			BHttpFormData&		operator[](const BString& name);
154 
155 private:
156 			void				_ExtractNameValuePair(const BString& string, int32* index);
157 			void				_GenerateMultipartBoundary();
158 			BString				_GetMultipartHeader(const BHttpFormData* element) const;
159 			form_content_type	_GetType(FormStorage::const_iterator it) const;
160 			void				_Erase(FormStorage::iterator it);
161 
162 private:
163 	friend	class Iterator;
164 
165 			FormStorage			fFields;
166 			form_type			fType;
167 			BString				fMultipartBoundary;
168 };
169 
170 
171 class BHttpForm::Iterator {
172 public:
173 								Iterator(const Iterator& other);
174 
175 			BHttpFormData*		Next();
176 			bool 				HasNext() const;
177 			void				Remove();
178 			BString				MultipartHeader();
179 
180 			Iterator& 			operator=(const Iterator& other);
181 
182 private:
183 								Iterator(BHttpForm* form);
184 			void				_FindNext();
185 
186 private:
187 	friend	class BHttpForm;
188 
189 			BHttpForm*			fForm;
190 			BHttpForm::FormStorage::iterator
191 								fStdIterator;
192 			BHttpFormData*		fElement;
193 			BHttpFormData*		fPrevElement;
194 };
195 
196 
197 } // namespace Network
198 
199 } // namespace BPrivate
200 
201 #endif // _B_HTTP_FORM_H_
202