ultimatepp/uppsrc/Web/httpsrv.h
mdelfede d2b54f7989 changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-06-07 22:31:27 +00:00

185 lines
7 KiB
C++

String MIMECharsetName(byte charset);
inline String HttpContentType(String type) { return "Content-Type: " + type + "\r\n"; }
inline String HttpTextHtml(String encoding) { return "text/html; charset=" + encoding; }
inline String HttpTextHtml(byte charset = CHARSET_DEFAULT) { return HttpTextHtml(MIMECharsetName(charset)); }
//inline String HttpTextHtml1250() { return "text/html; charset=windows-1250"; }
inline String HttpTextPlain(String encoding) { return "text/plain; charset=" + encoding; }
//inline String HttpTextPlain1250() { return "text/plain; charset=windows-1250"; }
inline String HttpTextPlain(byte charset = CHARSET_DEFAULT) { return HttpTextPlain(MIMECharsetName(charset)); }
inline String HttpTextXml() { return "text/xml"; }
inline String HttpImage(String format) { return "image/" + format; }
inline String HttpImageGif() { return "image/gif"; }
inline String HttpImageJpg() { return "image/jpeg"; }
inline String HttpImagePng() { return "image/png"; }
inline String HttpBinary() { return "application/octet-stream"; }
class HttpServer;
class HttpRequest
{
friend class HttpServer;
public:
HttpRequest(HttpServer& server, pick_ Socket& socket, HttpQuery query);
HttpServer& GetServer() { return server; }
Socket& GetSocket() { return socket; }
#ifdef PLATFORM_WIN32
Event& GetEvent() { return event; }
#endif
HttpQuery GetQuery() const { return query; }
bool IsLogging() const;
void LogTime(const char *s, int level);
int GetDuration() const;
void Write(String header, String body, int result_code, String result_text);
void Write(String header, String body);
void Write(String body) { Write(Null, body); }
void Redirect(String url);
void Error(String err);
private:
HttpServer& server;
Socket socket;
#ifdef PLATFORM_WIN32
SocketEvent event;
#endif
HttpQuery query;
dword request_ticks;
};
class HttpServer
{
public:
HttpServer();
bool Open(int port, int listen_count = 5);
bool Reopen();
void Close();
bool IsOpen() const { return socket.IsOpen(); }
bool IsError() const { return socket.IsError(); }
int GetPort() const { return server_port; }
Socket& GetSocket() { return socket; }
Socket& GetConnSocket() { return connection; }
#ifdef PLATFORM_WIN32
Event& GetEvent() { return sock_event; }
Event& GetConnEvent() { return conn_event; }
#endif
void Logging(const char *log = NULL, int max_log_size = 500000);
void NoLogging() { logfile = Null; }
bool IsLogging() const { return !logfile.IsEmpty(); }
void Log(const char *s, int level);
void LogTime(const char *s, int level);
HttpServer& operator << (const char *s) { Log(s, 0); return *this; }
static HttpServer *Wait(const Vector<HttpServer *>& list, int msec);
bool Wait(int msec);
void GetReadSockets(Vector<Socket *>& sockets);
void GetWriteSockets(Vector<Socket *>& sockets);
#ifdef PLATFORM_WIN32
void GetWaitEvents(Vector<Event *>& events);
#endif
One<HttpRequest> GetRequest();
Time GetStartTime() const { return start_time; }
double GetHitCount() const { return hit_count; }
double GetResponseTime() const { return total_response_msec; }
double GetAvgTime() const;
double GetAvgLagTime() const;
double GetElapsedTime() const; // msec
String GetDefaultHeader() const { return default_header; }
void DefaultHeader(String h) { default_header = h; }
int GetMaxPostSize() const { return max_post_size; }
void MaxPostSize(int size) { max_post_size = size; }
int GetMaxRequestTime() const { return max_request_time; }
void MaxRequestTime(int time) { max_request_time = time; }
bool IsShowQuery() const { return show_headers; }
void ShowQuery(bool sh = true) { show_headers = sh; }
void AddRequest(int duration_msec);
void ReadPostData(Socket& socket, HttpQuery& query);
void AddWrite(Socket socket, String data);
bool DelayedWrite();
bool IsDelayedWrite() const;
public:
Callback2<String, int> WhenLog;
private:
bool Accept();
private:
Socket socket;
Socket connection;
#ifdef PLATFORM_WIN32
SocketEvent sock_event;
SocketEvent conn_event;
#endif
class SocketWrite
{
public:
SocketWrite(Socket socket, String data, int ticks = 0);
public:
Socket socket;
#ifdef PLATFORM_WIN32
SocketEvent sock_event;
#endif
String data;
int done;
int ticks;
};
Array<SocketWrite> delayed_writes;
int server_port;
dword ipaddr;
String default_header;
String logfile;
int max_log_size;
enum { DEFAULT_MAX_POST_SIZE = 1000000 };
int max_post_size;
enum { DEFAULT_MAX_REQUEST_TIME = 60000 };
int max_request_time;
bool show_headers;
int request_time;
int request_state;
enum { RS_FIRST, RS_SAPI, RS_GET_HEADERS, RS_POST_HEADERS, RS_POST_DATA };
String first_line;
String sapi_request;
int sapi_length;
int request_version;
String header_line;
int headers_length;
int post_length;
String post_data;
HttpQuery request_query;
Time start_time;
double hit_count;
double total_response_msec;
enum { TRAILER = 10 };
dword trailing_times[TRAILER];
dword trailing_sum;
int trailing_count;
};
inline bool HttpRequest::IsLogging() const { return server.IsLogging(); }
inline String GetHttpPath(HttpQuery query) { return query.GetString("$$PATH"); }
inline String GetHttpQuery(HttpQuery query) { return query.GetString("$$QUERY"); }
String GetHttpURI(HttpQuery query);
void GetHttpPostData(HttpQuery& query, String data);
String GetHttpQueryDump(HttpQuery query);
String GetHttpErrorPage(HttpQuery query, String err, bool show_query);