Previous 199869 Revisions Next

r30952 Thursday 12th June, 2014 at 07:03:23 UTC by Miodrag Milanović
Updated mongoose and fixed initial websocket connecte to client (nw)
[src/emu]luaengine.c webengine.c
[src/lib/web]mongoose.c mongoose.h

trunk/src/emu/luaengine.c
r30951r30952
570570{
571571   int s = luaL_loadfile(m_lua_state, filename);
572572   report(s);   
573   update_machine();
573574   start();
574575}
575576
r30951r30952
581582{
582583   int s = luaL_loadstring(m_lua_state, value);
583584   report(s);   
585   update_machine();
584586   start();
585587}
586588
trunk/src/emu/webengine.c
r30951r30952
276276      return conn->content_len == 4 && !memcmp(conn->content, "exit", 4) ? MG_FALSE : MG_TRUE;
277277    } else {
278278      web_engine *engine = static_cast<web_engine *>(conn->server_param);   
279      return engine->begin_request_handler(conn);   
279      return engine->begin_request_handler(conn);
280280   }
281  } else if (ev== MG_WS_CONNECT) {
282   // New websocket connection. Send connection ID back to the client.
283   mg_websocket_printf(conn, WEBSOCKET_OPCODE_TEXT, "update_machine");
284   return MG_FALSE;
281285  } else if (ev == MG_AUTH) {
282286    return MG_TRUE;
283287  } else {
trunk/src/lib/web/mongoose.c
r30951r30952
222222void ns_server_wakeup(struct ns_server *);
223223void ns_server_wakeup_ex(struct ns_server *, ns_callback_t, void *, size_t);
224224void ns_iterate(struct ns_server *, ns_callback_t cb, void *param);
225struct ns_connection *ns_next(struct ns_server *, struct ns_connection *);
225226struct ns_connection *ns_add_sock(struct ns_server *, sock_t sock, void *p);
226227
227228int ns_bind(struct ns_server *, const char *addr);
r30951r30952
676677#endif
677678    }
678679    if (flags & 2) {
679      snprintf(buf + strlen(buf), len - (strlen(buf) + 1), ":%d",
680      (int) ntohs(sa.sin.sin_port));
680      snprintf(buf + strlen(buf), len - (strlen(buf) + 1), "%s%d",
681               flags & 1 ? ":" : "", (int) ntohs(sa.sin.sin_port));
681682    }
682683  }
683684}
r30951r30952
861862  tv.tv_usec = (milli % 1000) * 1000;
862863
863864  if (select((int) max_fd + 1, &read_set, &write_set, NULL, &tv) > 0) {
865    // select() might have been waiting for a long time, reset current_time
866    // now to prevent last_io_time being set to the past.
867    current_time = time(NULL);
868   
864869    // Accept new connections
865870    if (server->listening_sock != INVALID_SOCKET &&
866871        FD_ISSET(server->listening_sock, &read_set)) {
r30951r30952
885890
886891    for (conn = server->active_connections; conn != NULL; conn = tmp_conn) {
887892      tmp_conn = conn->next;
888      //DBG(("%p LOOP %p", conn, conn->ssl));
889893      if (FD_ISSET(conn->sock, &read_set)) {
890894        conn->last_io_time = current_time;
891895        ns_read_from_socket(conn);
r30951r30952
979983  return conn;
980984}
981985
986struct ns_connection *ns_next(struct ns_server *s, struct ns_connection *conn) {
987  return conn == NULL ? s->active_connections : conn->next;
988}
989
982990void ns_iterate(struct ns_server *server, ns_callback_t cb, void *param) {
983991  struct ns_connection *conn, *tmp_conn;
984992
r30951r30952
16561664
16571665static void *pull_from_stdout(void *arg) {
16581666  struct threadparam *tp = (struct threadparam *)arg;
1659  int k=0, stop = 0;
1667  int k, stop = 0;
16601668  DWORD n, sent;
16611669  char buf[IOBUF_SIZE];
16621670
r30951r30952
27042712      free(copy);
27052713    }
27062714
2715    // If we send closing frame, schedule a connection to be closed after
2716    // data is drained to the client.
2717    if (opcode == WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
2718      MG_CONN_2_CONN(conn)->ns_conn->flags |= NSF_FINISHED_SENDING_DATA;
2719    }
2720
27072721    return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
27082722}
27092723
r30951r30952
27342748    if (call_user(MG_CONN_2_CONN(conn), MG_WS_HANDSHAKE) == MG_FALSE) {
27352749      send_websocket_handshake(conn, key);
27362750    }
2751    call_user(MG_CONN_2_CONN(conn), MG_WS_CONNECT);
27372752  }
27382753}
27392754
r30951r30952
39954010}
39964011#endif
39974012
3998static int parse_url(const char *url, char *proto, size_t plen,
3999                     char *host, size_t hlen, unsigned short *port) {
4000  int n;
4001  char fmt1[100], fmt2[100], fmt3[100];
4002
4003  *port = 80;
4004  proto[0] = host[0] = '\0';
4005
4006  snprintf(fmt1, sizeof(fmt1), "%%%zu[a-z]://%%%zu[^: ]:%%hu%%n", plen, hlen);
4007  snprintf(fmt2, sizeof(fmt2), "%%%zu[a-z]://%%%zu[^/ ]%%n", plen, hlen);
4008  snprintf(fmt3, sizeof(fmt3), "%%%zu[^: ]:%%hu%%n", hlen);
4009
4010  if (sscanf(url, fmt1, proto, host, port, &n) == 3 ||
4011      sscanf(url, fmt2, proto, host, &n) == 2) {
4012    return n;
4013  } else if (sscanf(url, fmt3, host, port, &n) == 2) {
4014    proto[0] = '\0';
4015    return n;
4016  }
4017
4018  return 0;
4019}
4020
40214013static void proxy_request(struct ns_connection *pc, struct mg_connection *c) {
40224014  int i, sent_close_header = 0;
40234015
r30951r30952
40424034
40434035}
40444036
4037#ifdef NS_ENABLE_SSL
4038int mg_terminate_ssl(struct mg_connection *c, const char *cert) {
4039  static const char ok[] = "HTTP/1.0 200 OK\r\n\r\n";
4040  struct connection *conn = MG_CONN_2_CONN(c);
4041  int n;
4042  SSL_CTX *ctx;
4043
4044  DBG(("%p MITM", conn));
4045  SSL_library_init();
4046  if ((ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) return 0;
4047
4048  SSL_CTX_use_certificate_file(ctx, cert, 1);
4049  SSL_CTX_use_PrivateKey_file(ctx, cert, 1);
4050  SSL_CTX_use_certificate_chain_file(ctx, cert);
4051
4052  // When clear-text reply is pushed to client, switch to SSL mode.
4053  n = send(conn->ns_conn->sock, ok, sizeof(ok) - 1, 0);
4054  DBG(("%p %lu %d SEND", c, sizeof(ok) - 1, n));
4055  conn->ns_conn->send_iobuf.len = 0;
4056  conn->endpoint_type = EP_USER;  // To keep-alive in close_local_endpoint()
4057  close_local_endpoint(conn);     // Clean up current CONNECT request
4058  if ((conn->ns_conn->ssl = SSL_new(ctx)) != NULL) {
4059    SSL_set_fd(conn->ns_conn->ssl, conn->ns_conn->sock);
4060  }
4061  SSL_CTX_free(ctx);
4062  return 1;
4063}
4064#endif
4065
40454066static void proxify_connection(struct connection *conn) {
40464067  char proto[10], host[500], cert[500];
40474068  unsigned short port = 80;
40484069  struct mg_connection *c = &conn->mg_conn;
40494070  struct ns_server *server = &conn->server->ns_server;
4050  struct ns_connection *pc;
4051  int n, use_ssl;
4071  struct ns_connection *pc = NULL;
4072  int n = 0;
4073  const char *url = c->uri;
40524074
40534075  proto[0] = host[0] = cert[0] = '\0';
4054  n = parse_url(c->uri, proto, sizeof(proto), host, sizeof(host), &port);
4076  if (sscanf(url, "%499[^: ]:%hu%n", host, &port, &n) != 2 &&
4077      sscanf(url, "%9[a-z]://%499[^: ]:%hu%n", proto, host, &port, &n) != 3 &&
4078      sscanf(url, "%9[a-z]://%499[^/ ]%n", proto, host, &n) != 2) {
4079    n = 0;
4080  }
40554081
40564082#ifdef NS_ENABLE_SSL
40574083  // Find out whether we should be in the MITM mode
r30951r30952
40604086    int host_len = strlen(host);
40614087    struct vec a, b;
40624088
4063    while ((certs = next_option(certs, &a, &b)) != NULL) {
4064      if (a.len == host_len && mg_strncasecmp(a.ptr, host, a.len) == 0) {
4065        snprintf(cert, sizeof(cert), "%.*s", b.len, b.ptr);
4066        break;
4067      }
4089    while (conn->ns_conn->ssl == NULL && port != 80 &&
4090           (certs = next_option(certs, &a, &b)) != NULL) {
4091      if (a.len != host_len || mg_strncasecmp(a.ptr, host, a.len)) continue;
4092      snprintf(cert, sizeof(cert), "%.*s", b.len, b.ptr);
4093      mg_terminate_ssl(&conn->mg_conn, cert);
4094      return;
40684095    }
40694096  }
40704097#endif
40714098
4072  use_ssl = port != 80 && cert[0] != '\0';
4073
40744099  if (n > 0 &&
4075      (pc = ns_connect(server, host, port, use_ssl, conn)) != NULL) {
4100      (pc = ns_connect(server, host, port, conn->ns_conn->ssl != NULL,
4101                       conn)) != NULL) {
40764102    // Interlink two connections
40774103    pc->flags |= MG_PROXY_CONN;
40784104    conn->endpoint_type = EP_PROXY;
40794105    conn->endpoint.nc = pc;
4080    DBG(("%p [%s] -> %p %d", conn, c->uri, pc, use_ssl));
4106    DBG(("%p [%s] -> %p %p", conn, c->uri, pc, conn->ns_conn->ssl));
40814107
40824108    if (strcmp(c->request_method, "CONNECT") == 0) {
40834109      // For CONNECT request, reply with 200 OK. Tunnel is established.
r30951r30952
40854111      conn->request_len = 0;
40864112      free(conn->request);
40874113      conn->request = NULL;
4088#ifdef NS_ENABLE_SSL
4089      if (use_ssl) {
4090        SSL_CTX *ctx;
4091
4092        DBG(("%s", "Triggering MITM mode: terminating SSL connection"));
4093        SSL_library_init();
4094        ctx = SSL_CTX_new(SSLv23_server_method());
4095
4096        if (ctx == NULL) {
4097          pc->flags |= NSF_CLOSE_IMMEDIATELY;
4098        } else {
4099          SSL_CTX_use_certificate_file(ctx, cert, 1);
4100          SSL_CTX_use_PrivateKey_file(ctx, cert, 1);
4101          SSL_CTX_use_certificate_chain_file(ctx, cert);
4102
4103          // When clear-text reply is pushed to client, switch to SSL mode.
4104          n = send(conn->ns_conn->sock, conn->ns_conn->send_iobuf.buf,
4105                   conn->ns_conn->send_iobuf.len, 0);
4106          DBG(("%p %lu %d SEND", c, conn->ns_conn->send_iobuf.len, n));
4107          conn->ns_conn->send_iobuf.len = 0;
4108          if ((conn->ns_conn->ssl = SSL_new(ctx)) != NULL) {
4109            //SSL_set_fd((SSL *) c->connection_param, conn->ns_conn->sock);
4110            SSL_set_fd(conn->ns_conn->ssl, conn->ns_conn->sock);
4111          }
4112          SSL_CTX_free(ctx);
4113        }
4114      }
4115#endif
41164114    } else {
41174115      // For other methods, forward the request to the target host.
41184116      c->uri += n;
r30951r30952
41874185#endif  // !MONGOOSE_NO_FILESYSTEM
41884186
41894187static void open_local_endpoint(struct connection *conn, int skip_user) {
4188#ifndef MONGOOSE_NO_FILESYSTEM
41904189  char path[MAX_PATH_SIZE];
41914190  file_stat_t st;
41924191  int exists = 0;
4192#endif
41934193
41944194  // If EP_USER was set in a prev call, reset it
41954195  conn->endpoint_type = EP_NONE;
r30951r30952
43024302
43034303static void do_proxy(struct connection *conn) {
43044304  if (conn->request_len == 0) {
4305    DBG(("%p parsing", conn));
43064305    try_parse(conn);
4307    if (conn->request_len > 0 &&
4308        call_user(conn, MG_REQUEST) == MG_FALSE) {
4306    DBG(("%p parsing -> %d", conn, conn->request_len));
4307    if (conn->request_len > 0 && call_user(conn, MG_REQUEST) == MG_FALSE) {
43094308      proxy_request(conn->endpoint.nc, &conn->mg_conn);
43104309    } else if (conn->request_len < 0) {
43114310      ns_forward(conn->ns_conn, conn->endpoint.nc);
r30951r30952
45644563  }
45654564}
45664565
4566struct mg_connection *mg_next(struct mg_server *s, struct mg_connection *c) {
4567  struct connection *conn = MG_CONN_2_CONN(c);
4568  struct ns_connection *nc = ns_next(&s->ns_server,
4569                                     c == NULL ? NULL : conn->ns_conn);
4570   
4571  return nc == NULL ? NULL :
4572    & ((struct connection *) nc->connection_data)->mg_conn;
4573}
4574
45674575// Apply function to all active connections.
45684576void mg_iterate_over_connections(struct mg_server *server, mg_handler_t cb,
45694577  void *param) {
r30951r30952
47304738    if (port < 0) {
47314739      error_msg = "Cannot bind to port";
47324740    } else {
4733      if (!strcmp(value, "0")) {
4734        char buf[10];
4735        mg_snprintf(buf, sizeof(buf), "%d", port);
4736        free(*v);
4737        *v = mg_strdup(buf);
4738      }
4741      char buf[100];
4742      ns_sock_to_str(server->ns_server.listening_sock, buf, sizeof(buf), 2);
4743      free(*v);
4744      *v = mg_strdup(buf);
47394745    }
47404746#ifndef _WIN32
47414747  } else if (ind == RUN_AS_USER) {
r30951r30952
48294835
48304836static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) {
48314837  struct connection *conn = (struct connection *) nc->connection_data;
4838#ifndef MONGOOSE_NO_FILESYSTEM
48324839  struct mg_server *server = (struct mg_server *) nc->server;
4840#endif
48334841
48344842  // Send NS event to the handler. Note that call_user won't send an event
48354843  // if conn == NULL. Therefore, repeat this for NS_ACCEPT event as well.
trunk/src/lib/web/mongoose.h
r30951r30952
6868  MG_REPLY,       // If callback returns MG_FALSE, Mongoose closes connection
6969  MG_CLOSE,       // Connection is closed, callback return value is ignored
7070  MG_WS_HANDSHAKE,  // New websocket connection, handshake request
71  MG_WS_CONNECT,  // New websocket connection established
7172  MG_HTTP_ERROR   // If callback returns MG_FALSE, Mongoose continues with err
7273};
7374typedef int (*mg_handler_t)(struct mg_connection *, enum mg_event);
r30951r30952
9293void mg_set_listening_socket(struct mg_server *, int sock);
9394int mg_get_listening_socket(struct mg_server *);
9495void mg_iterate_over_connections(struct mg_server *, mg_handler_t, void *);
96struct mg_connection *mg_next(struct mg_server *, struct mg_connection *);
9597void mg_wakeup_server(struct mg_server *);
9698void mg_wakeup_server_ex(struct mg_server *, mg_handler_t, const char *, ...);
9799struct mg_connection *mg_connect(struct mg_server *, const char *, int, int);

Previous 199869 Revisions Next


© 1997-2024 The MAME Team