xref: /haiku/headers/private/netservices/HttpForm.h (revision 70b63f18b32a7ae90e4ff49659ba3844ce4c9aa5)
1603e0bdfSNiels Sascha Reedijk /*
2603e0bdfSNiels Sascha Reedijk  * Copyright 2010-2013 Haiku Inc. All rights reserved.
3603e0bdfSNiels Sascha Reedijk  * Distributed under the terms of the MIT License.
4603e0bdfSNiels Sascha Reedijk  */
5603e0bdfSNiels Sascha Reedijk #ifndef _B_HTTP_FORM_H_
6603e0bdfSNiels Sascha Reedijk #define _B_HTTP_FORM_H_
7603e0bdfSNiels Sascha Reedijk 
8603e0bdfSNiels Sascha Reedijk 
9603e0bdfSNiels Sascha Reedijk #include <Path.h>
10603e0bdfSNiels Sascha Reedijk #include <String.h>
11603e0bdfSNiels Sascha Reedijk 
12603e0bdfSNiels Sascha Reedijk #include <map>
13603e0bdfSNiels Sascha Reedijk 
14603e0bdfSNiels Sascha Reedijk 
15ce64ffdbSNiels Sascha Reedijk namespace BPrivate {
16ce64ffdbSNiels Sascha Reedijk 
17ce64ffdbSNiels Sascha Reedijk namespace Network {
18*70b63f18SNiels Sascha Reedijk 
19ce64ffdbSNiels Sascha Reedijk 
20603e0bdfSNiels Sascha Reedijk enum form_type {
21603e0bdfSNiels Sascha Reedijk 	B_HTTP_FORM_URL_ENCODED,
22603e0bdfSNiels Sascha Reedijk 	B_HTTP_FORM_MULTIPART
23603e0bdfSNiels Sascha Reedijk };
24603e0bdfSNiels Sascha Reedijk 
25603e0bdfSNiels Sascha Reedijk 
26603e0bdfSNiels Sascha Reedijk enum form_content_type {
27603e0bdfSNiels Sascha Reedijk 	B_HTTPFORM_UNKNOWN,
28603e0bdfSNiels Sascha Reedijk 	B_HTTPFORM_STRING,
29603e0bdfSNiels Sascha Reedijk 	B_HTTPFORM_FILE,
30603e0bdfSNiels Sascha Reedijk 	B_HTTPFORM_BUFFER
31603e0bdfSNiels Sascha Reedijk };
32603e0bdfSNiels Sascha Reedijk 
33603e0bdfSNiels Sascha Reedijk 
34603e0bdfSNiels Sascha Reedijk class BHttpFormData {
35603e0bdfSNiels Sascha Reedijk private:
36603e0bdfSNiels Sascha Reedijk 	// Empty constructor is only kept for compatibility with map<>::operator[],
37603e0bdfSNiels Sascha Reedijk 	// but never used (see BHttpForm::operator[] which does the necessary
38603e0bdfSNiels Sascha Reedijk 	// check up)
39603e0bdfSNiels Sascha Reedijk 								BHttpFormData();
40603e0bdfSNiels Sascha Reedijk #if (__GNUC__ >= 6) || defined(__clang__)
41603e0bdfSNiels Sascha Reedijk 	friend class std::pair<const BString, BHttpFormData>;
42603e0bdfSNiels Sascha Reedijk #else
43603e0bdfSNiels Sascha Reedijk 	friend class std::map<BString, BHttpFormData>;
44603e0bdfSNiels Sascha Reedijk #endif
45603e0bdfSNiels Sascha Reedijk 
46603e0bdfSNiels Sascha Reedijk public:
47603e0bdfSNiels Sascha Reedijk 								BHttpFormData(const BString& name,
48603e0bdfSNiels Sascha Reedijk 									const BString& value);
49603e0bdfSNiels Sascha Reedijk 								BHttpFormData(const BString& name,
50603e0bdfSNiels Sascha Reedijk 									const BPath& file);
51603e0bdfSNiels Sascha Reedijk 								BHttpFormData(const BString& name,
52603e0bdfSNiels Sascha Reedijk 									const void* buffer, ssize_t size);
53603e0bdfSNiels Sascha Reedijk 								BHttpFormData(const BHttpFormData& other);
54603e0bdfSNiels Sascha Reedijk 								~BHttpFormData();
55603e0bdfSNiels Sascha Reedijk 
56603e0bdfSNiels Sascha Reedijk 	// Retrieve data informations
57603e0bdfSNiels Sascha Reedijk 			bool				InitCheck() const;
58603e0bdfSNiels Sascha Reedijk 
59603e0bdfSNiels Sascha Reedijk 			const BString&		Name() const;
60603e0bdfSNiels Sascha Reedijk 			const BString&		String() const;
61603e0bdfSNiels Sascha Reedijk 			const BPath&		File() const;
62603e0bdfSNiels Sascha Reedijk 			const void*			Buffer() const;
63603e0bdfSNiels Sascha Reedijk 			ssize_t				BufferSize() const;
64603e0bdfSNiels Sascha Reedijk 
65603e0bdfSNiels Sascha Reedijk 			bool				IsFile() const;
66603e0bdfSNiels Sascha Reedijk 			const BString&		Filename() const;
67603e0bdfSNiels Sascha Reedijk 			const BString&		MimeType() const;
68603e0bdfSNiels Sascha Reedijk 			form_content_type	Type() const;
69603e0bdfSNiels Sascha Reedijk 
70603e0bdfSNiels Sascha Reedijk 	// Change behavior
71603e0bdfSNiels Sascha Reedijk 			status_t			MarkAsFile(const BString& filename,
72603e0bdfSNiels Sascha Reedijk 									const BString& mimeType = "");
73603e0bdfSNiels Sascha Reedijk 			void				UnmarkAsFile();
74603e0bdfSNiels Sascha Reedijk 			status_t			CopyBuffer();
75603e0bdfSNiels Sascha Reedijk 
76603e0bdfSNiels Sascha Reedijk 	// Overloaded operators
77603e0bdfSNiels Sascha Reedijk 			BHttpFormData&		operator=(const BHttpFormData& other);
78603e0bdfSNiels Sascha Reedijk 
79603e0bdfSNiels Sascha Reedijk private:
80603e0bdfSNiels Sascha Reedijk 			form_content_type	fDataType;
81603e0bdfSNiels Sascha Reedijk 			bool				fCopiedBuffer;
82603e0bdfSNiels Sascha Reedijk 			bool				fFileMark;
83603e0bdfSNiels Sascha Reedijk 
84603e0bdfSNiels Sascha Reedijk 			BString				fName;
85603e0bdfSNiels Sascha Reedijk 			BString				fStringValue;
86603e0bdfSNiels Sascha Reedijk 			BPath				fPathValue;
87603e0bdfSNiels Sascha Reedijk 			const void*			fBufferValue;
88603e0bdfSNiels Sascha Reedijk 			ssize_t				fBufferSize;
89603e0bdfSNiels Sascha Reedijk 
90603e0bdfSNiels Sascha Reedijk 			BString				fFilename;
91603e0bdfSNiels Sascha Reedijk 			BString				fMimeType;
92603e0bdfSNiels Sascha Reedijk };
93603e0bdfSNiels Sascha Reedijk 
94603e0bdfSNiels Sascha Reedijk 
95603e0bdfSNiels Sascha Reedijk class BHttpForm {
96603e0bdfSNiels Sascha Reedijk public:
97603e0bdfSNiels Sascha Reedijk 	// Nested types
98603e0bdfSNiels Sascha Reedijk 	class Iterator;
99603e0bdfSNiels Sascha Reedijk 	typedef std::map<BString, BHttpFormData> FormStorage;
100603e0bdfSNiels Sascha Reedijk 
101603e0bdfSNiels Sascha Reedijk public:
102603e0bdfSNiels Sascha Reedijk 								BHttpForm();
103603e0bdfSNiels Sascha Reedijk 								BHttpForm(const BHttpForm& other);
104603e0bdfSNiels Sascha Reedijk 								BHttpForm(const BString& formString);
105603e0bdfSNiels Sascha Reedijk 								~BHttpForm();
106603e0bdfSNiels Sascha Reedijk 
107603e0bdfSNiels Sascha Reedijk 	// Form string parsing
108603e0bdfSNiels Sascha Reedijk 			void				ParseString(const BString& formString);
109603e0bdfSNiels Sascha Reedijk 			BString				RawData() const;
110603e0bdfSNiels Sascha Reedijk 
111603e0bdfSNiels Sascha Reedijk 	// Form add
112603e0bdfSNiels Sascha Reedijk 			status_t			AddString(const BString& name,
113603e0bdfSNiels Sascha Reedijk 									const BString& value);
114603e0bdfSNiels Sascha Reedijk 			status_t			AddInt(const BString& name, int32 value);
115603e0bdfSNiels Sascha Reedijk 			status_t			AddFile(const BString& fieldName,
116603e0bdfSNiels Sascha Reedijk 									const BPath& file);
117603e0bdfSNiels Sascha Reedijk 			status_t			AddBuffer(const BString& fieldName,
118603e0bdfSNiels Sascha Reedijk 									const void* buffer, ssize_t size);
119603e0bdfSNiels Sascha Reedijk 			status_t			AddBufferCopy(const BString& fieldName,
120603e0bdfSNiels Sascha Reedijk 									const void* buffer, ssize_t size);
121603e0bdfSNiels Sascha Reedijk 
122603e0bdfSNiels Sascha Reedijk 	// Mark a field as a filename
123603e0bdfSNiels Sascha Reedijk 			void				MarkAsFile(const BString& fieldName,
124603e0bdfSNiels Sascha Reedijk 									const BString& filename,
125603e0bdfSNiels Sascha Reedijk 									const BString& mimeType);
126603e0bdfSNiels Sascha Reedijk 			void				MarkAsFile(const BString& fieldName,
127603e0bdfSNiels Sascha Reedijk 									const BString& filename);
128603e0bdfSNiels Sascha Reedijk 			void				UnmarkAsFile(const BString& fieldName);
129603e0bdfSNiels Sascha Reedijk 
130603e0bdfSNiels Sascha Reedijk 	// Change form type
131603e0bdfSNiels Sascha Reedijk 			void				SetFormType(form_type type);
132603e0bdfSNiels Sascha Reedijk 
133603e0bdfSNiels Sascha Reedijk 	// Form test
134603e0bdfSNiels Sascha Reedijk 			bool				HasField(const BString& name) const;
135603e0bdfSNiels Sascha Reedijk 
136603e0bdfSNiels Sascha Reedijk 	// Form retrieve
137603e0bdfSNiels Sascha Reedijk 			BString				GetMultipartHeader(const BString& fieldName) const;
138603e0bdfSNiels Sascha Reedijk 			form_content_type	GetType(const BString& fieldname) const;
139603e0bdfSNiels Sascha Reedijk 
140603e0bdfSNiels Sascha Reedijk 	// Form informations
141603e0bdfSNiels Sascha Reedijk 			form_type			GetFormType() const;
142603e0bdfSNiels Sascha Reedijk 			const BString&		GetMultipartBoundary() const;
143603e0bdfSNiels Sascha Reedijk 			BString				GetMultipartFooter() const;
144603e0bdfSNiels Sascha Reedijk 			ssize_t				ContentLength() const;
145603e0bdfSNiels Sascha Reedijk 
146603e0bdfSNiels Sascha Reedijk 	// Form iterator
147603e0bdfSNiels Sascha Reedijk 			Iterator			GetIterator();
148603e0bdfSNiels Sascha Reedijk 
149603e0bdfSNiels Sascha Reedijk 	// Form clear
150603e0bdfSNiels Sascha Reedijk 			void				Clear();
151603e0bdfSNiels Sascha Reedijk 
152603e0bdfSNiels Sascha Reedijk 	// Overloaded operators
153603e0bdfSNiels Sascha Reedijk 			BHttpFormData&		operator[](const BString& name);
154603e0bdfSNiels Sascha Reedijk 
155603e0bdfSNiels Sascha Reedijk private:
156603e0bdfSNiels Sascha Reedijk 			void				_ExtractNameValuePair(const BString& string, int32* index);
157603e0bdfSNiels Sascha Reedijk 			void				_GenerateMultipartBoundary();
158603e0bdfSNiels Sascha Reedijk 			BString				_GetMultipartHeader(const BHttpFormData* element) const;
159603e0bdfSNiels Sascha Reedijk 			form_content_type	_GetType(FormStorage::const_iterator it) const;
160603e0bdfSNiels Sascha Reedijk 			void				_Erase(FormStorage::iterator it);
161603e0bdfSNiels Sascha Reedijk 
162603e0bdfSNiels Sascha Reedijk private:
163603e0bdfSNiels Sascha Reedijk 	friend	class Iterator;
164603e0bdfSNiels Sascha Reedijk 
165603e0bdfSNiels Sascha Reedijk 			FormStorage			fFields;
166603e0bdfSNiels Sascha Reedijk 			form_type			fType;
167603e0bdfSNiels Sascha Reedijk 			BString				fMultipartBoundary;
168603e0bdfSNiels Sascha Reedijk };
169603e0bdfSNiels Sascha Reedijk 
170603e0bdfSNiels Sascha Reedijk 
171603e0bdfSNiels Sascha Reedijk class BHttpForm::Iterator {
172603e0bdfSNiels Sascha Reedijk public:
173603e0bdfSNiels Sascha Reedijk 								Iterator(const Iterator& other);
174603e0bdfSNiels Sascha Reedijk 
175603e0bdfSNiels Sascha Reedijk 			BHttpFormData*		Next();
176603e0bdfSNiels Sascha Reedijk 			bool 				HasNext() const;
177603e0bdfSNiels Sascha Reedijk 			void				Remove();
178603e0bdfSNiels Sascha Reedijk 			BString				MultipartHeader();
179603e0bdfSNiels Sascha Reedijk 
180603e0bdfSNiels Sascha Reedijk 			Iterator& 			operator=(const Iterator& other);
181603e0bdfSNiels Sascha Reedijk 
182603e0bdfSNiels Sascha Reedijk private:
183603e0bdfSNiels Sascha Reedijk 								Iterator(BHttpForm* form);
184603e0bdfSNiels Sascha Reedijk 			void				_FindNext();
185603e0bdfSNiels Sascha Reedijk 
186603e0bdfSNiels Sascha Reedijk private:
187603e0bdfSNiels Sascha Reedijk 	friend	class BHttpForm;
188603e0bdfSNiels Sascha Reedijk 
189603e0bdfSNiels Sascha Reedijk 			BHttpForm*			fForm;
190603e0bdfSNiels Sascha Reedijk 			BHttpForm::FormStorage::iterator
191603e0bdfSNiels Sascha Reedijk 								fStdIterator;
192603e0bdfSNiels Sascha Reedijk 			BHttpFormData*		fElement;
193603e0bdfSNiels Sascha Reedijk 			BHttpFormData*		fPrevElement;
194603e0bdfSNiels Sascha Reedijk };
195603e0bdfSNiels Sascha Reedijk 
196*70b63f18SNiels Sascha Reedijk 
197ce64ffdbSNiels Sascha Reedijk } // namespace Network
198ce64ffdbSNiels Sascha Reedijk 
199ce64ffdbSNiels Sascha Reedijk } // namespace BPrivate
200ce64ffdbSNiels Sascha Reedijk 
201603e0bdfSNiels Sascha Reedijk #endif // _B_HTTP_FORM_H_
202