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