1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-07-29 21:01:13 +03:00

Made file dormat UNIX LF

This commit is contained in:
Thomas Davis
2013-09-01 02:40:52 -04:00
parent 9e17943d25
commit 6b7e1ff2a8
5 changed files with 6926 additions and 6902 deletions

View File

@ -19,74 +19,98 @@ bool exitNow = false;
class ExampleHandler: public CivetHandler { class ExampleHandler: public CivetHandler {
public: public:
bool handleGet(CivetServer *server, struct mg_connection *conn) { bool handleGet(CivetServer *server, struct mg_connection *conn) {
mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
mg_printf(conn, "<html><body>"); mg_printf(conn, "<html><body>");
mg_printf(conn, "<h2>This is example text!!!</h2>"); mg_printf(conn, "<h2>This is example text!!!</h2>");
mg_printf(conn, "<p>To exit <a href=\"%s\">click here</a></p>", mg_printf(conn, "<p>To exit <a href=\"%s\">click here</a></p>",
EXIT_URI); EXIT_URI);
mg_printf(conn, "</body></html>\n"); mg_printf(conn, "</body></html>\n");
return true; return true;
} }
}; };
class ExitHandler: public CivetHandler { class ExitHandler: public CivetHandler {
public: public:
bool handleGet(CivetServer *server, struct mg_connection *conn) { bool handleGet(CivetServer *server, struct mg_connection *conn) {
mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n");
mg_printf(conn, "Bye!\n"); mg_printf(conn, "Bye!\n");
exitNow = true; exitNow = true;
return true; return true;
} }
}; };
class AHandler: public CivetHandler { class AHandler: public CivetHandler {
public: public:
bool handleGet(CivetServer *server, struct mg_connection *conn) { bool handleGet(CivetServer *server, struct mg_connection *conn) {
mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
mg_printf(conn, "<html><body>"); mg_printf(conn, "<html><body>");
mg_printf(conn, "<h2>This is the A handler!!!</h2>"); mg_printf(conn, "<h2>This is the A handler!!!</h2>");
mg_printf(conn, "</body></html>\n"); mg_printf(conn, "</body></html>\n");
return true; return true;
} }
}; };
class ABHandler: public CivetHandler { class ABHandler: public CivetHandler {
public: public:
bool handleGet(CivetServer *server, struct mg_connection *conn) { bool handleGet(CivetServer *server, struct mg_connection *conn) {
mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
mg_printf(conn, "<html><body>"); mg_printf(conn, "<html><body>");
mg_printf(conn, "<h2>This is the AB handler!!!</h2>"); mg_printf(conn, "<h2>This is the AB handler!!!</h2>");
mg_printf(conn, "</body></html>\n"); mg_printf(conn, "</body></html>\n");
return true; return true;
} }
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
const char * options[] = { "document_root", DOCUMENT_ROOT, const char * options[] = { "document_root", DOCUMENT_ROOT,
"listening_ports", PORT, 0 }; "listening_ports", PORT, 0 };
CivetServer server(options); CivetServer server(options);
server.addHandler(EXAMPLE_URI, new ExampleHandler()); server.addHandler(EXAMPLE_URI, new ExampleHandler());
server.addHandler(EXIT_URI, new ExitHandler()); server.addHandler(EXIT_URI, new ExitHandler());
server.addHandler("/a", new AHandler()); server.addHandler("/a", new AHandler());
server.addHandler("/a/b", new ABHandler()); // going out of order with this to see if it will work. server.addHandler("/a/b", new ABHandler()); // going out of order with this to see if it will work.
printf("Browse files at http://localhost:%s/\n", PORT); printf("Browse files at http://localhost:%s/\n", PORT);
printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI); printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI);
printf("Exit at http://localhost:%s%s\n", PORT, EXIT_URI); printf("Exit at http://localhost:%s%s\n", PORT, EXIT_URI);
while (!exitNow) { #define TEST1 "a=1 1&b=2%202&a=3+3"
std::string rtn;
std::string back;
bool ok;
ok = CivetServer::getParam(TEST1,strlen(TEST1),"a",rtn,0);
printf("TEST 1 %s,%d => %s ok=%d\n", "a", 0, rtn.c_str(), ok?1:0);
ok = CivetServer::getParam(TEST1,strlen(TEST1),"a",rtn,1);
printf("TEST 1 %s,%d => %s ok=%d\n", "a", 1, rtn.c_str(), ok?1:0);
ok = CivetServer::getParam(TEST1,strlen(TEST1),"a",rtn,2);
printf("TEST 1 %s,%d => %s ok=%d\n", "a", 2, rtn.c_str(), ok?1:0);
ok = CivetServer::getParam(TEST1,strlen(TEST1),"x",rtn,0);
printf("TEST 1 %s,%d => %s ok=%d\n", "x", 0, rtn.c_str(), ok?1:0);
ok = CivetServer::getParam(TEST1,strlen(TEST1),"b",rtn,0);
printf("TEST 1 %s,%d => %s ok=%d\n", "b", 0, rtn.c_str(), ok?1:0);
CivetServer::urlEncode(TEST1,strlen(TEST1),rtn);
CivetServer::urlDecode(rtn,back);
printf("[%s]\n[%s]\n[%s]\n", TEST1, rtn.c_str(), back.c_str());
char b1[256], b2[256];
mg_url_encode(TEST1, b1, 256);
mg_url_decode(b1, 256, b2,256,1);
printf("[%s]\n[%s]\n[%s]\n", TEST1, b1, b2);
while (!exitNow) {
#ifdef _WIN32 #ifdef _WIN32
Sleep(1000); Sleep(1000);
#else #else
sleep(1); sleep(1);
#endif #endif
} }
printf("Bye!\n"); printf("Bye!\n");
return 0; return 0;
} }

