MIDAS
mongoose v4 web server library

Classes

struct  mg_request_info
 
struct  mg_request_info::mg_header
 
struct  mg_event
 

Macros

#define MG_REQUEST_BEGIN   1
 
#define MG_REQUEST_END   2
 
#define MG_HTTP_ERROR   3
 
#define MG_EVENT_LOG   4
 
#define MG_THREAD_BEGIN   5
 
#define MG_THREAD_END   6
 
#define PRINTF_FORMAT_STRING(s)   s
 
#define PRINTF_ARGS(x, y)
 

Typedefs

typedef int(* mg_event_handler_t) (struct mg_event *event)
 
typedef void *(* mg_thread_func_t) (void *)
 

Enumerations

enum  {
  WEBSOCKET_OPCODE_CONTINUATION = 0x0 , WEBSOCKET_OPCODE_TEXT = 0x1 , WEBSOCKET_OPCODE_BINARY = 0x2 , WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8 ,
  WEBSOCKET_OPCODE_PING = 0x9 , WEBSOCKET_OPCODE_PONG = 0xa
}
 

Functions

struct mg_contextmg_start (const char **configuration_options, mg_event_handler_t func, void *user_data)
 
void mg_stop (struct mg_context *)
 
void mg_websocket_handshake (struct mg_connection *)
 
int mg_websocket_read (struct mg_connection *, int *bits, char **data)
 
int mg_websocket_write (struct mg_connection *conn, int opcode, const char *data, size_t data_len)
 
const char * mg_get_option (const struct mg_context *ctx, const char *name)
 
const char ** mg_get_valid_option_names (void)
 
int mg_modify_passwords_file (const char *passwords_file_name, const char *domain, const char *user, const char *password)
 
int mg_write (struct mg_connection *, const void *buf, int len)
 
