acl  3.5.3.0
HttpServletResponse.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include "../stdlib/noncopyable.hpp"
4 
5 #ifndef ACL_CLIENT_ONLY
6 
7 namespace acl {
8 
9 class dbuf_guard;
10 class string;
11 class xml;
12 class json;
13 class ostream;
14 class socket_stream;
15 class http_header;
16 class http_client;
17 class HttpCookie;
18 class HttpServletRequest;
19 
20 /**
21  * 与 HTTP 客户端响应相关的类,该类不应被继承,用户也不需要
22  * 定义或创建该类对象
23  */
25 {
26 public:
27  /**
28  * 构造函数
29  * @param stream {socket_stream&} 数据流,内部不会自动关闭流
30  */
32  ~HttpServletResponse(void);
33 
34  /**
35  * 设置 HTTP 响应数据体的长度
36  * @param n {acl_int64} 数据体长度
37  */
38 #if defined(_WIN32) || defined(_WIN64)
39  HttpServletResponse& setContentLength(__int64 n);
40 #else
41  HttpServletResponse& setContentLength(long long int n);
42 #endif
43 
44  /**
45  * 设置 HTTP chunked 传输模式
46  * @param on {bool} 如果为 true,即使设置了 setContentLength,
47  * 则内部也会采用 chunked 传输方式,根据 HTTP RFC 规范要求,
48  * chunked 传输的优先级高级 conteng-length 方式
49  * @return {HttpServletResponse&}
50  */
51  HttpServletResponse& setChunkedTransferEncoding(bool on);
52 
53  /**
54  * 设置与 HTTP 客户端保持联系长连接
55  * @param on {bool}
56  * @return {HttpServletResponse&}
57  */
58  HttpServletResponse& setKeepAlive(bool on);
59 
60  /**
61  * 设置 HTTP 响应数据体的 Content-Type 字段值,可字段值可以为:
62  * text/html 或 text/html; charset=utf8 格式
63  * @param value {const char*} 字段值
64  * @return {HttpServletResponse&}
65  */
66  HttpServletResponse& setContentType(const char* value);
67 
68  /**
69  * 设置 HTTP 响应数据体采用 gzip 压缩格式
70  * @param gzip {bool} 是否采用 gzip 压缩格式
71  * @return {HttpServletResponse&}
72  */
73  HttpServletResponse& setContentEncoding(bool gzip);
74 
75  /**
76  * 设置 HTTP 响应数据体中字符集,当已经在 setContentType 设置
77  * 了字符集,则就不必再调用本函数设置字符集
78  * @param charset {const char*} 响应体数据的字符集
79  * @return {HttpServletResponse&}
80  */
81  HttpServletResponse& setCharacterEncoding(const char* charset);
82 
83  /**
84  * 设置 HTTP 响应头中的日期格式的字段
85  * @param name {const char*} HTTP 响应头中的字段名
86  * @param value {time_t} 时间值
87  */
88  HttpServletResponse& setDateHeader(const char* name, time_t value);
89 
90  /**
91  * 设置 HTTP 响应头中的字符串格式字段
92  * @param name {const char*} HTTP 响应头中的字段名
93  * @param value {const char*} 字段值
94  */
95  HttpServletResponse& setHeader(const char* name, const char* value);
96 
97  /**
98  * 设置 HTTP 响应头中的整数格式字段
99  * @param name {const char*} HTTP 响应头中的字段名
100  * @param value {int} 字段值
101  */
102  HttpServletResponse& setHeader(const char* name, int value);
103 
104  /**
105  * 对于分区下载,调用本函数设置数据下载的偏移位置(下标从 0 开始)
106  * @param from {http_off_t} 数据区间起始偏移位置(下标从 0 开始计算)
107  * @param to {http_off_t} 数据区间结束位置(该值需小于总数据长度)
108  * @param total {http_off_t} 总数据长度,当数据源为一个静态文件时该值
109  * 应等于该文件的总长度大小
110  * @return {HttpServletResponse&}
111  */
112 #if defined(_WIN32) || defined(_WIN64)
113  HttpServletResponse& setRange(__int64 from,
114  __int64 to, __int64 total);
115 #else
116  HttpServletResponse& setRange(long long from,
117  long long to, long long total);
118 #endif
119 
120  /**
121  * 设置 HTTP 响应头中的状态码:1xx, 2xx, 3xx, 4xx, 5xx
122  * @param status {int} HTTP 响应状态码, 如:200
123  */
124  HttpServletResponse& setStatus(int status);
125 
126  /**
127  * 设置为 CGI 模式,用户一般不需手工设置,因为 HttpServlet 类
128  * 会自动设置是否是 CGI 模式
129  * @param on {bool} 是否是 CGI 模式
130  */
131  HttpServletResponse& setCgiMode(bool on);
132 
133  /**
134  * 设置 HTTP 响应头中的重定向 location 字段
135  * @param location {const char*} URL,非空
136  * @param status {int} HTTP 响应状态码,一般为 3xx 类
137  */
138  HttpServletResponse& setRedirect(const char* location, int status = 302);
139 
140  /**
141  * 添加 cookie 对象,该对象必须是动态分配的,且用户自己不能
142  * 再显示释放该对象,因为内部会自动释放
143  * @param cookie {HttpCookie*}
144  */
145  HttpServletResponse& addCookie(HttpCookie* cookie);
146 
147  /**
148  * 添加 cookie
149  * @param name {const char*} cookie 名
150  * @param value {const char*} cookie 值
151  * @param domain {const char*} cookie 存储域
152  * @param path {const char*} cookie 存储路径
153  * @param expires {time_t} cookie 过期时间间隔,当当前时间加
154  * 该值为 cookie 的过期时间截(秒)
155  */
156  HttpServletResponse& addCookie(const char* name, const char* value,
157  const char* domain = NULL, const char* path = NULL,
158  time_t expires = 0);
159 
160  /**
161  * 将 url 进行 url 编码
162  * @param out {string&} 存储编码后的结果
163  * @param url {const char*} 未编码前原始的 url
164  */
165  void encodeUrl(string& out, const char* url);
166 
167  /**
168  * 获得 HTTP 响应头
169  * @return {http_header&}
170  */
171  http_header& getHttpHeader(void) const;
172 
173  /**
174  * 向客户端发送 HTTP 数据体响应数据,可以循环调用此函数,
175  * 当通过 setChunkedTransferEncoding 设置了 chunked 传输方式后,
176  * 内部自动采用 chunked 传输方式;调用此函数不必显式调用
177  * sendHeader 函数来发送 HTTP 响应头,因为内部会自动在第一次
178  * 写时发送 HTTP 响应头;另外,在使用 chunked 方式传输数据时,
179  * 应该应该最后再调用一次本函数,且参数均设为 0 表示数据结束
180  * @param data {const void*} 数据地址
181  * @param len {size_t} data 数据长度
182  * @return {bool} 发送是否成功,如果返回 false 表示连接中断
183  */
184  bool write(const void* data, size_t len);
185 
186  /**
187  * 向客户端发送 HTTP 数据体响应数据,可以循环调用此函数,该函数
188  * 内部调用 HttpServletResponse::write(const void*, size_t) 过程,
189  * 另外,在使用 chunked 方式传输数据时,应该应该最后再调用一次本函数,
190  * 且输入空串,即 buf.empty() == true
191  * @param buf {const string&} 数据缓冲区
192  * @return {bool} 发送是否成功,如果返回 false 表示连接中断
193  */
194  bool write(const string& buf);
195 
196  /**
197  * 向客户端发送 HTTP Xml 响应数据体
198  * @param body {const xml&} 数据缓冲区
199  * @param charset {const char*} 数据体字符集
200  * @return {bool} 发送是否成功,如果返回 false 表示连接中断
201  */
202  bool write(const xml& body, const char* charset = "utf-8");
203 
204  /**
205  * 向客户端发送 HTTP Json 响应数据体
206  * @param body {const json&} 数据缓冲区
207  * @param charset {const char*} 数据体字符集
208  * @return {bool} 发送是否成功,如果返回 false 表示连接中断
209  */
210  bool write(const json& body, const char* charset = "utf-8");
211 
212  /**
213  * 带格式方式向 HTTP 客户端发送响应数据,内部自动调用
214  * HttpServletResponse::write(const void*, size_t) 过程,在使用
215  * chunked 方式传输数据时,应该应该最后再调用 write(NULL, 0)
216  * 表示数据结束
217  * @param fmt {const char*} 变参格式字符串
218  * @return {int} 成功则返回值 > 0,否则返回 -1
219  */
220  int format(const char* fmt, ...) ACL_CPP_PRINTF(2, 3);
221 
222  /**
223  * 带格式方式向 HTTP 客户端发送响应数据,内部自动调用
224  * HttpServletResponse::write(const string&) 过程,在使用 chunked
225  * 方式传输数据时,应该应该最后再调用 write(NULL, 0) 表示数据结束
226  * @param fmt {const char*} 变参格式字符串
227  * @param ap {va_list} 变参列表
228  * @return {int} 成功则返回值 > 0,否则返回 -1
229  */
230  int vformat(const char* fmt, va_list ap);
231 
232  ///////////////////////////////////////////////////////////////////
233 
234  /**
235  * 发送 HTTP 响应头,用户应该发送数据体前调用此函数将 HTTP
236  * 响应头发送给客户端
237  * @return {bool} 发送是否成功,若返回 false 则表示连接中断,
238  * 当调用以上几个写的函数时,本函数不必显式被调用,如果是
239  * 通过从 getOutputStream 获得的 socket 流写数据时,则本函数
240  * 必须显式被调用
241  */
242  bool sendHeader(void);
243 
244  /**
245  * 获得 HTTP 响应对象的输出流对象,用户在调用 sendHeader 发送
246  * 完 HTTP 响应头后,通过该输出流来发送 HTTP 数据体
247  * @return {ostream&}
248  */
249  ostream& getOutputStream(void) const;
250 
251  /**
252  * 获得 HTTP 双向流对象,由构造函数的参数输入
253  * @return {socket_stream&}
254  */
255  socket_stream& getSocketStream(void) const;
256 
257  /**
258  * 获得底层的 http_client 通信对象
259  * @return {http_client*} 非 NULL
260  */
262  {
263  return client_;
264  }
265 
266  /**
267  * 设置 http 请求对象,该函数目前只应被 HttpServlet 类内部调用
268  * @param request {HttpServletRequest*}
269  */
270  void setHttpServletRequest(HttpServletRequest* request);
271 
272 private:
273  dbuf_guard* dbuf_internal_;
274  dbuf_guard* dbuf_;
275  socket_stream& stream_; // 客户端连接流
276  HttpServletRequest* request_; // http 请求对象
277  http_client* client_; // http 响应流对象
278  http_header* header_; // http 响应头
279  char charset_[32]; // 字符集
280  char content_type_[32]; // content-type 类型
281  bool head_sent_; // 是否已经发送了 HTTP 响应头
282 };
283 
284 } // namespace acl
285 
286 #endif // ACL_CLIENT_ONLY
http_client * getClient() const
HTTP_API void const char * name
Definition: lib_http.h:620
#define ACL_CPP_PRINTF(format_idx, arg_idx)
Definition: atomic.hpp:75
ACL_API ACL_VSTRING const char * format
Definition: acl_vstring.h:239
ACL_API void const char * fmt
Definition: acl_aio.h:771
#define ACL_CPP_API