View File

@ -1,474 +1,474 @@
// Copyright (c) 2004-2012 Sergey Lyubka // Copyright (c) 2004-2012 Sergey Lyubka
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights // in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is // copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions: // furnished to do so, subject to the following conditions:
// //
// The above copyright notice and this permission notice shall be included in // The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software. // all copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#ifndef CIVETWEB_HEADER_INCLUDED #ifndef CIVETWEB_HEADER_INCLUDED
#define CIVETWEB_HEADER_INCLUDED #define CIVETWEB_HEADER_INCLUDED
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
struct mg_context; // Handle for the HTTP service itself struct mg_context; // Handle for the HTTP service itself
struct mg_connection; // Handle for the individual connection struct mg_connection; // Handle for the individual connection
// This structure contains information about the HTTP request. // This structure contains information about the HTTP request.
struct mg_request_info { struct mg_request_info {
const char *request_method; // "GET", "POST", etc const char *request_method; // "GET", "POST", etc
const char *uri; // URL-decoded URI const char *uri; // URL-decoded URI
const char *http_version; // E.g. "1.0", "1.1" const char *http_version; // E.g. "1.0", "1.1"
const char *query_string; // URL part after '?', not including '?', or NULL const char *query_string; // URL part after '?', not including '?', or NULL
const char *remote_user; // Authenticated user, or NULL if no auth used const char *remote_user; // Authenticated user, or NULL if no auth used
long remote_ip; // Client's IP address long remote_ip; // Client's IP address
int remote_port; // Client's port int remote_port; // Client's port
int is_ssl; // 1 if SSL-ed, 0 if not int is_ssl; // 1 if SSL-ed, 0 if not
void *user_data; // User data pointer passed to mg_start() void *user_data; // User data pointer passed to mg_start()
void *conn_data; // Connection-specific user data void *conn_data; // Connection-specific user data
int num_headers; // Number of HTTP headers int num_headers; // Number of HTTP headers
struct mg_header { struct mg_header {
const char *name; // HTTP header name const char *name; // HTTP header name
const char *value; // HTTP header value const char *value; // HTTP header value
} http_headers[64]; // Maximum 64 headers } http_headers[64]; // Maximum 64 headers
}; };
// This structure needs to be passed to mg_start(), to let civetweb know // This structure needs to be passed to mg_start(), to let civetweb know
// which callbacks to invoke. For detailed description, see // which callbacks to invoke. For detailed description, see
// https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md // https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md
struct mg_callbacks { struct mg_callbacks {
// Called when civetweb has received new HTTP request. // Called when civetweb has received new HTTP request.
// If callback returns non-zero, // If callback returns non-zero,
// callback must process the request by sending valid HTTP headers and body, // callback must process the request by sending valid HTTP headers and body,
// and civetweb will not do any further processing. // and civetweb will not do any further processing.
// If callback returns 0, civetweb processes the request itself. In this case, // If callback returns 0, civetweb processes the request itself. In this case,
// callback must not send any data to the client. // callback must not send any data to the client.
int (*begin_request)(struct mg_connection *); int (*begin_request)(struct mg_connection *);
// Called when civetweb has finished processing request. // Called when civetweb has finished processing request.
void (*end_request)(const struct mg_connection *, int reply_status_code); void (*end_request)(const struct mg_connection *, int reply_status_code);
// Called when civetweb is about to log a message. If callback returns // Called when civetweb is about to log a message. If callback returns
// non-zero, civetweb does not log anything. // non-zero, civetweb does not log anything.
int (*log_message)(const struct mg_connection *, const char *message); int (*log_message)(const struct mg_connection *, const char *message);
// Called when civetweb initializes SSL library. // Called when civetweb initializes SSL library.
int (*init_ssl)(void *ssl_context, void *user_data); int (*init_ssl)(void *ssl_context, void *user_data);
// Called when websocket request is received, before websocket handshake. // Called when websocket request is received, before websocket handshake.
// If callback returns 0, civetweb proceeds with handshake, otherwise // If callback returns 0, civetweb proceeds with handshake, otherwise
// cinnection is closed immediately. // cinnection is closed immediately.
int (*websocket_connect)(const struct mg_connection *); int (*websocket_connect)(const struct mg_connection *);
// Called when websocket handshake is successfully completed, and // Called when websocket handshake is successfully completed, and
// connection is ready for data exchange. // connection is ready for data exchange.
void (*websocket_ready)(struct mg_connection *); void (*websocket_ready)(struct mg_connection *);
// Called when data frame has been received from the client. // Called when data frame has been received from the client.
// Parameters: // Parameters:
// bits: first byte of the websocket frame, see websocket RFC at // bits: first byte of the websocket frame, see websocket RFC at
// http://tools.ietf.org/html/rfc6455, section 5.2 // http://tools.ietf.org/html/rfc6455, section 5.2
// data, data_len: payload, with mask (if any) already applied. // data, data_len: payload, with mask (if any) already applied.
// Return value: // Return value:
// non-0: keep this websocket connection opened. // non-0: keep this websocket connection opened.
// 0: close this websocket connection. // 0: close this websocket connection.
int (*websocket_data)(struct mg_connection *, int bits, int (*websocket_data)(struct mg_connection *, int bits,
char *data, size_t data_len); char *data, size_t data_len);
// Called when civetweb is closing a connection. The per-context mutex is locked when this // Called when civetweb is closing a connection. The per-context mutex is locked when this
// is invoked. This is primarily useful for noting when a websocket is closing and removing it // is invoked. This is primarily useful for noting when a websocket is closing and removing it
// from any application-maintained list of clients. // from any application-maintained list of clients.
void (*connection_close)(struct mg_connection *); void (*connection_close)(struct mg_connection *);
// Called when civetweb tries to open a file. Used to intercept file open // Called when civetweb tries to open a file. Used to intercept file open
// calls, and serve file data from memory instead. // calls, and serve file data from memory instead.
// Parameters: // Parameters:
// path: Full path to the file to open. // path: Full path to the file to open.
// data_len: Placeholder for the file size, if file is served from memory. // data_len: Placeholder for the file size, if file is served from memory.
// Return value: // Return value:
// NULL: do not serve file from memory, proceed with normal file open. // NULL: do not serve file from memory, proceed with normal file open.
// non-NULL: pointer to the file contents in memory. data_len must be // non-NULL: pointer to the file contents in memory. data_len must be
// initilized with the size of the memory block. // initilized with the size of the memory block.
const char * (*open_file)(const struct mg_connection *, const char * (*open_file)(const struct mg_connection *,
const char *path, size_t *data_len); const char *path, size_t *data_len);
// Called when civetweb is about to serve Lua server page (.lp file), if // Called when civetweb is about to serve Lua server page (.lp file), if
// Lua support is enabled. // Lua support is enabled.
// Parameters: // Parameters:
// lua_context: "lua_State *" pointer. // lua_context: "lua_State *" pointer.
void (*init_lua)(struct mg_connection *, void *lua_context); void (*init_lua)(struct mg_connection *, void *lua_context);
// Called when civetweb has uploaded a file to a temporary directory as a // Called when civetweb has uploaded a file to a temporary directory as a
// result of mg_upload() call. // result of mg_upload() call.
// Parameters: // Parameters:
// file_file: full path name to the uploaded file. // file_file: full path name to the uploaded file.
void (*upload)(struct mg_connection *, const char *file_name); void (*upload)(struct mg_connection *, const char *file_name);
// Called when civetweb is about to send HTTP error to the client. // Called when civetweb is about to send HTTP error to the client.
// Implementing this callback allows to create custom error pages. // Implementing this callback allows to create custom error pages.
// Parameters: // Parameters:
// status: HTTP error status code. // status: HTTP error status code.
int (*http_error)(struct mg_connection *, int status); int (*http_error)(struct mg_connection *, int status);
}; };
// Start web server. // Start web server.
// //
// Parameters: // Parameters:
// callbacks: mg_callbacks structure with user-defined callbacks. // callbacks: mg_callbacks structure with user-defined callbacks.
// options: NULL terminated list of option_name, option_value pairs that // options: NULL terminated list of option_name, option_value pairs that
// specify Civetweb configuration parameters. // specify Civetweb configuration parameters.
// //
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom // Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
// processing is required for these, signal handlers must be set up // processing is required for these, signal handlers must be set up
// after calling mg_start(). // after calling mg_start().
// //
// //
// Example: // Example:
// const char *options[] = { // const char *options[] = {
// "document_root", "/var/www", // "document_root", "/var/www",
// "listening_ports", "80,443s", // "listening_ports", "80,443s",
// NULL // NULL
// }; // };
// struct mg_context *ctx = mg_start(&my_func, NULL, options); // struct mg_context *ctx = mg_start(&my_func, NULL, options);
// //
// Refer to https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md // Refer to https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md
// for the list of valid option and their possible values. // for the list of valid option and their possible values.
// //
// Return: // Return:
// web server context, or NULL on error. // web server context, or NULL on error.
struct mg_context *mg_start(const struct mg_callbacks *callbacks, struct mg_context *mg_start(const struct mg_callbacks *callbacks,
void *user_data, void *user_data,
const char **configuration_options); const char **configuration_options);
// Stop the web server. // Stop the web server.
// //
// Must be called last, when an application wants to stop the web server and // Must be called last, when an application wants to stop the web server and
// release all associated resources. This function blocks until all Civetweb // release all associated resources. This function blocks until all Civetweb
// threads are stopped. Context pointer becomes invalid. // threads are stopped. Context pointer becomes invalid.
void mg_stop(struct mg_context *); void mg_stop(struct mg_context *);
// mg_request_handler // mg_request_handler
// //
// Called when a new request comes in. This callback is URI based // Called when a new request comes in. This callback is URI based
// and configured with mg_set_request_handler(). // and configured with mg_set_request_handler().
// //
// Parameters: // Parameters:
// conn: current connection information. // conn: current connection information.
// cbdata: the callback data configured with mg_set_request_handler(). // cbdata: the callback data configured with mg_set_request_handler().
// Returns: // Returns:
// 0: the handler could not handle the request, so fall through. // 0: the handler could not handle the request, so fall through.
// 1: the handler processed the request. // 1: the handler processed the request.
typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata); typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
// mg_set_request_handler // mg_set_request_handler
// //
// Sets or removes a URI mapping for a request handler. // Sets or removes a URI mapping for a request handler.
// //
// URI's are ordered and prefixed URI's are supported. For example, // URI's are ordered and prefixed URI's are supported. For example,
// consider two URIs: /a/b and /a // consider two URIs: /a/b and /a
// /a matches /a // /a matches /a
// /a/b matches /a/b // /a/b matches /a/b
// /a/c matches /a // /a/c matches /a
// //
// Parameters: // Parameters:
// ctx: server context // ctx: server context
// uri: the URI to configure // uri: the URI to configure
// handler: the callback handler to use when the URI is requested. // handler: the callback handler to use when the URI is requested.
// If NULL, the URI will be removed. // If NULL, the URI will be removed.
// cbdata: the callback data to give to the handler when it s requested. // cbdata: the callback data to give to the handler when it s requested.
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata); void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
// Get the value of particular configuration parameter. // Get the value of particular configuration parameter.
// The value returned is read-only. Civetweb does not allow changing // The value returned is read-only. Civetweb does not allow changing
// configuration at run time. // configuration at run time.
// If given parameter name is not valid, NULL is returned. For valid // If given parameter name is not valid, NULL is returned. For valid
// names, return value is guaranteed to be non-NULL. If parameter is not // names, return value is guaranteed to be non-NULL. If parameter is not
// set, zero-length string is returned. // set, zero-length string is returned.
const char *mg_get_option(const struct mg_context *ctx, const char *name); const char *mg_get_option(const struct mg_context *ctx, const char *name);
// Return array of strings that represent valid configuration options. // Return array of strings that represent valid configuration options.
// For each option, option name and default value is returned, i.e. the // For each option, option name and default value is returned, i.e. the
// number of entries in the array equals to number_of_options x 2. // number of entries in the array equals to number_of_options x 2.
// Array is NULL terminated. // Array is NULL terminated.
const char **mg_get_valid_option_names(void); const char **mg_get_valid_option_names(void);
// Add, edit or delete the entry in the passwords file. // Add, edit or delete the entry in the passwords file.
// //
// This function allows an application to manipulate .htpasswd files on the // This function allows an application to manipulate .htpasswd files on the
// fly by adding, deleting and changing user records. This is one of the // fly by adding, deleting and changing user records. This is one of the
// several ways of implementing authentication on the server side. For another, // several ways of implementing authentication on the server side. For another,
// cookie-based way please refer to the examples/chat in the source tree. // cookie-based way please refer to the examples/chat in the source tree.
// //
// If password is not NULL, entry is added (or modified if already exists). // If password is not NULL, entry is added (or modified if already exists).
// If password is NULL, entry is deleted. // If password is NULL, entry is deleted.
// //
// Return: // Return:
// 1 on success, 0 on error. // 1 on success, 0 on error.
int mg_modify_passwords_file(const char *passwords_file_name, int mg_modify_passwords_file(const char *passwords_file_name,
const char *domain, const char *domain,
const char *user, const char *user,
const char *password); const char *password);
// Return information associated with the request. // Return information associated with the request.
struct mg_request_info *mg_get_request_info(struct mg_connection *); struct mg_request_info *mg_get_request_info(struct mg_connection *);
// Send data to the client. // Send data to the client.
// Return: // Return:
// 0 when the connection has been closed // 0 when the connection has been closed
// -1 on error // -1 on error
// >0 number of bytes written on success // >0 number of bytes written on success
int mg_write(struct mg_connection *, const void *buf, size_t len); int mg_write(struct mg_connection *, const void *buf, size_t len);
// Send data to a websocket client wrapped in a websocket frame. Uses mg_lock to ensure // Send data to a websocket client wrapped in a websocket frame. Uses mg_lock to ensure
// that the transmission is not interrupted, i.e., when the application is proactively // that the transmission is not interrupted, i.e., when the application is proactively
// communicating and responding to a request simultaneously. // communicating and responding to a request simultaneously.
// //
// Send data to a websocket client wrapped in a websocket frame. // Send data to a websocket client wrapped in a websocket frame.
// This function is available when civetweb is compiled with -DUSE_WEBSOCKET // This function is available when civetweb is compiled with -DUSE_WEBSOCKET
// //
// Return: // Return:
// 0 when the connection has been closed // 0 when the connection has been closed
// -1 on error // -1 on error
// >0 number of bytes written on success // >0 number of bytes written on success
int mg_websocket_write(struct mg_connection* conn, int opcode, int mg_websocket_write(struct mg_connection* conn, int opcode,
const char *data, size_t data_len); const char *data, size_t data_len);
// Blocks until unique access is obtained to this connection. Intended for use with websockets only. // Blocks until unique access is obtained to this connection. Intended for use with websockets only.
// Invoke this before mg_write or mg_printf when communicating with a websocket if your code has // Invoke this before mg_write or mg_printf when communicating with a websocket if your code has
// server-initiated communication as well as communication in direct response to a message. // server-initiated communication as well as communication in direct response to a message.
void mg_lock(struct mg_connection* conn); void mg_lock(struct mg_connection* conn);
void mg_unlock(struct mg_connection* conn); void mg_unlock(struct mg_connection* conn);
// Opcodes, from http://tools.ietf.org/html/rfc6455 // Opcodes, from http://tools.ietf.org/html/rfc6455
enum { enum {
WEBSOCKET_OPCODE_CONTINUATION = 0x0, WEBSOCKET_OPCODE_CONTINUATION = 0x0,
WEBSOCKET_OPCODE_TEXT = 0x1, WEBSOCKET_OPCODE_TEXT = 0x1,
WEBSOCKET_OPCODE_BINARY = 0x2, WEBSOCKET_OPCODE_BINARY = 0x2,
WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8, WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
WEBSOCKET_OPCODE_PING = 0x9, WEBSOCKET_OPCODE_PING = 0x9,
WEBSOCKET_OPCODE_PONG = 0xa WEBSOCKET_OPCODE_PONG = 0xa
}; };
// Macros for enabling compiler-specific checks for printf-like arguments. // Macros for enabling compiler-specific checks for printf-like arguments.
#undef PRINTF_FORMAT_STRING #undef PRINTF_FORMAT_STRING
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
#include <sal.h> #include <sal.h>
#if defined(_MSC_VER) && _MSC_VER > 1400 #if defined(_MSC_VER) && _MSC_VER > 1400
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s #define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
#else #else
#define PRINTF_FORMAT_STRING(s) __format_string s #define PRINTF_FORMAT_STRING(s) __format_string s
#endif #endif
#else #else
#define PRINTF_FORMAT_STRING(s) s #define PRINTF_FORMAT_STRING(s) s
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y))) #define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
#else #else
#define PRINTF_ARGS(x, y) #define PRINTF_ARGS(x, y)
#endif #endif
// Send data to the client using printf() semantics. // Send data to the client using printf() semantics.
// //
// Works exactly like mg_write(), but allows to do message formatting. // Works exactly like mg_write(), but allows to do message formatting.
int mg_printf(struct mg_connection *, int mg_printf(struct mg_connection *,
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
// Send contents of the entire file together with HTTP headers. // Send contents of the entire file together with HTTP headers.
void mg_send_file(struct mg_connection *conn, const char *path); void mg_send_file(struct mg_connection *conn, const char *path);
// Read data from the remote end, return number of bytes read. // Read data from the remote end, return number of bytes read.
// Return: // Return:
// 0 connection has been closed by peer. No more data could be read. // 0 connection has been closed by peer. No more data could be read.
// < 0 read error. No more data could be read from the connection. // < 0 read error. No more data could be read from the connection.
// > 0 number of bytes read into the buffer. // > 0 number of bytes read into the buffer.
int mg_read(struct mg_connection *, void *buf, size_t len); int mg_read(struct mg_connection *, void *buf, size_t len);
// Get the value of particular HTTP header. // Get the value of particular HTTP header.
// //
// This is a helper function. It traverses request_info->http_headers array, // This is a helper function. It traverses request_info->http_headers array,
// and if the header is present in the array, returns its value. If it is // and if the header is present in the array, returns its value. If it is
// not present, NULL is returned. // not present, NULL is returned.
const char *mg_get_header(const struct mg_connection *, const char *name); const char *mg_get_header(const struct mg_connection *, const char *name);
// Get a value of particular form variable. // Get a value of particular form variable.
// //
// Parameters: // Parameters:
// data: pointer to form-uri-encoded buffer. This could be either POST data, // data: pointer to form-uri-encoded buffer. This could be either POST data,
// or request_info.query_string. // or request_info.query_string.
// data_len: length of the encoded data. // data_len: length of the encoded data.
// var_name: variable name to decode from the buffer // var_name: variable name to decode from the buffer
// dst: destination buffer for the decoded variable // dst: destination buffer for the decoded variable
// dst_len: length of the destination buffer // dst_len: length of the destination buffer
// //
// Return: // Return:
// On success, length of the decoded variable. // On success, length of the decoded variable.
// On error: // On error:
// -1 (variable not found). // -1 (variable not found).
// -2 (destination buffer is NULL, zero length or too small to hold the // -2 (destination buffer is NULL, zero length or too small to hold the
// decoded variable). // decoded variable).
// //
// Destination buffer is guaranteed to be '\0' - terminated if it is not // Destination buffer is guaranteed to be '\0' - terminated if it is not
// NULL or zero length. // NULL or zero length.
int mg_get_var(const char *data, size_t data_len, int mg_get_var(const char *data, size_t data_len,
const char *var_name, char *dst, size_t dst_len); const char *var_name, char *dst, size_t dst_len);
// Get a value of particular form variable. // Get a value of particular form variable.
// //
// Parameters: // Parameters:
// data: pointer to form-uri-encoded buffer. This could be either POST data, // data: pointer to form-uri-encoded buffer. This could be either POST data,
// or request_info.query_string. // or request_info.query_string.
// data_len: length of the encoded data. // data_len: length of the encoded data.
// var_name: variable name to decode from the buffer // var_name: variable name to decode from the buffer
// dst: destination buffer for the decoded variable // dst: destination buffer for the decoded variable
// dst_len: length of the destination buffer // dst_len: length of the destination buffer
// occurrence: which occurrence of the variable, 0 is the first, 1 the second... // occurrence: which occurrence of the variable, 0 is the first, 1 the second...
// this makes it possible to parse a query like // this makes it possible to parse a query like
// b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1 // b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
// //
// Return: // Return:
// On success, length of the decoded variable. // On success, length of the decoded variable.
// On error: // On error:
// -1 (variable not found). // -1 (variable not found).
// -2 (destination buffer is NULL, zero length or too small to hold the // -2 (destination buffer is NULL, zero length or too small to hold the
// decoded variable). // decoded variable).
// //
// Destination buffer is guaranteed to be '\0' - terminated if it is not // Destination buffer is guaranteed to be '\0' - terminated if it is not
// NULL or zero length. // NULL or zero length.
int mg_get_var2(const char *data, size_t data_len, int mg_get_var2(const char *data, size_t data_len,
const char *var_name, char *dst, size_t dst_len, size_t occurrence); const char *var_name, char *dst, size_t dst_len, size_t occurrence);
// Fetch value of certain cookie variable into the destination buffer. // Fetch value of certain cookie variable into the destination buffer.
// //
// Destination buffer is guaranteed to be '\0' - terminated. In case of // Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same // failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
// parameter. This function returns only first occurrence. // parameter. This function returns only first occurrence.
// //
// Return: // Return:
// On success, value length. // On success, value length.
// On error: // On error:
// -1 (either "Cookie:" header is not present at all or the requested // -1 (either "Cookie:" header is not present at all or the requested
// parameter is not found). // parameter is not found).
// -2 (destination buffer is NULL, zero length or too small to hold the // -2 (destination buffer is NULL, zero length or too small to hold the
// value). // value).
int mg_get_cookie(const char *cookie, const char *var_name, int mg_get_cookie(const char *cookie, const char *var_name,
char *buf, size_t buf_len); char *buf, size_t buf_len);
// Download data from the remote web server. // Download data from the remote web server.
// host: host name to connect to, e.g. "foo.com", or "10.12.40.1". // host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
// port: port number, e.g. 80. // port: port number, e.g. 80.
// use_ssl: wether to use SSL connection. // use_ssl: wether to use SSL connection.
// error_buffer, error_buffer_size: error message placeholder. // error_buffer, error_buffer_size: error message placeholder.
// request_fmt,...: HTTP request. // request_fmt,...: HTTP request.
// Return: // Return:
// On success, valid pointer to the new connection, suitable for mg_read(). // On success, valid pointer to the new connection, suitable for mg_read().
// On error, NULL. error_buffer contains error message. // On error, NULL. error_buffer contains error message.
// Example: // Example:
// char ebuf[100]; // char ebuf[100];
// struct mg_connection *conn; // struct mg_connection *conn;
// conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf), // conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
// "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n"); // "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
struct mg_connection *mg_download(const char *host, int port, int use_ssl, struct mg_connection *mg_download(const char *host, int port, int use_ssl,
char *error_buffer, size_t error_buffer_size, char *error_buffer, size_t error_buffer_size,
PRINTF_FORMAT_STRING(const char *request_fmt), PRINTF_FORMAT_STRING(const char *request_fmt),
...) PRINTF_ARGS(6, 7); ...) PRINTF_ARGS(6, 7);
// Close the connection opened by mg_download(). // Close the connection opened by mg_download().
void mg_close_connection(struct mg_connection *conn); void mg_close_connection(struct mg_connection *conn);
// File upload functionality. Each uploaded file gets saved into a temporary // File upload functionality. Each uploaded file gets saved into a temporary
// file and MG_UPLOAD event is sent. // file and MG_UPLOAD event is sent.
// Return number of uploaded files. // Return number of uploaded files.
int mg_upload(struct mg_connection *conn, const char *destination_dir); int mg_upload(struct mg_connection *conn, const char *destination_dir);
// Convenience function -- create detached thread. // Convenience function -- create detached thread.
// Return: 0 on success, non-0 on error. // Return: 0 on success, non-0 on error.
typedef void * (*mg_thread_func_t)(void *); typedef void * (*mg_thread_func_t)(void *);
int mg_start_thread(mg_thread_func_t f, void *p); int mg_start_thread(mg_thread_func_t f, void *p);
// Return builtin mime type for the given file name. // Return builtin mime type for the given file name.
// For unrecognized extensions, "text/plain" is returned. // For unrecognized extensions, "text/plain" is returned.
const char *mg_get_builtin_mime_type(const char *file_name); const char *mg_get_builtin_mime_type(const char *file_name);
// Return Civetweb version. // Return Civetweb version.
const char *mg_version(void); const char *mg_version(void);
// URL-decode input buffer into destination buffer. // URL-decode input buffer into destination buffer.
// 0-terminate the destination buffer. // 0-terminate the destination buffer.
// form-url-encoded data differs from URI encoding in a way that it // form-url-encoded data differs from URI encoding in a way that it
// uses '+' as character for space, see RFC 1866 section 8.2.1 // uses '+' as character for space, see RFC 1866 section 8.2.1
// http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt // http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
// Return: length of the decoded data, or -1 if dst buffer is too small. // Return: length of the decoded data, or -1 if dst buffer is too small.
int mg_url_decode(const char *src, int src_len, char *dst, int mg_url_decode(const char *src, int src_len, char *dst,
int dst_len, int is_form_url_encoded); int dst_len, int is_form_url_encoded);
// URL-encode input buffer into destination buffer. // URL-encode input buffer into destination buffer.
// returns the length of the resulting buffer or -1 // returns the length of the resulting buffer or -1
// is the buffer is too small. // is the buffer is too small.
int mg_url_encode(const char *src, char *dst, size_t dst_len); int mg_url_encode(const char *src, char *dst, size_t dst_len);
// MD5 hash given strings. // MD5 hash given strings.
// Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of // Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
// ASCIIz strings. When function returns, buf will contain human-readable // ASCIIz strings. When function returns, buf will contain human-readable
// MD5 hash. Example: // MD5 hash. Example:
// char buf[33]; // char buf[33];
// mg_md5(buf, "aa", "bb", NULL); // mg_md5(buf, "aa", "bb", NULL);
char *mg_md5(char buf[33], ...); char *mg_md5(char buf[33], ...);
// Print error message to the opened error log stream. // Print error message to the opened error log stream.
// This utilizes the provided logging configuration. // This utilizes the provided logging configuration.
// conn: connection // conn: connection
// fmt: format string without the line return // fmt: format string without the line return
// ...: variable argument list // ...: variable argument list
// Example: // Example:
// mg_cry(conn,"i like %s", "logging"); // mg_cry(conn,"i like %s", "logging");
void mg_cry(struct mg_connection *conn, void mg_cry(struct mg_connection *conn,
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
// utility method to compare two buffers, case incensitive. // utility method to compare two buffers, case incensitive.
int mg_strncasecmp(const char *s1, const char *s2, size_t len); int mg_strncasecmp(const char *s1, const char *s2, size_t len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif // __cplusplus #endif // __cplusplus
#endif // CIVETWEB_HEADER_INCLUDED #endif // CIVETWEB_HEADER_INCLUDED

View File

@ -190,7 +190,7 @@ CivetServer::urlEncode(const char *src, size_t src_len, std::string &dst, bool a
if (!append) if (!append)
dst.clear(); dst.clear();
for (; src_len > 0; src_len--) { for (; src_len > 0; src++, src_len--) {
if (isalnum(*(const unsigned char *) src) || if (isalnum(*(const unsigned char *) src) ||
strchr(dont_escape, * (const unsigned char *) src) != NULL) { strchr(dont_escape, * (const unsigned char *) src) != NULL) {
dst.push_back(*src); dst.push_back(*src);

File diff suppressed because it is too large Load Diff

1982
src/main.c

File diff suppressed because it is too large Load Diff