int mg_printf (struct mg_connection *, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
 
int void mg_send_file (struct mg_connection *conn, const char *path)
 
int mg_read (struct mg_connection *, void *buf, int len)
 
const char * mg_get_header (const struct mg_connection *, const char *name)
 
int mg_get_var (const char *data, size_t data_len, const char *var_name, char *dst, size_t dst_len)
 
int mg_get_cookie (const char *cookie, const char *var_name, char *buf, size_t buf_len)
 
struct mg_connectionmg_download (const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, PRINTF_FORMAT_STRING(const char *request_fmt),...) PRINTF_ARGS(6
 
struct mg_connection void mg_close_connection (struct mg_connection *conn)
 
FILE * mg_upload (struct mg_connection *conn, const char *destination_dir, char *path, int path_len)
 
int mg_start_thread (mg_thread_func_t f, void *p)
 
const char * mg_get_builtin_mime_type (const char *file_name)
 
const char * mg_version (void)
 
int mg_url_decode (const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
 
char * mg_md5 (char buf[33],...)
 

Variables

const char * mg_request_info::request_method
 
const char * mg_request_info::uri
 
const char * mg_request_info::http_version
 
const char * mg_request_info::query_string
 
const char * mg_request_info::remote_user
 
long mg_request_info::remote_ip
 
int mg_request_info::remote_port
 
int mg_request_info::is_ssl
 
int mg_request_info::num_headers
 
const char * mg_request_info::mg_header::name
 
const char * mg_request_info::mg_header::value
 
struct mg_request_info::mg_header mg_request_info::http_headers [64]
 
int mg_event::type
 
void * mg_event::user_data
 
void * mg_event::conn_data
 
void * mg_event::event_param
 
struct mg_connectionmg_event::conn
 
struct mg_request_infomg_event::request_info
 

Detailed Description


Macro Definition Documentation

◆ MG_EVENT_LOG

#define MG_EVENT_LOG   4

Definition at line 58 of file mongoose4.h.

◆ MG_HTTP_ERROR

#define MG_HTTP_ERROR   3

Definition at line 57 of file mongoose4.h.

◆ MG_REQUEST_BEGIN

#define MG_REQUEST_BEGIN   1

Definition at line 55 of file mongoose4.h.

◆ MG_REQUEST_END

#define MG_REQUEST_END   2

Definition at line 56 of file mongoose4.h.

◆ MG_THREAD_BEGIN

#define MG_THREAD_BEGIN   5

Definition at line 59 of file mongoose4.h.

◆ MG_THREAD_END

#define MG_THREAD_END   6

Definition at line 60 of file mongoose4.h.

◆ PRINTF_ARGS

#define PRINTF_ARGS (   x,
 
)

Definition at line 114 of file mongoose4.h.

◆ PRINTF_FORMAT_STRING

#define PRINTF_FORMAT_STRING (   s)    s

Definition at line 108 of file mongoose4.h.

Typedef Documentation

◆ mg_event_handler_t

typedef int(* mg_event_handler_t) (struct mg_event *event)

Definition at line 70 of file mongoose4.h.

◆ mg_thread_func_t

typedef void*(* mg_thread_func_t) (void *)

Definition at line 218 of file mongoose4.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
WEBSOCKET_OPCODE_CONTINUATION 
WEBSOCKET_OPCODE_TEXT 
WEBSOCKET_OPCODE_BINARY 
WEBSOCKET_OPCODE_CONNECTION_CLOSE 
WEBSOCKET_OPCODE_PING 
WEBSOCKET_OPCODE_PONG 

Definition at line 81 of file mongoose4.h.

81  {
88 };
@ WEBSOCKET_OPCODE_CONNECTION_CLOSE
Definition: mongoose4.h:85
@ WEBSOCKET_OPCODE_PONG
Definition: mongoose4.h:87
@ WEBSOCKET_OPCODE_TEXT
Definition: mongoose4.h:83
@ WEBSOCKET_OPCODE_CONTINUATION
Definition: mongoose4.h:82
@ WEBSOCKET_OPCODE_BINARY
Definition: mongoose4.h:84
@ WEBSOCKET_OPCODE_PING
Definition: mongoose4.h:86

Function Documentation

◆ mg_close_connection()

struct mg_connection void mg_close_connection ( struct mg_connection conn)

Definition at line 5097 of file mongoose4.cxx.

5097  {
5098 #ifndef NO_SSL
5099  if (conn->client_ssl_ctx != NULL) {
5100  SSL_CTX_free((SSL_CTX *) conn->client_ssl_ctx);
5101  }
5102 #endif
5103  close_connection(conn);
5104  free(conn);
5105 }
void * SSL_CTX
Definition: mongoose6.h:1175
static void close_connection(struct mg_connection *conn)
Definition: mongoose4.cxx:5080
SSL_CTX * client_ssl_ctx
Definition: mongoose4.cxx:483
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mg_download()

struct mg_connection* mg_download ( const char *  host,
int  port,
int  use_ssl,
char *  error_buffer,
size_t  error_buffer_size,
PRINTF_FORMAT_STRING(const char *request_fmt)  ,
  ... 
)

◆ mg_get_builtin_mime_type()

const char* mg_get_builtin_mime_type ( const char *  file_name)

Definition at line 2895 of file mongoose4.cxx.

2895  {
2896  const char *ext;
2897  size_t i, path_len;
2898 
2899  path_len = strlen(path);
2900 
2901  for (i = 0; builtin_mime_types[i].extension != NULL; i++) {
2902  ext = path + (path_len - builtin_mime_types[i].ext_len);
2903  if (path_len > builtin_mime_types[i].ext_len &&
2905  return builtin_mime_types[i].mime_type;
2906  }
2907  }
2908 
2909  return "text/plain";
2910 }
INT i
Definition: mdump.cxx:35
static int mg_strcasecmp(const char *s1, const char *s2)
Definition: mongoose4.cxx:555
size_t ext_len
Definition: mongoose4.cxx:2842
const char * extension
Definition: mongoose4.cxx:2841
static const struct @22 builtin_mime_types[]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mg_get_cookie()

int mg_get_cookie ( const char *  cookie,
const char *  var_name,
char *  buf,
size_t  buf_len 
)

Definition at line 2678 of file mongoose4.cxx.

2679  {
2680  const char *s, *p, *end;
2681  int name_len, len = -1;
2682 
2683  if (dst == NULL || dst_size == 0) {
2684  len = -2;
2685  } else if (var_name == NULL || (s = cookie_header) == NULL) {
2686  len = -1;
2687  dst[0] = '\0';
2688  } else {
2689  name_len = (int) strlen(var_name);
2690  end = s + strlen(s);
2691  dst[0] = '\0';
2692 
2693  for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
2694  if (s[name_len] == '=') {
2695  s += name_len + 1;
2696  if ((p = strchr(s, ' ')) == NULL)
2697  p = end;
2698  if (p[-1] == ';')
2699  p--;
2700  if (*s == '"' && p[-1] == '"' && p > s + 1) {
2701  s++;
2702  p--;
2703  }
2704  if ((size_t) (p - s) < dst_size) {
2705  len = p - s;
2706  mg_strlcpy(dst, s, (size_t) len + 1);
2707  } else {
2708  len = -3;
2709  }
2710  break;
2711  }
2712  }
2713  }
2714  return len;
2715 }
#define end
Definition: midas_macro.h:283
static void mg_strlcpy(register char *dst, register const char *src, size_t n)
Definition: mongoose4.cxx:533
static const char * mg_strcasestr(const char *big_str, const char *small_str)
Definition: mongoose4.cxx:579
char var_name[256]
Definition: odbhist.cxx:41
Here is the call graph for this function:

◆ mg_get_header()

const char* mg_get_header ( const struct mg_connection conn,
const char *  name 
)

Definition at line 693 of file mongoose4.cxx.

693  {
694  return get_header(&conn->request_info, name);
695 }
#define name(x)
Definition: midas_macro.h:24
static const char * get_header(const struct mg_request_info *ri, const char *name)
Definition: mongoose4.cxx:682
struct mg_request_info request_info
Definition: mongoose4.cxx:479
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mg_get_option()

const char* mg_get_option ( const struct mg_context ctx,
const char *  name 
)

Definition at line 870 of file mongoose4.cxx.

870  {
871  int i;
872  if ((i = get_option_index(name)) == -1) {
873  return NULL;
874  } else if (ctx->config[i] == NULL) {
875  return "";
876  } else {
877  return ctx->config[i];
878  }
879 }
static int get_option_index(const char *name)
Definition: mongoose4.cxx:859
char * config[NUM_OPTIONS]
Definition: mongoose4.cxx:460
Here is the call graph for this function:

◆ mg_get_valid_option_names()

const char** mg_get_valid_option_names ( void  )

Definition at line 855 of file mongoose4.cxx.

855  {
856  return config_options;
857 }
static const char * config_options[]
Definition: mongoose4.cxx:826

◆ mg_get_var()

int mg_get_var ( const char *  data,
size_t  data_len,
const char *  var_name,
char *  dst,
size_t  dst_len 
)

Definition at line 2631 of file mongoose4.cxx.

2632  {
2633  const char *p, *e, *s;
2634  size_t name_len;
2635  int len;
2636 
2637  if (dst == NULL || dst_len == 0) {
2638  len = -2;
2639  } else if (data == NULL || name == NULL || data_len == 0) {
2640  len = -1;
2641  dst[0] = '\0';
2642  } else {
2643  name_len = strlen(name);
2644  e = data + data_len;
2645  len = -1;
2646  dst[0] = '\0';
2647 
2648  // data is "var1=val1&var2=val2...". Find variable first
2649  for (p = data; p + name_len < e; p++) {
2650  if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
2651  !mg_strncasecmp(name, p, name_len)) {
2652 
2653  // Point p to variable value
2654  p += name_len + 1;
2655 
2656  // Point s to the end of the value
2657  s = (const char *) memchr(p, '&', (size_t)(e - p));
2658  if (s == NULL) {
2659  s = e;
2660  }
2661  assert(s >= p);
2662 
2663  // Decode variable into destination buffer
2664  len = mg_url_decode(p, (size_t)(s - p), dst, dst_len, 1);
2665 
2666  // Redirect error code from -1 to -2 (destination buffer too small).
2667  if (len == -1) {
2668  len = -2;
2669  }
2670  break;
2671  }
2672  }
2673  }
2674 
2675  return len;
2676 }
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
Definition: mongoose4.cxx:2606
void * data
Definition: mana.cxx:268
static int mg_strncasecmp(const char *s1, const char *s2, size_t len)
Definition: mongoose4.cxx:544
static double e(void)
Definition: tinyexpr.c:136
Here is the call graph for this function:

