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