Remove DLLAPI define.
[catagits/fcgi2.git] / include / fcgio.h
1 //
2 // $Id: fcgio.h,v 1.5 2001/06/22 13:15:10 robs Exp $
3 //
4 // Allows you communicate with FastCGI streams using C++ iostream
5 // objects
6 //
7 // defines classes fcgi_streambuf, fcgi_ostream, fcgi_istream
8 // you can redefine cin, cout, cerr or use your own custom
9 // FCGI stream names.
10 //
11 // ORIGINAL AUTHOR: George Feinberg
12 //
13 //
14 // REWRITTEN BY: Michael Richards  06/20/1999
15 //          -added cin support
16 //          -added ability to replace cin/cout so existing code only
17 //           needs to include the header file and use the normal
18 //           cin/cout. This has been altered as of 2/2000, see below.
19 //          -added buffered read support which is required for ungets.
20 //
21 //
22 // REWRITTEN AGAIN BY: Michael Shell 02/23/2000
23 //
24 //            Previous versions of this code had problems.
25 //            Two hellish bugs have been fixed and there is now full
26 //            buffering for both input and output streams.
27 //
28 //          - fixed signed char bug in underflow() that would
29 //            cause a false EOF to be flagged when reading binary
30 //            data. Uploading short binary files via <input type=file
31 //            which uses multipart/form-data encoding would reveal
32 //            this bug. Also could be triggered by hackers
33 //            sending binary data instead of legitimate form data,
34 //            in which case the hung network connection, depending on
35 //            how the FCGI application server handles things, could
36 //            form the basis for a stupid denial of service attack.
37 //          - fixed code to properly use the get and put buffers via
38 //            underflow() and overflow() NOT xsgetn() and xsputn() as
39 //            was done before. Because of this, the previous
40 //            version would often drop data, especially if the
41 //            user did an initial getline() followed by a read().
42 //          - added the attach() method and a parameterless
43 //            constructor so that you can declare fcgi_iostream
44 //            objects and attach() to them later - after accept().
45 //          - enhanced docs to include examples that actually work.
46 //          - removed any predefined redefinitions of cin,cout,cerr.
47 //            The example shows how you can use these names if you
48 //            want (via properly placed #undefs) or use ones of your
49 //            choosing (such as fin,fout,ferr). This may be very
50 //            helpful when testing code. Also, as a result, you
51 //            no longer have to place fcgio2.h in any special
52 //            order in your #includes.
53 //          - added an experimental method drain() to istream which
54 //            allows the user to drain the get buffer. This is
55 //            designed to provide users with a way to drain the get
56 //            buffer prior to using a read function from the FCGI
57 //            library in applications which mix I/O methods. i.e.
58 //            it is the input equivalent to flush(). It does not
59 //            read from the FCGI stream, but gets only characters
60 //            already in the istream buffer. Mixing I/O methods is
61 //            not recommended since this iostream implementation
62 //            is complete and should provide you with everything
63 //            you need.
64 //
65 //
66 // NOTES: encapsulates the FastCGI protocol in an iostream via a
67 // nice custom streambuf. Very nice, very robust, and very powerful.
68 //
69 // This work is based on routines written by George Feinberg. They
70 // have been mostly re-written and extensively changed by
71 // Michael Richards.
72 //
73 // Rewritten again with bug fixes and numerous enhancements by
74 // Michael Shell.
75 //
76 // Special Thanks to Dietmar Kuehl for his help and the numerous custom
77 // streambuf examples on his web site.
78 //
79 // Copyright (c) 2000 Tux the Linux Penguin
80 //
81 // You are free to use this software without charge or royalty
82 // as long as this notice is not removed or altered, and recognition
83 // is given to the author(s)
84 //
85 // This code is offered as-is without any warranty either expressed or
86 // implied; without even the implied warranty of MERCHANTABILITY or
87 // FITNESS FOR A PARTICULAR PURPOSE.
88 // If it breaks, you get to keep both halves.
89
90
91 // BEGIN EXAMPLE CODE: test_fcgio2.cpp
92 /*
93 // This code uses the fcgiapp interface to show a little bit more
94 // complexity and to demonstrate the fact that with fcgio2 and just
95 // a few more lines of code (like FCGX_Init etc.) you can easily
96 // make FastCGI programs without needing wrapper functions.
97 // You can use the fcgi_stdio interface if you you want a
98 // simpler accept(). However note that the fcgio2 interface
99 // removes the need for the fcgi_stdio wrapper functions.
100 // i.e. Why override printf when you aren't going to use it anyway?
101 // Also, be aware that because of iostream buffering, you must take
102 // care when mixing FCGI iostream I/O with the FCGI library I/O
103 // commands (such as printf). Be sure to flush() any open
104 // fcgi_ostreams prior to using commands such as printf. This is true
105 // even on systems which have the C I/O commands synced with C++
106 // iostreams, such as Linux, because the FCGI wrapper printf, etc. are
107 // not the same as the "normal" printf etc. It is recommended that you
108 // not use any FCGI library input (read) commands if you use
109 // fcgi_istream (cin) input as there is no easy way to "flush" (drain)
110 // an istream get buffer. However, an experimental istream method
111 // drain() has been provided to istream for those of you who need to
112 // do mixed input. There should be no need to do mixed I/O as the
113 // fcgio2 iostream implementation is complete.
114
115 #include <stdlib.h>
116 #include "fcgio.h"   // fcgio.h includes fcgiapp.h
117                      // however you must include fcgi_stdio.h if
118                      // you want to use it as fcgio.h does not
119                      // include it for you
120
121 #undef cin  // remember you have to undo the stuff predefined
122 #undef cout // for cin, cout, cerr if you wish to use these
123 #undef cerr // names for your FastCGI streams
124
125 int main(void)
126 {
127
128  int count = 0;
129
130  // I can create/declare my objects here, but I don't dare use them
131  // until I set them up with attach().
132
133  // note that version 1.0 of fcgio used fcgio_istream & fcgio_ostream
134  // we made a little change to the names in V2.00 for clarity.
135  fcgi_istream cin;  // you do not *HAVE* to use these names, you
136  fcgi_ostream cout; // could use other stream names of your choice
137  fcgi_ostream cerr; // don't forget that the input is
138                     // fcgi_*I*stream class
139
140  FCGX_Request request; // here is our request structure
141
142  // get everything ready for the customers
143  FCGX_Init();
144
145  FCGX_InitRequest(&request,0,0);
146
147
148  // let the games begin
149  while(FCGX_Accept_r(&request) >= 0)
150     {
151     count++;
152
153     cout.attach(request.out); // now I know my pointer values for
154     cerr.attach(request.err); // this request. attach to them
155     cin.attach(request.in);
156     // attach will initialize everything
157     // alternatively, you could declare the streams here and the
158     // constructor with the (FCGX_Stream *str) parameter would
159     // do the same job as attach
160
161     // If you are using fcgi_stdio.h, the equivalent command would
162     // be cout.attach(FCGI_stdout->fcgx_stream);
163     // and so forth for cin,cerr using FCGI_stdin and FCGI_stderr
164     // respectively.
165
166
167     // now I can fire at will:
168     cout << "Content-type: text/html\r\n\r\n"
169          << "<title> FastCGI cin, cout, cerr tester </title>\r\n"
170          << "<h1><center> FastCGI C++ IOstream test: "
171          << "It works! </center></h1>\r\n";
172     cout << "<h4><center><i> Total served by this task: "
173          << count << "</i></center></h4>\r\n";
174
175 // didn't use cin or cerr in this example.
176
177 // it is good practice to flush the buffers.
178 // use cout.flush() if you don't want the line feed.
179
180    cout << endl;
181
182 // there is no cxxx.close() and you do not need it with the fcgio
183 // interface. You would need to call cxxx.close() if cxxx was an
184 // fstream based object and attached to a file descripter you got
185 // from a command like fd=open(blah). (GNU (Linux) based fstreams
186 // support this) Then you need to call cxxx.close() before you
187 // close the physical file with close(fd). If doing this with
188 // fstream objects, you should call cxxx.clear() after
189 // attach(fd) as the file descriptor attach is not as complete in
190 // initialization as our fcgi_iostream attach()
191 // If you don't understand any of this, don't worry about it and
192 // forget I even mentioned it.
193
194    // all done with this request
195    FCGX_Finish_r(&request);
196
197    // do the next request
198    }
199  return (1);
200 }
201
202 */
203
204 // END EXAMPLE CODE
205
206 /*------------------------------------------------------------------*/
207
208
209 #ifndef FCGIO_H
210 #define FCGIO_H
211
212 #include <iostream.h>
213
214 #include "fcgiapp.h"
215
216 // we aren't pulling from the heap, so it is best not to make it too big
217 #define FCGIO_BUFSIZE 200
218
219 // FastCGI streambuf replacement. Implements low level I/O to the
220 // FastCGI C functions so our higher level iostreams will talk
221 // in the FastCGI protocol
222 class fcgi_streambuf : public streambuf
223 {
224   public:
225     // constructor
226     fcgi_streambuf(void);
227     ~fcgi_streambuf();
228
229     // handles allocation of buffers by doing nothing since buffer
230     // allocation isn't needed
231     virtual int doallocate();
232
233     // gets data (upto the given maximum) from the get buffer and
234     // copies it to the given char array. Returns the number of chars
235     // written or -1 on error. A returned value less than the given
236     // maximum, assuming the user requested at least one char,
237     // indicates that the get buffer is empty. The underflow() method
238     // is never called to refill the get buffer, so this method can be
239     // used to drain the get buffer. It is used to form an istream
240     // drain() method which is the input equivalent to flush().
241     virtual int drain_strm(char *,int);
242
243     // let's us know if this strembuf has been initialized
244     virtual int isstrmdefined(void);
245
246     // (for writers) empties the put buffer and possibly an
247     // overflow char into the FCGI interface
248     virtual int overflow(int);
249
250     // bogus routine in case somebody thinks they know
251     // better and calls it. We currently are happy with
252     // our static buffer.
253     virtual streambuf * setbuf(char *, int);
254
255     // initializes the buffering and FCGI interface
256     virtual void stream_initialize(FCGX_Stream *,int);
257
258     // (for writers) flushes the put buffer into the FCGI
259     // interface and then flushes the FCGI interface
260     virtual int sync();
261
262     // (for readers) fills the get buffer with data from the
263     // FCGI interface
264     virtual int underflow();
265
266   private:
267     // pointer to our underlying FCGI interface
268     FCGX_Stream * fcgx_strm;
269
270     // our buffer
271     static int buffersize;
272     char buffer[FCGIO_BUFSIZE];
273
274     // little flag so that we can tell if the
275     // fcgi_str pointer was ever set
276     int defined;
277 };
278
279 int fcgi_streambuf::buffersize = FCGIO_BUFSIZE;
280
281 // Here's the istream class definition.
282 class fcgi_istream : public istream
283 {
284   public:
285     fcgi_istream();
286     fcgi_istream(FCGX_Stream *str);
287     ~fcgi_istream();
288
289     // connects the fcgi_streambuf of  an existing fcgi_istream
290     // object to a given FCGI interface
291     virtual void attach(FCGX_Stream *str);
292
293     // allows you to drain down the streambuf buffer. It will not
294     // read any chars from the FCGI interface. You can repeatedly
295     // call drain() to empty the get buffer prior to using a
296     // FCGI library function to ensure syncronization of the
297     // reads. i.e. it flushes the input stream
298     // This method should be considered both nonstandard and
299     // experimental. It's use is entirely optional to the user,
300     // but could be very helpful for applications which use
301     // both istream and FCGI library based reads on a single
302     // FCGI interface and need a way to sync the reads.
303     // It copies upto the given number of chars into the given
304     // char array. It returns the number of chars written or
305     // -1 on error. If the number of chars written is less than
306     // the number the user requested, the get buffer is empty.
307     // This method does not alter or check any of the input
308     // status flags such as EOF or FAIL since it does not interact
309     // with the underlying FCGI interface at all - it only reads from
310     // the get buffer.
311     virtual int drain(char *,int);
312
313     // lets us know if this object has been initialized
314     virtual int isdefined(void);
315
316   private:
317     // FastCGI streambuf
318     fcgi_streambuf fcgi_strmbuf;
319
320 };
321
322
323
324 // Here's the ostream class definition.
325 class fcgi_ostream : public ostream
326 {
327   public:
328     fcgi_ostream(void);
329     fcgi_ostream(FCGX_Stream *str);
330     ~fcgi_ostream();
331
332   // connects the fcgi_streambuf of an existing fcgi_ostream
333   // object to a given FCGI interface
334   virtual void attach(FCGX_Stream *str);
335
336   // lets us know if this object has been initialized
337   virtual int isdefined(void);
338
339   private:
340     // FastCGI streambuf
341     fcgi_streambuf fcgi_strmbuf;
342 };
343
344 #endif FCGIO_H