◆ mg_md5()

char* mg_md5 ( char  buf[33],
  ... 
)

Definition at line 1090 of file mongoose4.cxx.

1090  {
1091  unsigned char hash[16];
1092  const char *p;
1093  va_list ap;
1094  MD5_CTX ctx;
1095 
1096  MD5Init(&ctx);
1097 
1098  va_start(ap, buf);
1099  while ((p = va_arg(ap, const char *)) != NULL) {
1100  MD5Update(&ctx, (const unsigned char *) p, (unsigned) strlen(p));
1101  }
1102  va_end(ap);
1103 
1104  MD5Final(hash, &ctx);
1105  bin2str(buf, hash, sizeof(hash));
1106  return buf;
1107 }
static void MD5Final(unsigned char digest[16], MD5_CTX *ctx)
Definition: mongoose4.cxx:1044
static void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len)
Definition: mongoose4.cxx:1008
static void bin2str(char *to, const unsigned char *p, size_t len)
Definition: mongoose4.cxx:1079
static void MD5Init(MD5_CTX *ctx)
Definition: mongoose4.cxx:916
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mg_modify_passwords_file()

int mg_modify_passwords_file ( const char *  passwords_file_name,
const char *  domain,
const char *  user,
const char *  password 
)

Definition at line 1314 of file mongoose4.cxx.

