1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2009 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef HTTP_RESPONSE_H_
8 #define HTTP_RESPONSE_H_
9 
10 #include <string>
11 #include <Wt/WGlobal.h>
12 #include <Wt/Http/ResponseContinuation.h>
13 #include <ostream>
14 
15 namespace Wt {
16 
17   class WResource;
18   class WebSession;
19 
20   namespace Http {
21 
22 /*! \class Response Wt/Http/Response.h Wt/Http/Response.h
23  *  \brief A resource response.
24  *
25  * This class defines the HTTP response for a WResource request.
26  *
27  * More specifically you can:
28  * - set the content mime type using setMimeType()
29  * - add HTTP headers using addHeader()
30  * - stream content into out()
31  *
32  * You may chose to provide only a partial response. In that case, use
33  * createContinuation() to create a continuation object to which you
34  * can annotate information for the next request to process the
35  * response further.
36  *
37  * \sa WResource::handleRequest(), Request
38  *
39  * \ingroup http
40  */
41 class WT_API Response
42 {
43 public:
44   /*! \brief Sets the response status.
45    *
46    * Unless a overriden, 200 OK will be assumed.
47    */
48   void setStatus(int status);
49 
50   /*! \brief Sets the content length
51    *
52    * If content length is known, use this method to set it. File downloads
53    * will see progress bars. If not set, Wt will use chunked transfers.
54    *
55    * Always use this method instead of setting the Content-Length header
56    * with addHeader().
57    *
58    * Headers may be added only before setting the content mime-type
59    * (setMimeType()), and before streaming any data to the out()
60    * stream.
61    */
62    void setContentLength(::uint64_t length);
63 
64   /*! \brief Set the content mime type.
65    *
66    * The content mimetype is used by the browser to correctly interpret
67    * the resource.
68    */
69   void setMimeType(const std::string& mimeType);
70 
71   /*! \brief Add an HTTP header.
72    *
73    * Headers may be added only before setting the content mime-type
74    * (setMimeType()), and before streaming any data to the out()
75    * stream.
76    */
77   void addHeader(const std::string& name, const std::string& value);
78 
79   /*! \brief Create a continuation object for this response.
80    *
81    * A continuation is used to resume sending more data later for this
82    * response. There are two possible reasons for this:
83    * - the entire response is quite big and you may want to read and send
84    *   it in smaller chunks to avoid memory consumption problems since the
85    *   I/O layer buffers the response first in memory to send it then out
86    *   to a possibly slow client using async I/O.
87    * - you may not have any more data available, currently, but expect more
88    *   data later. In that case you can call
89    *   ResponseContinuation::waitForMoreData() and later call
90    *   WResource::haveMoreData() when more data is available.
91    *
92    * A new call to handleRequest() will be made to retrieve more
93    * data.
94    *
95    * \sa continuation()
96    */
97   ResponseContinuation *createContinuation();
98 
99   /*! \brief Return the continuation, if one was created for this response.
100    *
101    * Returns the continuation that was previously created using
102    * createContinuation(), or \c nullptr if no continuation was created yet.
103    *
104    * \sa createContinuation()
105    */
106   ResponseContinuation *continuation() const;
107 
108   /*! \brief Returns the stream for getting the response output.
109    */
110   std::ostream& out();
111 
bout()112   WT_BOSTREAM& bout() { return out(); }
113 
114 private:
115   WResource *resource_;
116   WebResponse *response_;
117   ResponseContinuationPtr continuation_;
118   WT_BOSTREAM *out_;
119   bool headersCommitted_;
120 
121   Response(WResource *resource, WebResponse *response,
122 	   ResponseContinuationPtr continuation);
123   Response(WResource *resource, WT_BOSTREAM& out);
124 
125   friend class Wt::WResource;
126   friend class Wt::WebSession;
127 };
128 
129   }
130 }
131 
132 #endif // HTTP_RESPONSE_H_
133