1 #ifndef CGI_IMPL___CGI_ENTRY_READER__HPP 2 #define CGI_IMPL___CGI_ENTRY_READER__HPP 3 4 /* $Id: cgi_entry_reader.hpp 561553 2018-04-09 17:42:02Z grichenk $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Authors: Aaron Ucko 30 * 31 */ 32 33 /// @file cgi_entry_reader.hpp 34 /// Support classes for on-demand CGI input parsing. 35 36 37 #include <cgi/ncbicgi.hpp> 38 39 40 /** @addtogroup CGIReqRes 41 * 42 * @{ 43 */ 44 45 46 BEGIN_NCBI_SCOPE 47 48 49 class CCgiEntryReader : public IReader 50 { 51 public: 52 typedef CCgiEntryReaderContext TContext; 53 54 ERW_Result Read(void* buf, size_t count, size_t* bytes_read); 55 ERW_Result PendingCount(size_t* count); 56 57 private: 58 enum EState { 59 fUnread = 0x1, 60 fHitCR = 0x2, 61 fHitLF = 0x4, 62 fHitCRLF = fHitCR | fHitLF, 63 fHitBoundary = 0x8 64 }; 65 typedef int TState; 66 CCgiEntryReader(TContext & context)67 CCgiEntryReader(TContext& context) 68 : m_Context(context), m_State(fUnread | fHitCRLF) 69 { } 70 ~CCgiEntryReader(); 71 72 void x_FillBuffer(SIZE_TYPE count); x_Flush(void)73 void x_Flush(void) { x_FillBuffer(NPOS); } 74 void x_HitBoundary(bool final); 75 76 TContext& m_Context; 77 string m_Buffer; 78 TState m_State; 79 80 friend class CCgiEntryReaderContext; 81 }; 82 83 84 class CCgiEntryReaderContext 85 { 86 public: 87 CCgiEntryReaderContext(CNcbiIstream& in, TCgiEntries& out, 88 const string& content_type, 89 size_t content_length 90 = CCgiRequest::kContentLengthUnknown, 91 string* content_log = NULL); 92 ~CCgiEntryReaderContext(); 93 94 TCgiEntriesI GetNextEntry(void); 95 96 void IncludePreparsedEntries(void); 97 98 private: 99 typedef CCgiEntryReader TReader; 100 enum EContentType { 101 eCT_Null, // at end of input 102 eCT_URLEncoded, 103 eCT_Multipart 104 }; 105 enum EReadTerminator { 106 eRT_Delimiter, 107 eRT_EOF, 108 eRT_LengthBound, 109 eRT_PartialDelimiter 110 }; 111 112 void x_FlushCurrentEntry(void); 113 EReadTerminator x_DelimitedRead(string& s, SIZE_TYPE n = NPOS); 114 void x_ReadURLEncodedEntry(string& name, string& value); 115 void x_ReadMultipartHeaders(string& name, string& filename, 116 string& content_type); 117 118 CNcbiIstream& m_In; 119 TCgiEntries& m_Out; 120 TCgiEntriesI m_OutIter; 121 bool m_OutIterated; 122 EContentType m_ContentType; 123 bool m_ContentTypeDeclared; 124 size_t m_ContentLength; 125 string m_Boundary; 126 string* m_ContentLog; 127 unsigned int m_Position; 128 SIZE_TYPE m_BytePos; 129 CCgiEntry* m_CurrentEntry; 130 TReader* m_CurrentReader; 131 132 friend class CCgiEntryReader; 133 }; 134 135 136 END_NCBI_SCOPE 137 138 139 /* @} */ 140 141 #endif /* CGI_IMPL___CGI_ENTRY_READER__HPP */ 142