1315  {
1316  int found;
1317  char line[512], u[512], d[512], ha1[33], tmp[PATH_MAX];
1318  FILE *fp, *fp2;
1319 
1320  found = 0;
1321  fp = fp2 = NULL;
1322 
1323  // Regard empty password as no password - remove user record.
1324  if (pass != NULL && pass[0] == '\0') {
1325  pass = NULL;
1326  }
1327 
1328  (void) snprintf(tmp, sizeof(tmp), "%s.tmp", fname);
1329 
1330  // Create the file if does not exist
1331  if ((fp = fopen(fname, "a+")) != NULL) {
1332  fclose(fp);
1333  }
1334 
1335  // Open the given file and temporary file
1336  if ((fp = fopen(fname, "r")) == NULL) {
1337  return 0;
1338  } else if ((fp2 = fopen(tmp, "w+")) == NULL) {
1339  fclose(fp);
1340  return 0;
1341  }
1342 
1343  // Copy the stuff to temporary file
1344  while (fgets(line, sizeof(line), fp) != NULL) {
1345  if (sscanf(line, "%[^:]:%[^:]:%*s", u, d) != 2) {
1346  continue;
1347  }
1348 
1349  if (!strcmp(u, user) && !strcmp(d, domain)) {
1350  found++;
1351  if (pass != NULL) {
1352  mg_md5(ha1, user, ":", domain, ":", pass, NULL);
1353  fprintf(fp2, "%s:%s:%s\n", user, domain, ha1);
1354  }
1355  } else {
1356  fprintf(fp2, "%s", line);
1357  }
1358  }
1359 
1360  // If new user, just add it
1361  if (!found && pass != NULL) {
1362  mg_md5(ha1, user, ":", domain, ":", pass, NULL);
1363  fprintf(fp2, "%s:%s:%s\n", user, domain, ha1);
1364  }
1365 
1366  // Close files
1367  fclose(fp);
1368  fclose(fp2);
1369 
1370  // Put the temp file in place of real file
1371  remove(fname);
1372  rename(tmp, fname);
1373 
1374  return 1;
1375 }
char * mg_md5(char buf[33],...)
Definition: mongoose4.cxx:1090
static std::string remove(const std::string s, char c)
Definition: mjsonrpc.cxx:252
static FILE * fp
Definition: mlxspeaker.cxx:24
#define PATH_MAX
Definition: mongoose4.cxx:306
double d
Definition: system.cxx:1317
Here is the call graph for this function:

◆ mg_printf()

int mg_printf ( struct mg_connection ,
PRINTF_FORMAT_STRING(const char *fmt)  ,
  ... 
)
Here is the caller graph for this function:

◆ mg_read()

int mg_read ( struct mg_connection conn,
void *  buf,
int  len 
)

Definition at line 2529 of file mongoose4.cxx.

2529  {
2530  int n, buffered_len, nread = 0;
2531  int64_t left;
2532 
2533  if (conn->content_len <= 0) {
2534  return 0;
2535  }
2536 
2537  // conn->buf body
2538  // |=================|==========|===============|
2539  // |<--request_len-->| |
2540  // |<-----------data_len------->| conn->buf + conn->buf_size
2541 
2542  // First, check for data buffered in conn->buf by read_request().
2543  if (len > 0 && (buffered_len = conn->data_len - conn->request_len) > 0) {
2544  char *body = conn->buf + conn->request_len;
2545  if (buffered_len > len) buffered_len = len;
2546  if (buffered_len > conn->content_len) buffered_len = (int)conn->content_len;
2547 
2548  memcpy(buf, body, (size_t) buffered_len);
2549  memmove(body, body + buffered_len,
2550  &conn->buf[conn->data_len] - &body[buffered_len]);
2551  len -= buffered_len;
2552  conn->data_len -= buffered_len;
2553  nread += buffered_len;
2554  }
2555 
2556  // Read data from the socket.
2557  if (len > 0 && (left = left_to_read(conn)) > 0) {
2558  if (left < len) {
2559  len = (int) left;
2560  }
2561  n = pull_all(NULL, conn, (char *) buf + nread, (int) len);
2562  nread = n >= 0 ? nread + n : n;
2563  }
2564 
2565  return nread;
2566 }
DWORD n[4]
Definition: mana.cxx:247
static int64_t left_to_read(const struct mg_connection *conn)
Definition: mongoose4.cxx:2315
static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
Definition: mongoose4.cxx:2510
static int left(const struct frozen *f)
Definition: mongoose6.cxx:622
int64_t content_len
Definition: mongoose4.cxx:487
Here is the call graph for this function:

◆ mg_send_file()

