#ifndef	__LIB_HTTP_INCLUDE_H__
#define	__LIB_HTTP_INCLUDE_H__

#include "lib_http_status.h"
#include "lib_http_struct.h"

#ifdef	__cplusplus
extern "C" {
#endif

/*---------------------------- ͨ HTTP ͷ --------------------------*/
/* in http_hdr.c */

/**
 * һͨHTTPЭͷĽṹ
 * @param size {size_t} ڴС,  HTTP_HDR_REQ  HTTP_HDR_RES ĳߴ
 * @return {HTTP_HDR*} !NULL: һHTTP_HDRṹָ; NULL: .
 */
HTTP_API HTTP_HDR *http_hdr_new(size_t size);

/**
 * ԴHTTPͨͷڲԱһµHTTPͨͷṹ
 * @param src {const HTTP_HDR*} ԴHTTPͨͷ󣬲Ϊ
 * @param dst {HTTP_HDR*} ĿHTTPͨͷ󣬲Ϊ
 */
HTTP_API void http_hdr_clone(const HTTP_HDR *src, HTTP_HDR *dst);

/**
 * ͷһHTTP_HDRṹڴ
 * @param hh {HTTP_HDR*} ͵ָ룬Ϊ
 */
HTTP_API void http_hdr_free(HTTP_HDR *hh);

/**
 * һHTTPͨͷ״̬ͷڲԱҪkeep-aliveĳӶ
 * @param hh {HTTP_HDR*} HTTPͨͷ͵ָ룬Ϊ
 */
HTTP_API void http_hdr_reset(HTTP_HDR *hh);

/**
 *  HTTP_HDR ͷһĿ
 * @param hh {HTTP_HDR*} ͨͷ͵ָ룬Ϊ
 * @param entry {HTTP_HDR_ENTRY*} HTTPͷĿṹָ, Ϊ
 */
HTTP_API void http_hdr_append_entry(HTTP_HDR *hh, HTTP_HDR_ENTRY *entry);

/**
 * , Э, /ΰ汾ţͨHTTPͷṹ
 * @param hh {HTTP_HDR*} ͵ָ룬Ϊ
 * @param data {const char*} ݸʽΪ: HTTP/1.0
 * @return {int} 0: OK; < 0: error.
 */
HTTP_API int http_hdr_parse_version(HTTP_HDR *hh, const char *data);

/**
 * еͨHTTPЭͷ洢 hh ṹ
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @return {int} 0: ok; < 0: error
 */
HTTP_API int http_hdr_parse(HTTP_HDR *hh);

/**
 * ɴ name, value Բһ HTTP_HDR_ENTRY 
 * @param name {const char*} 
 * @param value {const char*} ֵ
 * @return {HTTP_HDR_ENTRY*} ΪΪ
 */
HTTP_API HTTP_HDR_ENTRY *http_hdr_entry_build(const char *name, const char *value);

/**
 * ݴһݽз, һ HTTP_HDR_ENTRY
 * @param data {const char*} HTTP Эͷеһ, : Content-Length: 200
 * @return {HTTP_HDR_ENTRY*} !NULL: ok; NULL: err.
 */
HTTP_API HTTP_HDR_ENTRY *http_hdr_entry_new(const char *data);
HTTP_API HTTP_HDR_ENTRY *http_hdr_entry_head(char *data);
HTTP_API HTTP_HDR_ENTRY *http_hdr_entry_new2(char *data);

/**
 * ȡһ HTTP_HDR_ENTRY Ŀ
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param name {const char*}  HTTP_HDR_ENTRY Ŀıʶ, Ϊ. : Content-Length.
 * @return ret {HTTP_HDR_ENTRY *} ret != NULL: ok; ret == NULL: 򲻴.
 */
HTTP_API HTTP_HDR_ENTRY *http_hdr_entry(const HTTP_HDR *hh, const char *name);

/**
 * ȡHTTPЭͷĳʵͷıֵĳʵͷΪHost: www.test.com
 * Ҫ Host ֵøúȡ www.test.com
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param name {const char*}  HTTP_HDR_ENTRY Ŀıʶ, Ϊ. : Content-Length
 * @return ret {char*} ret != NULL: ok; ret == NULL: 򲻴.
 */
HTTP_API char *http_hdr_entry_value(const HTTP_HDR *hh, const char *name);

/**
 *  HTTP ͷеĳֶν滻, ùҪΪʵ keep-alive ֶε滻
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param name {const char*}  HTTP_HDR_ENTRY Ŀıʶ, Ϊ. : Content-Length
 * @param value {const char*}  name ֶӦµֵ
 * @param force {int} 滻ֶԭʼHTTPﲻ, ǿвµ entry ֶβ
 *  ͷ, ֵΪ0ֵʱǿ, nameﲻ.
 * @return {int} 0 ʾ滻ɹ; < 0 ʾ name ֶڸHTTPͷﲻ
 */
HTTP_API int http_hdr_entry_replace(HTTP_HDR *hh, const char *name, const char *value, int force);

/**
 *  HTTP ͷеĳֶаĳַԴַ滻, ֶ֧ƥ滻
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param name {const char*}  HTTP_HDR_ENTRY Ŀıʶ, Ϊ. : Cookie
 * @param from {const char*} 滻ʱԴַ
 * @param to {const char*} 滻ʱĿַ
 * @param ignore_case {int} ڲ滻ʱǷԴַĴСд
 * @return {int} 0: ʾδκ滻, > 0: ʾ滻Ĵ
 */
HTTP_API int http_hdr_entry_replace2(HTTP_HDR *hh, const char *name,
        const char *from, const char *to, int ignore_case);

/**
 * ֹHTTPЭͷеĳ
 * @param hh {HTTP_HDR* } ͨHTTPͷ͵ָ룬Ϊ
 * @param name {const char*}  HTTP_HDR_ENTRY Ŀıʶ, Ϊ. : Content-Length
 */
HTTP_API void http_hdr_entry_off(HTTP_HDR *hh, const char *name);

/**
 * HTTPЭͷݣӿ
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param msg {const char*} ûϣͷϢһԶϢ, Ϊ
 */
HTTP_API void http_hdr_print(const HTTP_HDR *hh, const char *msg);

/**
 * HTTPЭͷݣӿ
 * @param fp {ACL_VSTREAM*} ĳָ룬ᶨ(Ϊļ)
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param msg {const char*} ûϣͷϢһԶϢ, Ϊ
*/
HTTP_API void http_hdr_fprint(ACL_VSTREAM *fp, const HTTP_HDR *hh, const char *msg);

/**
 * HTTPЭͷݣӿ
 * @param bf {ACL_VSTRING*} ᶨû
 * @param hh {HTTP_HDR*} ͨHTTPͷ͵ָ룬Ϊ
 * @param msg {const char*} ûϣͷϢһԶϢ, Ϊ
*/
HTTP_API void http_hdr_sprint(ACL_VSTRING *bf, const HTTP_HDR *hh, const char *msg);

/*-------------------------------- HTTP ͷ -----------------------*/
/* in http_hdr_req.c */

/**
 * ñ־λ HTTP  URI е ? ʺűת(ת %3F)ǷԴ
 * @param onoff {int} Ϊ 0 ֵʱʾԴڲȱʡֵΪ 1
 */
HTTP_API void http_uri_correct(int onoff);

/**
 * һHTTPЭͷ
 * @return {HTTP_HDR_REQ*} HTTPͷ
 */
HTTP_API HTTP_HDR_REQ *http_hdr_req_new(void);

/**
 * URLķHTTP汾һHTTPͷ
 * @param url {const char*} URLURL磺
 *  http://www.test.com/path/proc?name=value
 *  http://www.test.com/path/proc
 *  http://www.test.com/
 * @param method {const char*} HTTP󷽷Ϊ֮һ
 *  GET, POST, CONNECT, HEAD, Ҫע붼Ϊд
 * @param version {const char *} HTTP汾Ϊ֮һ
 *  HTTP/1.0, HTTP/1.1
 * @return {HTTP_HDR_REQ*} HTTPͷ
 */
HTTP_API HTTP_HDR_REQ *http_hdr_req_create(const char *url,
		const char *method, const char *version);

/**
 * ¡һHTTPͷ󣬵е chat_ctx, chat_free_ctx_fn
 * Ա
 * @param hdr_req {const HTTP_HDR_REQ*} HTTPͷ
 * @return {HTTP_HDR_REQ*} ¡HTTPͷ
 */
HTTP_API HTTP_HDR_REQ *http_hdr_req_clone(const HTTP_HDR_REQ* hdr_req);

/**
 * ϴHTTPͷݼضURLһµHTTPͷ
 * @param hh {const HTTP_HDR_REQ*} ϴεHTTPͷ
 * @param url {const char *} ضURL http[s]:// ǰ׺Ϊ
 *  URLµ Host ֶνɸURLȡ̳ԴHTTPͷ
 *   Host ֶ
 * @return {HTTP_HDR_REQ*} ²ضHTTPͷ
 */
HTTP_API HTTP_HDR_REQ *http_hdr_req_rewrite(const HTTP_HDR_REQ *hh, const char *url);

/**
 * HTTPͷݼضURLøHTTPͷϢ
 * @param hh {const HTTP_HDR_REQ*} ϴεHTTPͷ
 * @param url {const char *} ضURL http[s]:// ǰ׺Ϊ
 *  URLµ Host ֶνɸURLȡ̳ԴHTTPͷ
 *   Host ֶ
 * @return {int} 0: ok; < 0: error
 */
HTTP_API int http_hdr_req_rewrite2(HTTP_HDR_REQ *hh, const char *url);

/**
 * ͷHTTPͷ
 * @param hh {HTTP_HDR_REQ*} HTTPͷ
 */
HTTP_API void http_hdr_req_free(HTTP_HDR_REQ *hh);

/**
 * HTTPͷĳԱͷŲ³ʼ
 * @param hh {HTTP_HDR_REQ*} HTTPͷ
 */
HTTP_API void http_hdr_req_reset(HTTP_HDR_REQ *hh);

/**
 * HTTPЭͷcookies
 * @param hh {HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {int} 0: ok;  -1: err.
 */
HTTP_API int http_hdr_req_cookies_parse(HTTP_HDR_REQ *hh);

/**
 * HTTP(: GET /cgi-bin/test.cgi?name=value&name2=value2 HTTP/1.0)
 * ķ(GET)-->hdr_request_method
 * URLݷ(name=value)-->hdr_request_table
 * HTTPЭ汾(HTTP/1.0)-->hdr_request_proto
 * URLе·(/cgi-bin/test.cgi)-->hdr_request_url
 * @param hh {HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {int} 0: ok;  -1: err.
 */
HTTP_API int http_hdr_req_line_parse(HTTP_HDR_REQ *hh);

/**
 * HTTPͷЭ, ڲ http_hdr_req_line_parse, http_hdr_req_cookies_parse
 * @param hh {HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {int} 0: ok;  -1: err.
 */
HTTP_API int http_hdr_req_parse(HTTP_HDR_REQ *hh);

/**
 * HTTPͷЭ, ڲ http_hdr_req_line_parse, http_hdr_req_cookies_parse
 *  parse_params  0 HTTP url еĲ;  parse_cookie  0 
 * HTTPе cookie 
 * @param hh {HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @param parse_params {int} Ƿ url еĲ
 * @param parse_cookie {int} Ƿе cookie 
 * @return {int} 0: ok;  -1: err.
 */
HTTP_API int http_hdr_req_parse3(HTTP_HDR_REQ *hh, int parse_params, int parse_cookie);

/**
 * HTTPͷлĳcookieֵ
 * @param hh {HTTP_HDR_REQ*) HTTPͷ͵ָ룬Ϊ
 * @param name {const char*} ĳcookieı, Ϊ
 * @return {const char*} !NULL: ÷ֵΪҪcookie; NULL: Ҫcookie
 */
HTTP_API const char *http_hdr_req_cookie_get(HTTP_HDR_REQ *hh, const char *name);

/**
 * HTTPͷȡHTTPķ, : POST, GET, CONNECT
 * @param hh {const HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {const char*} ʾ. NULL: error; !NULL: OK.
 */
HTTP_API const char *http_hdr_req_method(const HTTP_HDR_REQ *hh);

/**
 * HTTPͷлȡURLĳֶε, 
 * ȡ: /cgi-bin/test.cgi?n1=v1&n2=v2 е n2ֵv2
 * @param hh {const HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @param name {const char*} еı
 * @return {const char*} !NULL: ok, رֵڴָ;  NULL: ı.
 */
HTTP_API const char *http_hdr_req_param(const HTTP_HDR_REQ *hh, const char *name);

/**
 * HTTPͷлȡеķ·, .
 * ԭΪ:
 *   GET /cgi-bin/test.cgi?n1=v1&n2=v2 HTTP/1.1
 *  or
 *   GET http://www.test.com[:80]/cgi-bin/test.cgi?n1=v1&n2=v2 HTTP/1.1
 * ĽΪ:
 *   /cgi-bin/test.cgi?n1=v1&n2=v2
 * @param hh {const HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {const char*} ʾURL. !NULL: OK; NULL: error.
 */
HTTP_API const char *http_hdr_req_url_part(const HTTP_HDR_REQ *hh);

/**
 * HTTPͷлȡеķ·, .
 * ԭΪ:
 *   GET /cgi-bin/test.cgi?n1=v1&n2=v2 HTTP/1.1
 *  or
 *   GET http://www.test.com[:80]/cgi-bin/test.cgi?n1=v1&n2=v2 HTTP/1.1
 * ĽΪ:
 *   /cgi-bin/test.cgi
 * @param hh {const HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {const char*} ʾURL. !NULL: OK; NULL: error.
 */
HTTP_API const char *http_hdr_req_url_path(const HTTP_HDR_REQ *hh);

/**
 * HTTPЭͷл÷IPʽΪIP|domain[:PORT]
 * : 192.168.0.22:80, or www.test.com:8088
 * @param hh {const HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {const char*} ûʾ. !NULL: ok; NULL: error.
 */
HTTP_API const char *http_hdr_req_host(const HTTP_HDR_REQ *hh);

/**
 * HTTPͷЭлURLַ
 * ԭHTTPͷΪ:
 * GET /cgi-bin/test.cgi?n1=v1&n2=v2 HTTP/1.1
 * HOST: www.test.com
 * 򾭸ú򷵻:
 * http://www.test.com/cgi-bin/test.cgi?n1=v1&n2=v2
 * @param hh {const HTTP_HDR_REQ*} HTTPͷ͵ָ룬Ϊ
 * @return {const char*} ʾURL. !NULL: OK; NULL: error.
 * @example:
 *  void test(HTTP_HDR_REQ *hh)
 *  {
 *    const char *url = http_hdr_req_url(hh);
 *    printf(">>> url: %s\r\n", url ? url : "null");
 *  }
 *  ע, Ϊ http_hdr_req_url ڲʹõһֲ̬߳̾ڴ, 
 *  ʹãʹصݷص.
 *  void test(HTTP_HDR_REQ *hh1, HTTP_HDR_REQ *hh2)
 *  {
 *    const char *url1 = http_hdr_req_url(hh1);
 *    const char *url2 = http_hdr_req_url(hh2);
 *    printf(">>> url1: %s, url2: %s\n", url1, url2);
 *  }
 *  Ϊ url1, url2 ʵ϶ָͬһڴ, յĽ url1, url2
 *  ͬ. , Ӧ²:
 *  void test(HTTP_HDR_REQ *hh1, HTTP_HDR_REQ *hh2)
 *  {
 *    const char *ptr;
 *    static char dummy[1];
 *    char *url1 = dummy, *url2 = dummy;
 *    ptr = http_hdr_req_url(hh1);
 *    if (ptr)
 *      url1 = acl_mystrdup(ptr);
 *    ptr = http_hdr_req_url(hh2);
 *    if (ptr)
 *      url2 = acl_mystrdup(ptr);
 *    printf(">>> url1: %s, url2: %s\n", url1, url2);
 *    if (url1 != dummy)
 *      acl_myfree(url1);
 *    if (url2 != dummy)
 *      acl_myfree(url2);
 *  }
 */
HTTP_API const char *http_hdr_req_url(const HTTP_HDR_REQ *hh);

/**
 * HTTPͷе Range ֶ
 * @param hdr_req {HTTP_HDR_REQ*} HTTPЭͷ, Ϊ
 * @param range_from {http_off_t*} 洢ƫʼλ
 * @param range_to {http_off_t*} 洢ƫƽλ
 * ע * {range_from}, {range_to} ±0ʼ
 *  Range ʽ:
 *   Range: bytes={range_from}-, bytes={range_from}-{range_to}
 */
HTTP_API int http_hdr_req_range(const HTTP_HDR_REQ *hdr_req,
	http_off_t *range_from, http_off_t *range_to);

/*---------------------------- HTTP Ӧͷ ---------------------------*/
/* in http_hdr_res.c */

/**
 * HTTPӦͷе״̬
 *@param hh {HTTP_HDR_RES*} HTTPӦͷ͵ָ룬Ϊ
 *@param dbuf {const char*} ״̬, : HTTP/1.0 200 OKΪ
 *@return {int} 0: ok;  < 0: error洢 hh ṹ
 */
HTTP_API int http_hdr_res_status_parse(HTTP_HDR_RES *hh, const char *dbuf);

/**
 * һµHTTPӦͷ
 * @return {HTTP_HDR_RES*}
 */
HTTP_API HTTP_HDR_RES *http_hdr_res_new(void);

/**
 * ¡һHTTPӦͷ
 * @param hdr_res {const HTTP_HDR_RES*} ԴHTTPӦͷ
 * @return {HTTP_HDR_RES *} ²HTTPӦͷ
 */
HTTP_API HTTP_HDR_RES *http_hdr_res_clone(const HTTP_HDR_RES *hdr_res);

/**
 * ͷһHTTPӦͷ
 * @param hh {HTTP_HDR_RES*} HTTPӦͷ
 */
HTTP_API void http_hdr_res_free(HTTP_HDR_RES *hh);

/**
 * HTTPӦͷ³ʼͷеĳԱ
 * @param hh {HTTP_HDR_RES*} HTTPӦͷ
 */
HTTP_API void http_hdr_res_reset(HTTP_HDR_RES *hh);

/**
 * HTTPӦͷݣ洢
 * @param hdr_res {HTTP_HDR_RES*} HTTPӦͷ
 */
HTTP_API int http_hdr_res_parse(HTTP_HDR_RES *hdr_res);

/**
 * HTTPӦͷе Range ֶ
 * @param hdr_res {HTTP_HDR_RES*} ӦHTTPЭͷ, Ϊ
 * @param range_from {http_off_t*} 洢ƫʼλ, Ϊ
 * @param range_to {http_off_t*} 洢ƫƽλ, Ϊ
 * @param total_length {http_off_t*} ļܳ, Ϊ
 * @return {int}  0 ʾɹ-1 ʾʧ
 * ע * {range_from}, {range_to} ±0ʼ
 * Ӧ Range ʽ:
 *   Content-Range: bytes {range_from}-{range_to}/{total_length}
 */
HTTP_API int http_hdr_res_range(const HTTP_HDR_RES *hdr_res,
	http_off_t *range_from, http_off_t *range_to, http_off_t *total_length);

/* in http_rfc1123.c */

/**
 * ʱֵתRFC1123Ҫĸʽ
 * @param buf {char*} 洢ռ
 * @param size {size_t} buf ĿռС
 * @param t {time_t} ʱֵ
 */
HTTP_API const char *http_mkrfc1123(char *buf, size_t size, time_t t);

/*----------------------- HTTP 첽 --------------------------------*/
/* in http_chat_async.c */

/**
 * 첽ȡһHTTP REQUESTЭͷݽ洢hdr, ȡһHTTPͷ
 * ʱûעắ notify
 * @param hdr {HTTP_HDR_REQ*} HTTPͷͽṹָ룬Ϊ
 * @param astream {ACL_ASTREAM*} ͻӵ, Ϊ
 * @param notify {HTTP_HDR_NOTIFY} HTTPЭͷʱõûעắ
 * @param arg {void*} notify ʱһ
 * @param timeout {int} ݹеĶʱʱ
 */
HTTP_API void http_hdr_req_get_async(HTTP_HDR_REQ *hdr, ACL_ASTREAM *astream,
		HTTP_HDR_NOTIFY notify, void *arg, int timeout);

/**
 * 첽ȡһHTTP RESPONDЭͷݽ洢hdr, ȡһHTTPͷ
 * ʱûעắ notify
 * @param hdr {HTTP_HDR_REQ*} HTTPӦͷͽṹָ룬Ϊ
 * @param astream {ACL_ASTREAM*} ӵ, Ϊ
 * @param notify {HTTP_HDR_NOTIFY} HTTPЭͷʱõûעắ
 * @param arg {void*} notify ʱһ
 * @param timeout {int} ݹеĶʱʱ
 */
HTTP_API void http_hdr_res_get_async(HTTP_HDR_RES *hdr, ACL_ASTREAM *astream,
		HTTP_HDR_NOTIFY notify, void *arg, int timeout);

/**
 * 첽ӿͻ˶ȡBODYЭ, ڽչб߽صû notify
 * ص,  notify С 0 ֵ, ΪҲټ
 * @param request {HTTP_REQ*} HTTPָ, Ϊ,  request->hdr Ϊ
 * @param astream {ACL_ASTREAM*} ͻӵ, Ϊ
 * @param notify {HTTP_BODY_NOTIFY} տͻݹлصûעắ
 * @param arg {void*} notify ʱһ
 * @param timeout {int} ݹеĶʱʱ
 */
HTTP_API void http_req_body_get_async(HTTP_REQ *request, ACL_ASTREAM *astream,
		 HTTP_BODY_NOTIFY notify, void *arg, int timeout);
/*
 * 첽ӷ˶ȡӦݵBODYЭ, ڽչصû
 * notify ص,  notify С 0 ֵ, ΪҲټ
 * @param respond {HTTP_RES*} HTTPӦָ, Ϊ, respond->hdr Ϊ
 * @param astream {ACL_ASTREAM*} ӵ, Ϊ
 * @param notify {HTTP_BODY_NOTIFY} շݹлصûעắ
 * @param arg {void*} notify ʱһ
 * @param timeout {int} ݹеĶʱʱ
 */
HTTP_API void http_res_body_get_async(HTTP_RES *respond, ACL_ASTREAM *astream,
		HTTP_BODY_NOTIFY notify, void *arg, int timeout);

/*----------------------- HTTP ͬ --------------------------------*/
/* in http_chat_sync.c */

/**
* ͬȡһHTTP REQUESTЭͷݽ洢hdr, ȡһHTTPͷ
* ʱûעắ notify
* @param hdr {HTTP_HDR_REQ*} HTTPͷͽṹָ룬Ϊ
* @param stream {ACL_VSTREAM*} ͻӵ, Ϊ
* @param timeout {int} ݹеĶʱʱ
* @return {int} 0: ɹ; < 0: ʧ
*/
HTTP_API int http_hdr_req_get_sync(HTTP_HDR_REQ *hdr,
		 ACL_VSTREAM *stream, int timeout);

/**
 * ͬȡһHTTP RESPONDЭͷݽ洢hdr, ȡһHTTPͷ
 * ʱûעắ notify
 * @param hdr {HTTP_HDR_REQ*} HTTPӦͷͽṹָ룬Ϊ
 * @param stream {ACL_VSTREAM*} ӵ, Ϊ
 * @param timeout {int} ݹеĶʱʱ
 * @return {int} 0: ɹ; < 0: ʧ
 */
HTTP_API int http_hdr_res_get_sync(HTTP_HDR_RES *hdr,
		ACL_VSTREAM *stream, int timeout);

/**
 * ͬӿͻ˶ȡBODYЭ
 * @param request {HTTP_REQ*} HTTPָ, Ϊ,  request->hdr Ϊ
 * @param stream {ACL_VSTREAM*} ͻӵ, Ϊ
 * @param buf {void *} 洢ݿռ
 * @param size {int} buf ĿռС
 * @return ret {http_off_t} ζHTTP
 *             0: ʾHTTPݣѾر;
 *             < 0: ʾرջ;
 *             > 0: ʾδ꣬Ŀǰret ֽڵ
 */
HTTP_API http_off_t http_req_body_get_sync(HTTP_REQ *request, ACL_VSTREAM *stream,
		void *buf, int size);
#define http_req_body_get_sync2	http_req_body_get_sync

/**
 * ͬӷ˶ȡӦBODYЭ
 * @param respond {HTTP_RES*} HTTPӦָ, Ϊ,  respond->hdr Ϊ
 * @param stream {ACL_VSTREAM*} ͻӵ, Ϊ
 * @param buf {void *} 洢ݿռ
 * @param size {int} buf ĿռС
 * @return ret {http_off_t} ζHTTPӦ
 *             0: ʾHTTPݣѾر;
 *             < 0: ʾرջ;
 *             > 0: ʾδ꣬Ŀǰret ֽڵ
 */
HTTP_API http_off_t http_res_body_get_sync(HTTP_RES *respond, ACL_VSTREAM *stream,
		void *buf, int size);
#define http_res_body_get_sync2	http_res_body_get_sync

/**
 * ЭĿƱ־λ
 * @param request {HTTP_REQ*} HTTPָ, Ϊ,  request->hdr Ϊ
 * @param name {int} һ־λһ־λΪ HTTP_CHAT_SYNC_CTL_END ʱ
 *  ʾ
 */
HTTP_API void http_chat_sync_reqctl(HTTP_REQ *request, int name, ...);

/**
 * ӦЭĿƱ־λ
 * @param respond {HTTP_RES*} HTTPӦָ, Ϊ,  respond->hdr Ϊ
 * @param name {int} һ־λһ־λΪ HTTP_CHAT_SYNC_CTL_END ʱ
 *  ʾ
 */
HTTP_API void http_chat_sync_resctl(HTTP_RES *respond, int name, ...);
#define	HTTP_CHAT_SYNC_CTL_END      0  /**< ־λ */
#define	HTTP_CHAT_CTL_BUFF_ONOFF    1  /**< ǷݽʱԤ */

/*------------------------ HTTP 幹켰ͷź  ------------------------*/
/* in http_req.c */

/**
 * HTTPͷһ
 * @param hdr_req {HTTP_HDR_REQ*} ͷ
 * @return {HTTP_REQ*} 
 */
HTTP_API HTTP_REQ *http_req_new(HTTP_HDR_REQ *hdr_req);

/**
 * ͷ
 * @param request {HTTP_REQ*} 
 */
HTTP_API void http_req_free(HTTP_REQ *request);

/*------------------------ HTTP Ӧ幹켰ͷź  ------------------------*/
/* in http_res.c */

/**
* HTTPӦͷһӦ
* @param hdr_res {HTTP_HDR_RES*} Ӧͷ
* @return {HTTP_RES*} Ӧ
*/
HTTP_API HTTP_RES *http_res_new(HTTP_HDR_RES *hdr_res);

/**
 * ͷӦ
 * @param respond {HTTP_RES*} Ӧ
 */
HTTP_API void http_res_free(HTTP_RES *respond);

/*------------------------------ HTTP ͷ캯 -----------------------------*/
/* in http_hdr_build.c */

/**
 * ͨHTTPͷ
 * @param hdr {HTTP_HDR*} ͨHTTPͷ
 * @param name {const char*}  Accept-Encoding: deflate, gzip е Accept-Encoding
 * @param value {const char*} ֵ Accept-Encoding: deflate, gzip е deflate, gzip
 */
HTTP_API void http_hdr_put_str(HTTP_HDR *hdr, const char *name, const char *value);

/**
 * ͨHTTPͷ
 * @param hdr {HTTP_HDR*} ͨHTTPͷ
 * @param name {const char*}  Content-Length: 1024 е Conteng-Length
 * @param value {const int} ֵ Content-Length: 1024 е 1024
 */
HTTP_API void http_hdr_put_int(HTTP_HDR *hdr, const char *name, int value);

/**
 * ͨHTTPͷ
 * @param hdr {HTTP_HDR*} ͨHTTPͷ
 * @param name {const char*}  Accept-Encoding: deflate, gzip е Accept-Encoding
 * @param fmt {const char*} θʽַ
 */
# if defined(WIN32) || defined(WIN64)
HTTP_API void http_hdr_put_fmt(HTTP_HDR *hdr, const char *name, const char *fmt, ...);
#else
HTTP_API void __attribute__((format(printf,3,4)))
	http_hdr_put_fmt(HTTP_HDR *hdr, const char *name, const char *fmt, ...);
#endif

/**
 * ͨHTTPͷʱ
 * @param hdr {HTTP_HDR*} ͨHTTPͷ
 * @param name {const char*} 
 * @param t {time_t} ʱֵ
 */
HTTP_API void http_hdr_put_time(HTTP_HDR *hdr, const char *name, time_t t);

/**
 * HTTPͷֶǷ˱ֳ, 洢HTTPӦͷ
 * @param req {const HTTP_HDR_REQ*} HTTPͷ
 * @param res {HTTP_HDR_RES*} HTTPӦͷ洢
 */
HTTP_API int http_hdr_set_keepalive(const HTTP_HDR_REQ *req, HTTP_HDR_RES *res);

/**
 * ÷״̬(1xx, 2xx, 3xx, 4xx, 5xx) ʼһHTTPӦͷ
 * @param hdr_res {HTTP_HDR_RES*} HTTPӦͷ洢
 * @param status {int} ״̬ţnxx(1xx, 2xx, 3xx, 4xx, 5xx)
 */
HTTP_API void http_hdr_res_init(HTTP_HDR_RES *hdr_res, int status);

/**
 * ÷״̬(nxx)һHTTPӦͷ
 * @param status {int} ״̬ţnxx(1xx, 2xx, 3xx, 4xx, 5xx)
 * @return {HTTP_HDR_RES*} ɵHTTPӦͷ
 */
HTTP_API HTTP_HDR_RES *http_hdr_res_static(int status);

/**
* ÷״̬(nxx)һHTTPӦͷ
* @param status {int} ״̬ţnxx(4xx, 5xx)
* @return {HTTP_HDR_RES*} ɵHTTPӦͷ
*/
HTTP_API HTTP_HDR_RES *http_hdr_res_error(int status);

/**
 * HTTPͨͷͷBUF
 * @param hdr {const HTTP_HDR*} ͨHTTPͷ
 * @param strbuf {ACL_VSTRING*} 洢Ļ
 */
HTTP_API void http_hdr_build(const HTTP_HDR *hdr, ACL_VSTRING *strbuf);

/**
 * HTTPͷͷBUF
 * @param hdr_req {const HTTP_HDR_REQ*} HTTPͷ
 * @param strbuf {ACL_VSTRING*} 洢Ļ
 */
HTTP_API void http_hdr_build_request(const HTTP_HDR_REQ *hdr_req, ACL_VSTRING *strbuf);

/*----------------------------- HTTP Ӧ״̬Ϣ ------------------------*/
/* in http_status.c */

/**
 * HTTPӦ(nxx)ظֵַ
 * @param status {int} ״̬ţnxx(1xx, 2xx, 3xx, 4xx, 5xx)
 * @return {const char*} ӦӦַʾ
 */
HTTP_API const char *http_status_line(int status);

/*---------------------------- HTTP HTML ģ ------------------------*/
/* in http_tmpl.c */

/**
 * װHTTPӦHTMLģ
 * @param tmpl_path {const char*} HTMLģļڵ·
 */
HTTP_API void http_tmpl_load(const char *tmpl_path);

/**
 * ȡӦHTTPӦ״̬ģϢ
 * @param status {int} HTTP ״̬Ӧ
 * @return {const ACL_VSTRING*} ӦHTTPӦ״̬ģϢ
 */
HTTP_API const ACL_VSTRING *http_tmpl_get(int status);

/**
 * ȡӦHTTPӦ״̬ıʾϢ
 * @param status {int} HTTP ״̬Ӧ
 * @return {const char*} ӦHTTPӦ״̬ıʾϢ
 */
HTTP_API const char *http_tmpl_title(int status);

/**
 * ӦHTTPӦ״̬ģʾϢĳȴС
 * @param status {int} HTTP ״̬Ӧ
 * @return {int} ģʾϢĳȴС
 */
HTTP_API int http_tmpl_size(int status);

/*---------------------------- HTTP HTML ģʼ ----------------------*/
/* in http_init.c */

/**
 * ʼHTTPӦЭ
 * @param tmpl_path {const char*} ģϢļĴ·
 */
HTTP_API void http_init(const char *tmpl_path);

/**
 * ǷԶ屻ͷŵ HTTP ͷ󣬴Ӷʹڴظʹ, úڳʼ
 * ʱֻܱһ
 * @param max {int} ֵ > 0 ʱԶ HTTP ͷ󻺳幦
 */
HTTP_API void http_hdr_cache(int max);

/**
 * ڽ HTTP ЭݴʱĻС
 * @param size {http_off_t} С
 */
HTTP_API void http_buf_size_set(http_off_t size);

/**
 * ý HTTP ЭݴʱĻС
 * @return {http_off_t} С
 */
HTTP_API http_off_t http_buf_size_get(void);

#ifdef	__cplusplus
}
#endif

#endif
