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