int void mg_send_file ( struct mg_connection conn,
const char *  path 
)

Definition at line 3332 of file mongoose4.cxx.

3332  {
3334  if (mg_stat(path, &file)) {
3335  handle_file_request(conn, path, &file);
3336  } else {
3337  send_http_error(conn, 404, "Not Found", "%s", "File not found");
3338  }
3339 }
static void send_http_error(struct mg_connection *, int, const char *, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(4
static void handle_file_request(struct mg_connection *conn, const char *path, struct file *filep)
Definition: mongoose4.cxx:3250
static int mg_stat(const char *path, struct file *filep)
Definition: mongoose4.cxx:1778
#define STRUCT_FILE_INITIALIZER
Definition: mongoose4.cxx:434
Here is the call graph for this function:

◆ mg_start()

struct mg_context* mg_start ( const char **  configuration_options,
mg_event_handler_t  func,
void *  user_data 
)

Definition at line 5466 of file mongoose4.cxx.

5468  {
5469  struct mg_context *ctx;
5470  const char *name, *value, *default_value;
5471  int i;
5472 
5473 #if defined(_WIN32) && !defined(__SYMBIAN32__)
5474  WSADATA data;
5475  WSAStartup(MAKEWORD(2,2), &data);
5476 #endif // _WIN32
5477 
5478  // Allocate context and initialize reasonable general case defaults.
5479  // TODO(lsm): do proper error handling here.
5480  if ((ctx = (struct mg_context *) calloc(1, sizeof(*ctx))) == NULL) {
5481  return NULL;
5482  }
5483  ctx->event_handler = func;
5484  ctx->user_data = user_data;
5485 
5486  while (options && (name = *options++) != NULL) {
5487  if ((i = get_option_index(name)) == -1) {
5488  cry(fc(ctx), "Invalid option: %s", name);
5489  free_context(ctx);
5490  return NULL;
5491  } else if ((value = *options++) == NULL) {
5492  cry(fc(ctx), "%s: option value cannot be NULL", name);
5493  free_context(ctx);
5494  return NULL;
5495  }
5496  if (ctx->config[i] != NULL) {
5497  cry(fc(ctx), "warning: %s: duplicate option", name);
5498  free(ctx->config[i]);
5499  }
5500  ctx->config[i] = mg_strdup(value);
5501  DEBUG_TRACE(("[%s] -> [%s]", name, value));
5502  }
5503 
5504  // Set default value if needed
5505  for (i = 0; config_options[i * 2] != NULL; i++) {
5506  default_value = config_options[i * 2 + 1];
5507  if (ctx->config[i] == NULL && default_value != NULL) {
5508  ctx->config[i] = mg_strdup(default_value);
5509  }
5510  }
5511 
5512  // NOTE(lsm): order is important here. SSL certificates must
5513  // be initialized before listening ports. UID must be set last.
5514  if (!set_gpass_option(ctx) ||
5515 #if !defined(NO_SSL)
5516  !set_ssl_option(ctx) ||
5517 #endif
5518  !set_ports_option(ctx) ||
5519 #if !defined(_WIN32)
5520  !set_uid_option(ctx) ||
5521 #endif
5522  !set_acl_option(ctx)) {
5523  free_context(ctx);
5524  return NULL;
5525  }
5526 
5527 #if !defined(_WIN32) && !defined(__SYMBIAN32__)
5528  // Ignore SIGPIPE signal, so if browser cancels the request, it
5529  // won't kill the whole process.
5530  (void) signal(SIGPIPE, SIG_IGN);
5531 #endif // !_WIN32
5532 
5533  (void) pthread_mutex_init(&ctx->mutex, NULL);
5534  (void) pthread_cond_init(&ctx->cond, NULL);
5535  (void) pthread_cond_init(&ctx->sq_empty, NULL);
5536  (void) pthread_cond_init(&ctx->sq_full, NULL);
5537 
5538  // Start master (listening) thread
5540 
5541  // Start worker threads
5542  for (i = 0; i < atoi(ctx->config[NUM_THREADS]); i++) {
5543  if (mg_start_thread(worker_thread, ctx) != 0) {
5544  cry(fc(ctx), "Cannot start worker thread: %ld", (long) ERRNO);
5545  } else {
5546  ctx->num_threads++;
5547  }
5548  }
5549 
5550  return ctx;
5551 }
int mg_start_thread(mg_thread_func_t func, void *param)
Definition: mongoose4.cxx:1802
static int set_ports_option(struct mg_context *ctx)
Definition: mongoose4.cxx:4877
static int set_uid_option(struct mg_context *ctx)
Definition: mongoose4.cxx:5003
static int set_gpass_option(struct mg_context *ctx)
Definition: mongoose4.cxx:5026
static void * worker_thread(void *thread_func_param)
Definition: mongoose4.cxx:5235
#define ERRNO
Definition: mongoose4.cxx:251
static struct mg_connection * fc(struct mg_context *ctx)
Definition: mongoose4.cxx:525
#define DEBUG_TRACE(x)
Definition: mongoose4.cxx:285
static int set_ssl_option(struct mg_context *ctx)
Definition: mongoose4.cxx:2060
static char * mg_strdup(const char *str)
Definition: mongoose4.cxx:575
@ NUM_THREADS
Definition: mongoose4.cxx:453
static void free_context(struct mg_context *ctx)
Definition: mongoose4.cxx:5428
static void static void cry(struct mg_connection *conn, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
static int set_acl_option(struct mg_context *ctx)
Definition: mongoose4.cxx:5036
static void * master_thread(void *thread_func_param)
Definition: mongoose4.cxx:5355
double value[100]
Definition: odbhist.cxx:42
pthread_cond_t sq_empty
Definition: mongoose4.cxx:475
mg_event_handler_t event_handler
Definition: mongoose4.cxx:461
void * user_data
Definition: mongoose4.cxx:462
volatile int num_threads
Definition: mongoose4.cxx:467
pthread_cond_t sq_full
Definition: mongoose4.cxx:474
pthread_mutex_t mutex
Definition: mongoose4.cxx:468
pthread_cond_t cond
Definition: mongoose4.cxx:469

◆ mg_start_thread()

int mg_start_thread ( mg_thread_func_t  f,
void *  p 
)

Definition at line 1802 of file mongoose4.cxx.

1802  {
1803  pthread_t thread_id;
1804  pthread_attr_t attr;
1805  int result;
1806 
1807  (void) pthread_attr_init(&attr);
1808  (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1809 
1810 #if USE_STACK_SIZE > 1
1811  // Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384
1812  (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
1813 #endif
1814 
1815  result = pthread_create(&thread_id, &attr, func, param);
1816  pthread_attr_destroy(&attr);
1817 
1818  return result;
1819 }
char param[10][256]
Definition: mana.cxx:250

◆ mg_stop()

void mg_stop ( struct mg_context ctx)

Definition at line 5452 of file mongoose4.cxx.

5452  {
5453  ctx->stop_flag = 1;
5454 
5455  // Wait until mg_fini() stops
5456  while (ctx->stop_flag != 2) {
5457  (void) mg_sleep(10);
5458  }
5459  free_context(ctx);
5460 
5461 #if defined(_WIN32) && !defined(__SYMBIAN32__)
5462  (void) WSACleanup();
5463 #endif // _WIN32
5464 }
#define mg_sleep(x)
Definition: mongoose4.cxx:250
volatile int stop_flag
Definition: mongoose4.cxx:458
Here is the call graph for this function:

◆ mg_upload()

FILE* mg_upload ( struct mg_connection conn,
const char *  destination_dir,
char *  path,
int  path_len 
)

Definition at line 4543 of file mongoose4.cxx.

4544  {
4545  const char *content_type_header, *boundary_start;
4546  char *buf, fname[1024], boundary[100], *s;
4547  int bl, n, i, j, headers_len, boundary_len, eof, buf_len, to_read, len = 0;
4548  FILE *fp;
4549 
4550  // Request looks like this:
4551  //
4552  // POST /upload HTTP/1.1
4553  // Host: 127.0.0.1:8080
4554  // Content-Length: 244894
4555  // Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryRVr
4556  //
4557  // ------WebKitFormBoundaryRVr
4558  // Content-Disposition: form-data; name="file"; filename="accum.png"
4559  // Content-Type: image/png
4560  //
4561  // <89>PNG
4562  // <PNG DATA>
4563  // ------WebKitFormBoundaryRVr
4564 
4565  // Extract boundary string from the Content-Type header
4566  if ((content_type_header = mg_get_header(conn, "Content-Type")) == NULL ||
4567  (boundary_start = mg_strcasestr(content_type_header,
4568  "boundary=")) == NULL ||
4569  (sscanf(boundary_start, "boundary=\"%99[^\"]\"", boundary) == 0 &&
4570  sscanf(boundary_start, "boundary=%99s", boundary) == 0) ||
4571  boundary[0] == '\0') {
4572  return NULL;
4573  }
4574 
4575  boundary_len = strlen(boundary);
4576  bl = boundary_len + 4; // \r\n--<boundary>
4577 
4578  // buf
4579  // conn->buf |<--------- buf_len ------>|
4580  // |=================|==========|===============|
4581  // |<--request_len-->|<--len--->| |
4582  // |<-----------data_len------->| conn->buf + conn->buf_size
4583 
4584  buf = conn->buf + conn->request_len;
4585  buf_len = conn->buf_size - conn->request_len;
4586  len = conn->data_len - conn->request_len;
4587 
4588  for (;;) {
4589  // Pull in headers
4590  assert(len >= 0 && len <= buf_len);
4591  to_read = buf_len - len;
4592  if (to_read > left_to_read(conn)) {
4593  to_read = (int) left_to_read(conn);
4594  }
4595  while (len < buf_len &&
4596  (n = pull(NULL, conn, buf + len, to_read)) > 0) {
4597  len += n;
4598  }
4599  if ((headers_len = get_request_len(buf, len)) <= 0) {
4600  break;
4601  }
4602 
4603  // Fetch file name.
4604  fname[0] = '\0';
4605  for (i = j = 0; i < headers_len; i++) {
4606  if (buf[i] == '\r' && buf[i + 1] == '\n') {
4607  buf[i] = buf[i + 1] = '\0';
4608  // TODO(lsm): don't expect filename to be the 3rd field,
4609  // parse the header properly instead.
4610  sscanf(&buf[j], "Content-Disposition: %*s %*s filename=\"%1023[^\"]",
4611  fname);
4612  j = i + 2;
4613  }
4614  }
4615 
4616  // Give up if the headers are not what we expect
4617  if (fname[0] == '\0') {
4618  break;
4619  }
4620 
4621  // Move data to the beginning of the buffer
4622  assert(len >= headers_len);
4623  memmove(buf, &buf[headers_len], len - headers_len);
4624  len -= headers_len;
4625  conn->data_len = conn->request_len + len;
4626 
4627  // We open the file with exclusive lock held. This guarantee us
4628  // there is no other thread can save into the same file simultaneously.
4629  fp = NULL;
4630 
4631  // Construct destination file name. Do not allow paths to have slashes.
4632  if ((s = strrchr(fname, '/')) == NULL &&
4633  (s = strrchr(fname, '\\')) == NULL) {
4634  s = fname;
4635  }
4636 
4637  // Open file in binary mode. TODO: set an exclusive lock.
4638  snprintf(path, path_len, "%s/%s", destination_dir, s);
4639  if ((fp = fopen(path, "wb")) == NULL) {
4640  break;
4641  }
4642 
4643  // Read POST data, write into file until boundary is found.
4644  eof = n = 0;
4645  do {
4646  len += n;
4647  for (i = 0; i < len - bl; i++) {
4648  if (!memcmp(&buf[i], "\r\n--", 4) &&
4649  !memcmp(&buf[i + 4], boundary, boundary_len)) {
4650  // Found boundary, that's the end of file data.
4651  fwrite(buf, 1, i, fp);
4652  eof = 1;
4653  memmove(buf, &buf[i + bl], len - (i + bl));
4654  len -= i + bl;
4655  break;
4656  }
4657  }
4658  if (!eof && len > bl) {
4659  fwrite(buf, 1, len - bl, fp);
4660  memmove(buf, &buf[len - bl], bl);
4661  len = bl;
4662  }
4663  to_read = buf_len - len;
4664  if (to_read > left_to_read(conn)) {
4665  to_read = (int) left_to_read(conn);
4666  }
4667  } while (!eof && (n = pull(NULL, conn, buf + len, to_read)) > 0);
4668  conn->data_len = conn->request_len + len;
4669 
4670  if (eof) {
4671  rewind(fp);
4672  return fp;
4673  } else {
4674  fclose(fp);
4675  }
4676  }
4677 
4678  return NULL;
4679 }
const char * mg_get_header(const struct mg_connection *conn, const char *name)
Definition: mongoose4.cxx:693
INT bl
Definition: mdump.cxx:32
static int get_request_len(const char *buf, int buf_len)
Definition: mongoose4.cxx:2796
static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
Definition: mongoose4.cxx:2487
INT j
Definition: odbhist.cxx:40
Here is the call graph for this function:

◆ mg_url_decode()

int mg_url_decode ( const char *  src,
int  src_len,
char *  dst,
int  dst_len,
int  is_form_url_encoded 
)

Definition at line 2606 of file mongoose4.cxx.

2607  {
2608  int i, j, a, b;
2609 #define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
2610 
2611  for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
2612  if (src[i] == '%' && i < src_len - 2 &&
2613  isxdigit(* (const unsigned char *) (src + i + 1)) &&
2614  isxdigit(* (const unsigned char *) (src + i + 2))) {
2615  a = tolower(* (const unsigned char *) (src + i + 1));
2616  b = tolower(* (const unsigned char *) (src + i + 2));
2617  dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
2618  i += 2;
2619  } else if (is_form_url_encoded && src[i] == '+') {
2620  dst[j] = ' ';
2621  } else {
2622  dst[j] = src[i];
2623  }
2624  }
2625 
2626  dst[j] = '\0'; // Null-terminate the destination
2627 
2628  return i >= src_len ? j : -1;
2629 }
#define HEXTOI(x)

◆ mg_version()

const char* mg_version ( void  )

Definition at line 2396 of file mongoose4.cxx.

2396  {
2397  return MONGOOSE_VERSION;
2398 }
#define MONGOOSE_VERSION
Definition: mongoose4.cxx:261
Here is the caller graph for this function:

◆ mg_websocket_handshake()

void mg_websocket_handshake ( struct mg_connection )

◆ mg_websocket_read()

int mg_websocket_read ( struct mg_connection ,
int *  bits,
char **  data 
)

◆ mg_websocket_write()

int mg_websocket_write ( struct mg_connection conn,
int  opcode,
const char *  data,
size_t  data_len 
)

◆ mg_write()

int mg_write ( struct mg_connection conn,
const void *  buf,
int  len 
)

Definition at line 2568 of file mongoose4.cxx.

2568  {
2569  time_t now;
2570  int64_t n, total, allowed;
2571 
2572  if (conn->throttle > 0) {
2573  if ((now = time(NULL)) != conn->last_throttle_time) {
2574  conn->last_throttle_time = now;
2575  conn->last_throttle_bytes = 0;
2576  }
2577  allowed = conn->throttle - conn->last_throttle_bytes;
2578  if (allowed > (int64_t) len) {
2579  allowed = len;
2580  }
2581  if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
2582  (int64_t) allowed)) == allowed) {
2583  buf = (char *) buf + total;
2584  conn->last_throttle_bytes += total;
2585  while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
2586  allowed = conn->throttle > (int64_t) len - total ?
2587  (int64_t) len - total : conn->throttle;
2588  if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
2589  (int64_t) allowed)) != allowed) {
2590  break;
2591  }
2592  sleep(1);
2593  conn->last_throttle_bytes = allowed;
2594  conn->last_throttle_time = time(NULL);
2595  buf = (char *) buf + n;
2596  total += n;
2597  }
2598  }
2599  } else {
2600  total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
2601  (int64_t) len);
2602  }
2603  return (int) total;
2604 }
#define sleep(ms)
Definition: midas_macro.h:269
static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
Definition: mongoose4.cxx:2451
double total[100]
Definition: odbhist.cxx:42
time_t last_throttle_time
Definition: mongoose4.cxx:497
struct socket client
Definition: mongoose4.cxx:484
int64_t last_throttle_bytes
Definition: mongoose4.cxx:498
struct mg_context * ctx
Definition: mongoose4.cxx:481
SOCKET sock
Definition: mongoose4.cxx:439
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ conn

