1057 lines
25 KiB
C
1057 lines
25 KiB
C
/*
|
|
* $Id$
|
|
*
|
|
Copyright 2006-2014 Chung, Hyung-Hwan.
|
|
This file is part of QSE.
|
|
|
|
QSE is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as
|
|
published by the Free Software Foundation, either version 3 of
|
|
the License, or (at your option) any later version.
|
|
|
|
QSE is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with QSE. If not, see <htrd://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef _QSE_HTTP_HTTPD_H_
|
|
#define _QSE_HTTP_HTTPD_H_
|
|
|
|
#include <qse/types.h>
|
|
#include <qse/macros.h>
|
|
#include <qse/http/htre.h>
|
|
#include <qse/http/htrd.h>
|
|
#include <qse/cmn/nwad.h>
|
|
#include <qse/cmn/time.h>
|
|
#include <qse/cmn/tmr.h>
|
|
|
|
typedef struct qse_httpd_t qse_httpd_t;
|
|
typedef struct qse_httpd_mate_t qse_httpd_mate_t;
|
|
typedef struct qse_httpd_server_t qse_httpd_server_t;
|
|
typedef struct qse_httpd_client_t qse_httpd_client_t;
|
|
typedef struct qse_httpd_dns_t qse_httpd_dns_t;
|
|
typedef struct qse_httpd_urs_t qse_httpd_urs_t;
|
|
|
|
enum qse_httpd_errnum_t
|
|
{
|
|
QSE_HTTPD_ENOERR,
|
|
QSE_HTTPD_EOTHER,
|
|
QSE_HTTPD_ENOIMPL,
|
|
QSE_HTTPD_ESYSERR,
|
|
QSE_HTTPD_EINTERN,
|
|
|
|
QSE_HTTPD_ENOMEM,
|
|
QSE_HTTPD_EINVAL,
|
|
QSE_HTTPD_EACCES,
|
|
QSE_HTTPD_ENOENT,
|
|
QSE_HTTPD_EEXIST,
|
|
QSE_HTTPD_EINTR,
|
|
QSE_HTTPD_EPIPE,
|
|
QSE_HTTPD_EAGAIN,
|
|
|
|
QSE_HTTPD_ENOSVR, /* no active servers */
|
|
QSE_HTTPD_ECONN,
|
|
QSE_HTTPD_ENOBUF, /* no buffer available */
|
|
QSE_HTTPD_EDISCON, /* client disconnnected */
|
|
QSE_HTTPD_EBADREQ, /* bad request */
|
|
QSE_HTTPD_ENODNS, /* dns service not activated/enabled or no valid dns server specified */
|
|
QSE_HTTPD_ENOURS, /* urs service not activated/enabled or no valid urs server specified */
|
|
QSE_HTTPD_ETASK
|
|
};
|
|
typedef enum qse_httpd_errnum_t qse_httpd_errnum_t;
|
|
|
|
enum qse_httpd_opt_t
|
|
{
|
|
QSE_HTTPD_TRAIT,
|
|
QSE_HTTPD_SCB,
|
|
QSE_HTTPD_RCB,
|
|
QSE_HTTPD_TMOUT,
|
|
QSE_HTTPD_IDLELIMIT
|
|
};
|
|
typedef enum qse_httpd_opt_t qse_httpd_opt_t;
|
|
|
|
enum qse_httpd_trait_t
|
|
{
|
|
QSE_HTTPD_MUTECLIENT = (1 << 0),
|
|
QSE_HTTPD_CGIERRTONUL = (1 << 1),
|
|
QSE_HTTPD_CGINOCLOEXEC = (1 << 2),
|
|
QSE_HTTPD_CGINOCHUNKED = (1 << 3),
|
|
QSE_HTTPD_PROXYNOVIA = (1 << 4),
|
|
QSE_HTTPD_LOGACT = (1 << 5),
|
|
QSE_HTTPD_DNSNOA = (1 << 6),
|
|
QSE_HTTPD_DNSNOAAAA = (1 << 7),
|
|
};
|
|
typedef enum qse_httpd_trait_t qse_httpd_trait_t;
|
|
|
|
typedef struct qse_httpd_stat_t qse_httpd_stat_t;
|
|
struct qse_httpd_stat_t
|
|
{
|
|
int isdir;
|
|
qse_long_t dev;
|
|
qse_long_t ino;
|
|
qse_foff_t size;
|
|
qse_ntime_t mtime;
|
|
};
|
|
|
|
typedef struct qse_httpd_peer_t qse_httpd_peer_t;
|
|
struct qse_httpd_peer_t
|
|
{
|
|
qse_nwad_t nwad;
|
|
qse_nwad_t local; /* local side address facing the peer */
|
|
qse_ubi_t handle;
|
|
};
|
|
|
|
enum qse_httpd_mux_mask_t
|
|
{
|
|
QSE_HTTPD_MUX_READ = (1 << 0),
|
|
QSE_HTTPD_MUX_WRITE = (1 << 1)
|
|
};
|
|
|
|
typedef int (*qse_httpd_muxcb_t) (
|
|
qse_httpd_t* httpd,
|
|
void* mux,
|
|
qse_ubi_t handle,
|
|
int mask, /* ORed of qse_httpd_mux_mask_t */
|
|
void* cbarg
|
|
);
|
|
|
|
typedef struct qse_httpd_dirent_t qse_httpd_dirent_t;
|
|
|
|
struct qse_httpd_dirent_t
|
|
{
|
|
const qse_mchar_t* name;
|
|
qse_httpd_stat_t stat;
|
|
};
|
|
|
|
typedef struct qse_httpd_natr_t qse_httpd_natr_t;
|
|
|
|
struct qse_httpd_natr_t
|
|
{
|
|
qse_nwad_t nwad;
|
|
qse_ntime_t tmout;
|
|
int retries;
|
|
};
|
|
|
|
typedef void (*qse_httpd_resol_t) (
|
|
qse_httpd_t* httpd,
|
|
const qse_mchar_t* name,
|
|
const qse_nwad_t* nwad,
|
|
void* ctx
|
|
);
|
|
|
|
typedef void (*qse_httpd_rewrite_t) (
|
|
qse_httpd_t* httpd,
|
|
const qse_mchar_t* url,
|
|
const qse_mchar_t* new_url,
|
|
void* ctx
|
|
);
|
|
|
|
typedef struct qse_httpd_scb_t qse_httpd_scb_t;
|
|
struct qse_httpd_scb_t
|
|
{
|
|
struct
|
|
{
|
|
int (*open) (qse_httpd_t* httpd, qse_httpd_server_t* server);
|
|
void (*close) (qse_httpd_t* httpd, qse_httpd_server_t* server);
|
|
int (*accept) (qse_httpd_t* httpd, qse_httpd_server_t* server, qse_httpd_client_t* client);
|
|
} server;
|
|
|
|
struct
|
|
{
|
|
int (*open) (qse_httpd_t* httpd, qse_httpd_peer_t* peer);
|
|
void (*close) (qse_httpd_t* httpd, qse_httpd_peer_t* peer);
|
|
int (*connected) (qse_httpd_t* httpd, qse_httpd_peer_t* peer);
|
|
|
|
qse_ssize_t (*recv) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_peer_t* peer,
|
|
qse_mchar_t* buf, qse_size_t bufsize);
|
|
|
|
qse_ssize_t (*send) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_peer_t* peer,
|
|
const qse_mchar_t* buf, qse_size_t bufsize);
|
|
} peer;
|
|
|
|
struct
|
|
{
|
|
void* (*open) (qse_httpd_t* httpd, qse_httpd_muxcb_t muxcb);
|
|
void (*close) (qse_httpd_t* httpd, void* mux);
|
|
int (*addhnd) (qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg);
|
|
int (*delhnd) (qse_httpd_t* httpd, void* mux, qse_ubi_t handle);
|
|
int (*poll) (qse_httpd_t* httpd, void* mux, const qse_ntime_t* tmout);
|
|
|
|
int (*readable) (
|
|
qse_httpd_t* httpd, qse_ubi_t handle, const qse_ntime_t* tmout);
|
|
int (*writable) (
|
|
qse_httpd_t* httpd, qse_ubi_t handle, const qse_ntime_t* tmout);
|
|
} mux;
|
|
|
|
struct
|
|
{
|
|
int (*stat) (
|
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
|
qse_httpd_stat_t* stat);
|
|
int (*purge) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
|
|
|
int (*ropen) (
|
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
|
qse_ubi_t* handle);
|
|
int (*wopen) (
|
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
|
qse_ubi_t* handle);
|
|
void (*close) (qse_httpd_t* httpd, qse_ubi_t handle);
|
|
|
|
qse_ssize_t (*read) (
|
|
qse_httpd_t* httpd, qse_ubi_t handle,
|
|
qse_mchar_t* buf, qse_size_t len);
|
|
qse_ssize_t (*write) (
|
|
qse_httpd_t* httpd, qse_ubi_t handle,
|
|
const qse_mchar_t* buf, qse_size_t len);
|
|
} file;
|
|
|
|
struct
|
|
{
|
|
int (*stat) (
|
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
|
qse_httpd_stat_t* stat);
|
|
int (*make) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
|
int (*purge) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
|
|
|
int (*open) (
|
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
|
qse_ubi_t* handle);
|
|
void (*close) (qse_httpd_t* httpd, qse_ubi_t handle);
|
|
int (*read) (
|
|
qse_httpd_t* httpd, qse_ubi_t handle,
|
|
qse_httpd_dirent_t* ent);
|
|
} dir;
|
|
|
|
struct
|
|
{
|
|
void (*close) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client);
|
|
|
|
void (*shutdown) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client);
|
|
|
|
/* action */
|
|
qse_ssize_t (*recv) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_mchar_t* buf, qse_size_t bufsize);
|
|
|
|
qse_ssize_t (*send) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
const qse_mchar_t* buf, qse_size_t bufsize);
|
|
|
|
qse_ssize_t (*sendfile) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_ubi_t handle, qse_foff_t* offset, qse_size_t count);
|
|
|
|
/* event notification */
|
|
int (*accepted) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client); /* optional */
|
|
void (*closed) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client); /* optional */
|
|
} client;
|
|
|
|
struct
|
|
{
|
|
int (*open) (qse_httpd_t* httpd, qse_httpd_dns_t* dns);
|
|
void (*close) (qse_httpd_t* httpd, qse_httpd_dns_t* dns);
|
|
int (*recv) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, qse_ubi_t handle);
|
|
int (*send) (qse_httpd_t* httpd, qse_httpd_dns_t* dns,
|
|
const qse_mchar_t* name, qse_httpd_resol_t resol,
|
|
const qse_httpd_natr_t* dns_server, void* ctx);
|
|
} dns;
|
|
|
|
struct
|
|
{
|
|
int (*open) (qse_httpd_t* httpd, qse_httpd_urs_t* urs);
|
|
void (*close) (qse_httpd_t* httpd, qse_httpd_urs_t* urs);
|
|
int (*recv) (qse_httpd_t* httpd, qse_httpd_urs_t* urs, qse_ubi_t handle);
|
|
int (*send) (qse_httpd_t* httpd, qse_httpd_urs_t* urs,
|
|
const qse_mchar_t* url, qse_httpd_rewrite_t rewrite,
|
|
const qse_httpd_natr_t* urs_server, void* ctx);
|
|
} urs;
|
|
};
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
typedef int (*qse_httpd_peekreq_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
typedef int (*qse_httpd_pokereq_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
typedef int (*qse_httpd_fmterr_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
int code,
|
|
qse_mchar_t* buf,
|
|
int bufsz
|
|
);
|
|
|
|
typedef void (*qse_httpd_impede_t) (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
enum qse_httpd_act_code_t
|
|
{
|
|
QSE_HTTPD_CATCH_MERRMSG,
|
|
QSE_HTTPD_CATCH_MWARNMSG,
|
|
QSE_HTTPD_CATCH_MDBGMSG,
|
|
QSE_HTTPD_ACCEPT_CLIENT,
|
|
QSE_HTTPD_PURGE_CLIENT,
|
|
QSE_HTTPD_READERR_CLIENT
|
|
};
|
|
typedef enum qse_httpd_act_code_t qse_httpd_act_code_t;
|
|
|
|
struct qse_httpd_act_t
|
|
{
|
|
qse_httpd_act_code_t code;
|
|
union
|
|
{
|
|
qse_httpd_client_t* client;
|
|
qse_mchar_t merrmsg[128];
|
|
qse_mchar_t mwarnmsg[128];
|
|
qse_mchar_t mdbgmsg[128];
|
|
} u;
|
|
};
|
|
typedef struct qse_httpd_act_t qse_httpd_act_t;
|
|
|
|
typedef void (*qse_httpd_logact_t) (
|
|
qse_httpd_t* httpd,
|
|
const qse_httpd_act_t* act
|
|
);
|
|
|
|
typedef struct qse_httpd_rcb_t qse_httpd_rcb_t;
|
|
struct qse_httpd_rcb_t
|
|
{
|
|
qse_httpd_peekreq_t peekreq;
|
|
qse_httpd_pokereq_t pokereq;
|
|
qse_httpd_fmterr_t fmterr;
|
|
qse_httpd_impede_t impede;
|
|
qse_httpd_logact_t logact;
|
|
};
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
typedef struct qse_httpd_task_t qse_httpd_task_t;
|
|
|
|
typedef int (*qse_httpd_task_init_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* task
|
|
);
|
|
|
|
typedef void (*qse_httpd_task_fini_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* task
|
|
);
|
|
|
|
typedef int (*qse_httpd_task_main_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* task
|
|
);
|
|
|
|
enum qse_httpd_task_trigger_flag_t
|
|
{
|
|
QSE_HTTPD_TASK_TRIGGER_INACTIVE = (1 << 0)
|
|
};
|
|
|
|
enum qse_httpd_task_trigger_mask_t
|
|
{
|
|
QSE_HTTPD_TASK_TRIGGER_READ = (1 << 0),
|
|
QSE_HTTPD_TASK_TRIGGER_WRITE = (1 << 1),
|
|
QSE_HTTPD_TASK_TRIGGER_READABLE = (1 << 2),
|
|
QSE_HTTPD_TASK_TRIGGER_WRITABLE = (1 << 3)
|
|
};
|
|
|
|
#define QSE_HTTPD_TASK_TRIGGER_MAX 3
|
|
|
|
typedef struct qse_httpd_task_trigger_t qse_httpd_task_trigger_t;
|
|
struct qse_httpd_task_trigger_t
|
|
{
|
|
int flags; /**< [IN] bitwise-ORed of #qse_httpd_task_trigger_flag_t enumerators*/
|
|
int cmask; /* client mask - QSE_HTTPD_TASK_TRIGGER_READ | QSE_HTTPD_TASK_TRIGGER_WRITE */
|
|
struct
|
|
{
|
|
int mask; /* QSE_HTTPD_TASK_TRIGGER_READ | QSE_HTTPD_TASK_TRIGGER_WRITE */
|
|
qse_ubi_t handle;
|
|
} v[QSE_HTTPD_TASK_TRIGGER_MAX];
|
|
};
|
|
|
|
struct qse_httpd_task_t
|
|
{
|
|
/* you must not call another entask functions from within
|
|
* an initailizer. you can call entask functions from within
|
|
* a finalizer and a main function. */
|
|
qse_httpd_task_init_t init; /**< [IN] initializer */
|
|
qse_httpd_task_fini_t fini; /**< [IN] finalizer */
|
|
qse_httpd_task_main_t main; /**< [IN] main task function */
|
|
qse_httpd_task_trigger_t trigger;
|
|
void* ctx; /**< [IN OUT] user-defined data */
|
|
};
|
|
|
|
enum qse_httpd_mate_type_t
|
|
{
|
|
QSE_HTTPD_SERVER,
|
|
QSE_HTTPD_CLIENT,
|
|
QSE_HTTPD_DNS,
|
|
QSE_HTTPD_URS
|
|
};
|
|
typedef enum qse_httpd_mate_type_t qse_httpd_mate_type_t;
|
|
|
|
/* it contains header fields common between
|
|
* qse_httpd_cleint_t and qse_httpd_server_t. */
|
|
#define QSE_HTTPD_MATE_HDR \
|
|
qse_httpd_mate_type_t type
|
|
|
|
struct qse_httpd_mate_t
|
|
{
|
|
/* == PRIVATE == */
|
|
QSE_HTTPD_MATE_HDR;
|
|
};
|
|
|
|
struct qse_httpd_client_t
|
|
{
|
|
/* == PRIVATE == */
|
|
QSE_HTTPD_MATE_HDR;
|
|
|
|
/* == PUBLIC == */
|
|
qse_ubi_t handle;
|
|
qse_ubi_t handle2;
|
|
qse_nwad_t remote_addr;
|
|
qse_nwad_t local_addr;
|
|
qse_nwad_t orgdst_addr;
|
|
qse_httpd_server_t* server;
|
|
int initial_ifindex;
|
|
|
|
/* == PRIVATE == */
|
|
qse_htrd_t* htrd;
|
|
int status;
|
|
qse_httpd_task_trigger_t trigger;
|
|
qse_ntime_t last_active;
|
|
|
|
qse_tmr_index_t tmr_idle;
|
|
|
|
qse_httpd_client_t* prev;
|
|
qse_httpd_client_t* next;
|
|
|
|
qse_httpd_client_t* bad_next;
|
|
|
|
struct
|
|
{
|
|
int count;
|
|
qse_httpd_task_t* head;
|
|
qse_httpd_task_t* tail;
|
|
} task;
|
|
};
|
|
|
|
/* client->status */
|
|
#define QSE_HTTPD_CLIENT_BAD (1 << 0)
|
|
#define QSE_HTTPD_CLIENT_READY (1 << 1)
|
|
#define QSE_HTTPD_CLIENT_INTERCEPTED (1 << 2)
|
|
#define QSE_HTTPD_CLIENT_SECURE (1 << 3)
|
|
#define QSE_HTTPD_CLIENT_PENDING (1 << 4)
|
|
#define QSE_HTTPD_CLIENT_MUTE (1 << 5)
|
|
#define QSE_HTTPD_CLIENT_MUTE_DELETED (1 << 6)
|
|
#define QSE_HTTPD_CLIENT_HANDLE_READ_IN_MUX (1 << 7)
|
|
#define QSE_HTTPD_CLIENT_HANDLE_WRITE_IN_MUX (1 << 8)
|
|
#define QSE_HTTPD_CLIENT_HANDLE_RW_IN_MUX (QSE_HTTPD_CLIENT_HANDLE_READ_IN_MUX | QSE_HTTPD_CLIENT_HANDLE_WRITE_IN_MUX)
|
|
|
|
#define QSE_HTTPD_CLIENT_TASK_TRIGGER_READ_IN_MUX(i) (1 << ((i) + 9))
|
|
#define QSE_HTTPD_CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i) (1 << ((i) + 9 + QSE_HTTPD_TASK_TRIGGER_MAX))
|
|
#define QSE_HTTPD_CLIENT_TASK_TRIGGER_RW_IN_MUX(i) (QSE_HTTPD_CLIENT_TASK_TRIGGER_READ_IN_MUX(i) | QSE_HTTPD_CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i))
|
|
|
|
enum qse_httpd_server_flag_t
|
|
{
|
|
QSE_HTTPD_SERVER_ACTIVE = (1 << 0),
|
|
QSE_HTTPD_SERVER_SECURE = (1 << 1),
|
|
QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2)
|
|
};
|
|
|
|
typedef void (*qse_httpd_server_detach_t) (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_server_t* server
|
|
);
|
|
|
|
typedef struct qse_httpd_server_dope_t qse_httpd_server_dope_t;
|
|
|
|
struct qse_httpd_server_dope_t
|
|
{
|
|
int flags; /* bitwise-ORed of qse_httpd_server_flag_t */
|
|
qse_nwad_t nwad; /* binding address */
|
|
unsigned int nwif; /* interface number to bind to */
|
|
qse_httpd_server_detach_t detach; /* executed when the server is detached */
|
|
};
|
|
|
|
struct qse_httpd_server_t
|
|
{
|
|
/* == PRIVATE == */
|
|
QSE_HTTPD_MATE_HDR;
|
|
|
|
/* provided by a user for attaching */
|
|
qse_httpd_server_dope_t dope;
|
|
|
|
/* set by server.open callback */
|
|
qse_ubi_t handle;
|
|
|
|
/* private */
|
|
qse_httpd_t* httpd;
|
|
qse_httpd_server_t* next;
|
|
qse_httpd_server_t* prev;
|
|
};
|
|
|
|
|
|
struct qse_httpd_dns_t
|
|
{
|
|
/* == PRIVATE == */
|
|
QSE_HTTPD_MATE_HDR;
|
|
|
|
/* == PUBLIC == */
|
|
qse_ubi_t handle[5];
|
|
int handle_count;
|
|
void* ctx;
|
|
};
|
|
|
|
struct qse_httpd_urs_t
|
|
{
|
|
/* PRIVATE == */
|
|
QSE_HTTPD_MATE_HDR;
|
|
|
|
/* == PUBLIC == */
|
|
qse_ubi_t handle[5];
|
|
int handle_count;
|
|
void* ctx;
|
|
};
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* The qse_httpd_rsrc_type_t defines the resource type than can
|
|
* be entasked with qse_httpd_entaskrsrc().
|
|
*/
|
|
enum qse_httpd_rsrc_type_t
|
|
{
|
|
QSE_HTTPD_RSRC_AUTH,
|
|
QSE_HTTPD_RSRC_CGI,
|
|
QSE_HTTPD_RSRC_DIR,
|
|
QSE_HTTPD_RSRC_ERROR,
|
|
QSE_HTTPD_RSRC_FILE,
|
|
QSE_HTTPD_RSRC_PROXY,
|
|
QSE_HTTPD_RSRC_RELOC,
|
|
QSE_HTTPD_RSRC_REDIR,
|
|
QSE_HTTPD_RSRC_TEXT
|
|
};
|
|
typedef enum qse_httpd_rsrc_type_t qse_httpd_rsrc_type_t;
|
|
|
|
enum qse_httpd_rsrc_flag_t
|
|
{
|
|
QSE_HTTPD_RSRC_100_CONTINUE = (1 << 0)
|
|
};
|
|
|
|
typedef struct qse_httpd_rsrc_cgi_t qse_httpd_rsrc_cgi_t;
|
|
struct qse_httpd_rsrc_cgi_t
|
|
{
|
|
const qse_mchar_t* path;
|
|
const qse_mchar_t* script;
|
|
const qse_mchar_t* suffix;
|
|
const qse_mchar_t* root;
|
|
const qse_mchar_t* shebang;
|
|
int nph;
|
|
};
|
|
|
|
enum qse_httpd_rsrc_proxy_flag_t
|
|
{
|
|
QSE_HTTPD_RSRC_PROXY_RAW = (1 << 0), /* raw proxying. set this for CONNECT */
|
|
QSE_HTTPD_RSRC_PROXY_TRANSPARENT = (1 << 1),
|
|
QSE_HTTPD_RSRC_PROXY_DST_STR = (1 << 2), /* destination is an unresovled string pointed to by dst.str */
|
|
QSE_HTTPD_RSRC_PROXY_ENABLE_DNS = (1 << 3), /* dns service enabled */
|
|
QSE_HTTPD_RSRC_PROXY_ENABLE_URS = (1 << 4), /* url rewriting enabled */
|
|
QSE_HTTPD_RSRC_PROXY_DNS_SERVER = (1 << 5), /* dns address specified */
|
|
QSE_HTTPD_RSRC_PROXY_URS_SERVER = (1 << 6) /* urs address specified */
|
|
};
|
|
|
|
typedef struct qse_httpd_rsrc_proxy_t qse_httpd_rsrc_proxy_t;
|
|
struct qse_httpd_rsrc_proxy_t
|
|
{
|
|
int flags; /* bitwise-ORed of qse_httpd_rsrc_proxy_flag_t enumerators */
|
|
|
|
const qse_mchar_t* host; /* host name part that were in the original request url */
|
|
union
|
|
{
|
|
qse_nwad_t nwad;
|
|
} src; /* local binding address */
|
|
union
|
|
{
|
|
qse_nwad_t nwad;
|
|
const qse_mchar_t* str;
|
|
} dst; /* remote destination address to connect to */
|
|
|
|
qse_httpd_natr_t dns_server;
|
|
qse_httpd_natr_t urs_server;
|
|
|
|
const qse_mchar_t* pseudonym; /* pseudonym to use in Via: */
|
|
};
|
|
|
|
typedef struct qse_httpd_rsrc_dir_t qse_httpd_rsrc_dir_t;
|
|
struct qse_httpd_rsrc_dir_t
|
|
{
|
|
const qse_mchar_t* path;
|
|
const qse_mchar_t* head;
|
|
const qse_mchar_t* foot;
|
|
};
|
|
|
|
typedef struct qse_httpd_rsrc_t qse_httpd_rsrc_t;
|
|
struct qse_httpd_rsrc_t
|
|
{
|
|
qse_httpd_rsrc_type_t type;
|
|
int flags; /**< bitwised-ORed of #qse_httpd_rsrc_flag_t */
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
const qse_mchar_t* realm;
|
|
} auth;
|
|
|
|
qse_httpd_rsrc_cgi_t cgi;
|
|
qse_httpd_rsrc_dir_t dir;
|
|
|
|
struct
|
|
{
|
|
int code;
|
|
} error;
|
|
|
|
struct
|
|
{
|
|
const qse_mchar_t* path;
|
|
const qse_mchar_t* mime;
|
|
} file;
|
|
|
|
qse_httpd_rsrc_proxy_t proxy;
|
|
|
|
struct
|
|
{
|
|
const qse_mchar_t* dst;
|
|
} reloc;
|
|
|
|
struct
|
|
{
|
|
const qse_mchar_t* dst;
|
|
} redir;
|
|
|
|
struct
|
|
{
|
|
const qse_mchar_t* ptr;
|
|
const qse_mchar_t* mime;
|
|
} text;
|
|
} u;
|
|
};
|
|
|
|
/**
|
|
* The qse_httpd_ecb_close_t type defines the callback function
|
|
* called when an httpd object is closed.
|
|
*/
|
|
typedef void (*qse_httpd_ecb_close_t) (
|
|
qse_httpd_t* httpd /**< httpd */
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_ecb_t type defines an event callback set.
|
|
* You can register a callback function set with
|
|
* qse_httpd_pushecb(). The callback functions in the registered
|
|
* set are called in the reverse order of registration.
|
|
*/
|
|
typedef struct qse_httpd_ecb_t qse_httpd_ecb_t;
|
|
struct qse_httpd_ecb_t
|
|
{
|
|
/**
|
|
* called by qse_httpd_close().
|
|
*/
|
|
qse_httpd_ecb_close_t close;
|
|
|
|
/* internal use only. don't touch this field */
|
|
qse_httpd_ecb_t* next;
|
|
};
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* The qse_httpd_open() function creates a httpd processor.
|
|
*/
|
|
QSE_EXPORT qse_httpd_t* qse_httpd_open (
|
|
qse_mmgr_t* mmgr, /**< memory manager */
|
|
qse_size_t xtnsize /**< extension size in bytes */
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_close() function destroys a httpd processor.
|
|
*/
|
|
QSE_EXPORT void qse_httpd_close (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT qse_mmgr_t* qse_httpd_getmmgr (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT void* qse_httpd_getxtn (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_errnum_t qse_httpd_geterrnum (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT void qse_httpd_seterrnum (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_errnum_t errnum
|
|
);
|
|
|
|
QSE_EXPORT int qse_httpd_getopt (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_opt_t id,
|
|
void* value
|
|
);
|
|
|
|
QSE_EXPORT int qse_httpd_setopt (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_opt_t id,
|
|
const void* value
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_popecb() function pops an httpd event callback set
|
|
* and returns the pointer to it. If no callback set can be popped,
|
|
* it returns #QSE_NULL.
|
|
*/
|
|
QSE_EXPORT qse_httpd_ecb_t* qse_httpd_popecb (
|
|
qse_httpd_t* httpd /**< httpd */
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_pushecb() function register a runtime callback set.
|
|
*/
|
|
QSE_EXPORT void qse_httpd_pushecb (
|
|
qse_httpd_t* httpd, /**< httpd */
|
|
qse_httpd_ecb_t* ecb /**< callback set */
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_loop() function starts a httpd server loop.
|
|
*/
|
|
QSE_EXPORT int qse_httpd_loop (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_stop() function requests to stop qse_httpd_loop()
|
|
*/
|
|
QSE_EXPORT void qse_httpd_stop (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT void qse_httpd_impede (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
#define qse_httpd_getserverxtn(httpd,server) ((void*)(server+1))
|
|
|
|
QSE_EXPORT qse_httpd_server_t* qse_httpd_attachserver (
|
|
qse_httpd_t* httpd,
|
|
const qse_httpd_server_dope_t* dope,
|
|
qse_size_t xtnsize
|
|
);
|
|
|
|
QSE_EXPORT void qse_httpd_detachserver (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_server_t* server
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_server_t* qse_httpd_getfirstserver (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_server_t* qse_httpd_getlastserver (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_server_t* qse_httpd_getnextserver (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_server_t* server
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_server_t* qse_httpd_getprevserver (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_server_t* server
|
|
);
|
|
|
|
QSE_EXPORT void qse_httpd_discardcontent (
|
|
qse_httpd_t* httpd,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT void qse_httpd_completecontent (
|
|
qse_httpd_t* httpd,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
|
|
/**
|
|
* The qse_httpd_setname() function changes the string
|
|
* to be used as the value for the server header.
|
|
*/
|
|
QSE_EXPORT void qse_httpd_setname (
|
|
qse_httpd_t* httpd,
|
|
const qse_mchar_t* name
|
|
);
|
|
|
|
|
|
/**
|
|
* The qse_httpd_getname() function returns the
|
|
* pointer to the string used as the value for the server
|
|
* header.
|
|
*/
|
|
QSE_EXPORT const qse_mchar_t* qse_httpd_getname (
|
|
qse_httpd_t* httpd
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_fmtgmtimetobb() function converts a numeric time @a nt
|
|
* to a string and stores it in a built-in buffer.
|
|
* If @a nt is QSE_NULL, the current time is used.
|
|
*/
|
|
QSE_EXPORT const qse_mchar_t* qse_httpd_fmtgmtimetobb (
|
|
qse_httpd_t* httpd,
|
|
const qse_ntime_t* nt,
|
|
int idx
|
|
);
|
|
|
|
QSE_EXPORT void* qse_httpd_gettaskxtn (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_task_t* task
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entask (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_httpd_task_t* task,
|
|
qse_size_t xtnsize
|
|
);
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskdisconnect (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred
|
|
);
|
|
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskformat (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* fmt,
|
|
...
|
|
);
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entasktext (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* text,
|
|
const qse_mchar_t* mime,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskerr (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
int code,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskcontinue (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
/**
|
|
* The qse_httpd_entaskauth() function adds a basic authorization task.
|
|
*/
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskauth (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* realm,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskreloc (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* dst,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskredir (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* dst,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entasknomod (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskallow (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* allow,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskdir (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
qse_httpd_rsrc_dir_t* dir,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskfile (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_mchar_t* name,
|
|
const qse_mchar_t* mime,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskcgi (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_httpd_rsrc_cgi_t* cgi,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskproxy (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
const qse_httpd_rsrc_proxy_t* proxy,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskrsrc (
|
|
qse_httpd_t* httpd,
|
|
qse_httpd_client_t* client,
|
|
qse_httpd_task_t* pred,
|
|
qse_httpd_rsrc_t* rsrc,
|
|
qse_htre_t* req
|
|
);
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
QSE_EXPORT void* qse_httpd_allocmem (
|
|
qse_httpd_t* httpd,
|
|
qse_size_t size
|
|
);
|
|
|
|
QSE_EXPORT void* qse_httpd_callocmem (
|
|
qse_httpd_t* httpd,
|
|
qse_size_t size
|
|
);
|
|
|
|
QSE_EXPORT void* qse_httpd_reallocmem (
|
|
qse_httpd_t* httpd,
|
|
void* ptr,
|
|
qse_size_t size
|
|
);
|
|
|
|
QSE_EXPORT void qse_httpd_freemem (
|
|
qse_httpd_t* httpd,
|
|
void* ptr
|
|
);
|
|
|
|
QSE_EXPORT qse_mchar_t* qse_httpd_strtombsdup (
|
|
qse_httpd_t* httpd,
|
|
const qse_char_t* str
|
|
);
|
|
|
|
QSE_EXPORT qse_mchar_t* qse_httpd_strntombsdup (
|
|
qse_httpd_t* httpd,
|
|
const qse_char_t* str,
|
|
qse_size_t len
|
|
);
|
|
|
|
QSE_EXPORT qse_mchar_t* qse_httpd_escapehtml (
|
|
qse_httpd_t* httpd,
|
|
const qse_mchar_t* str
|
|
);
|
|
|
|
QSE_EXPORT int qse_httpd_resolname (
|
|
qse_httpd_t* httpd,
|
|
const qse_mchar_t* name,
|
|
qse_httpd_resol_t resol,
|
|
const qse_httpd_natr_t* dns_server,
|
|
void* ctx
|
|
);
|
|
|
|
QSE_EXPORT int qse_httpd_rewriteurl (
|
|
qse_httpd_t* httpd,
|
|
const qse_mchar_t* url,
|
|
qse_httpd_rewrite_t rewrite,
|
|
const qse_httpd_natr_t* urs_server,
|
|
void* ctx
|
|
);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|