struct mg_connection* mg_event::conn

Definition at line 66 of file mongoose4.h.

◆ conn_data

void* mg_event::conn_data

Definition at line 63 of file mongoose4.h.

◆ event_param

void* mg_event::event_param

Definition at line 64 of file mongoose4.h.

◆ http_headers

struct mg_request_info::mg_header mg_request_info::http_headers[64]

◆ http_version

const char* mg_request_info::http_version

Definition at line 39 of file mongoose4.h.

◆ is_ssl

int mg_request_info::is_ssl

Definition at line 44 of file mongoose4.h.

◆ name

const char* mg_request_info::mg_header::name

Definition at line 48 of file mongoose4.h.

◆ num_headers

int mg_request_info::num_headers

Definition at line 46 of file mongoose4.h.

◆ query_string

const char* mg_request_info::query_string

Definition at line 40 of file mongoose4.h.

◆ remote_ip

long mg_request_info::remote_ip

Definition at line 42 of file mongoose4.h.

◆ remote_port

int mg_request_info::remote_port

Definition at line 43 of file mongoose4.h.

◆ remote_user

const char* mg_request_info::remote_user

Definition at line 41 of file mongoose4.h.

◆ request_info

struct mg_request_info* mg_event::request_info

Definition at line 67 of file mongoose4.h.

◆ request_method

const char* mg_request_info::request_method

Definition at line 37 of file mongoose4.h.

◆ type

int mg_event::type

Definition at line 54 of file mongoose4.h.

◆ uri

const char* mg_request_info::uri

Definition at line 38 of file mongoose4.h.

◆ user_data

void* mg_event::user_data

Definition at line 62 of file mongoose4.h.

◆ value

const char* mg_request_info::mg_header::value

Definition at line 49 of file mongoose4.h.