Previous 199869 Revisions Next

r30822 Wednesday 4th June, 2014 at 08:10:44 UTC by Miodrag Milanović
Updated to latest mongoose, used new added features (nw)
[src/emu]webengine.c
[src/lib]lib.mak
[src/lib/web]mongoose.c mongoose.h
[web]index.html

trunk/src/emu/webengine.c
r30821r30822
236236   }
237237   else if (!strncmp(conn->uri, "/screenshot.png",15))
238238   {
239      FILE *fp = (FILE *) conn->connection_param;
240      char buf[200];
241      size_t n = 0;
242      if (fp == NULL)
239      screen_device_iterator iter(m_machine->root_device());
240      screen_device *screen = iter.first();
241
242      if (screen == NULL)
243243      {
244         screen_device_iterator iter(m_machine->root_device());
245         screen_device *screen = iter.first();
244         return 0;
245      }
246246
247         if (screen == NULL)
248         {
249            return 0;
250         }
247      astring fname("screenshot.png");
248      emu_file file(m_machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
249      file_error filerr = file.open(fname);
251250
252         astring fname("screenshot.png");
253         {
254            emu_file file(m_machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
255            file_error filerr = file.open(fname);
256
257            if (filerr != FILERR_NONE)
258            {
259               return 0;
260            }
261
262            m_machine->video().save_snapshot(screen, file);
263            astring fullpath(file.fullpath());
264            file.close();
265         }
266         
267         {
268            emu_file file(m_machine->options().snapshot_directory(), OPEN_FLAG_READ);
269            file_error filerr = file.open(fname);
270
271            if (filerr != FILERR_NONE)
272            {
273               return 0;
274            }
275                     
276            file.seek(0, SEEK_SET);
277            mg_send_header(conn, "Content-Type", "image/png");
278            mg_send_header(conn, "Cache-Control", "no-cache, no-store, must-revalidate");
279            mg_send_header(conn, "Pragma", "no-cache");
280            mg_send_header(conn, "Expires", "0");         
281            do
282            {
283               n = file.read(buf, sizeof(buf));                             
284               mg_send_data(conn, buf, n);
285            }
286            while (n==sizeof(buf));
287            file.close();           
288         }
251      if (filerr != FILERR_NONE)
252      {
253         return 0;
289254      }
290      return MG_TRUE;
255
256      m_machine->video().save_snapshot(screen, file);
257      astring fullpath(file.fullpath());
258      file.close();
259      mg_send_header(conn, "Cache-Control", "no-cache, no-store, must-revalidate");
260      mg_send_header(conn, "Pragma", "no-cache");
261      mg_send_header(conn, "Expires", "0");         
262      mg_send_file(conn, fullpath.cstr());
263      return MG_MORE; // It is important to return MG_MORE after mg_send_file!
291264   }
292265   return 0;
293266}
trunk/src/lib/lib.mak
r30821r30822
532532$(LIBOBJ)/web/%.o: $(LIBSRC)/web/%.cpp | $(OSPREBUILD)
533533   @echo Compiling $<...
534534   $(CC) $(CDEFS) $(CFLAGS) -I$(LIBSRC)/web -c $< -o $@
535
536$(LIBOBJ)/web/%.o: $(LIBSRC)/web/%.c | $(OSPREBUILD)
537   @echo Compiling $<...
538   $(CC) $(CDEFS) $(CFLAGS) -I$(LIBSRC)/web -DNS_STACK_SIZE=0 -c $< -o $@
trunk/src/lib/web/mongoose.c
r30821r30822
337337  (void) pthread_attr_init(&attr);
338338  (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
339339
340#ifdef NS_STACK_SIZE
341340#if NS_STACK_SIZE > 1
342341  (void) pthread_attr_setstacksize(&attr, NS_STACK_SIZE);
343342#endif
344#endif
345343
346344  pthread_create(&thread_id, &attr, f, p);
347345  pthread_attr_destroy(&attr);
r30821r30822
807805    iobuf_remove(io, n);
808806  }
809807
810  if (io->len == 0 && conn->flags & NSF_FINISHED_SENDING_DATA) {
808  if (io->len == 0 && (conn->flags & NSF_FINISHED_SENDING_DATA)) {
811809    conn->flags |= NSF_CLOSE_IMMEDIATELY;
812810  }
813811}
r30821r30822
16041602  ns_send(conn->ns_conn, "\r\n", 2);
16051603}
16061604
1607int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
1605size_t mg_printf(struct mg_connection *conn, const char *fmt, ...) {
16081606  struct connection *c = MG_CONN_2_CONN(conn);
1609  int len;
16101607  va_list ap;
16111608
16121609  va_start(ap, fmt);
1613  len = ns_vprintf(c->ns_conn, fmt, ap);
1610  ns_vprintf(c->ns_conn, fmt, ap);
16141611  va_end(ap);
16151612
1616  return len;
1613  return c->ns_conn->send_iobuf.len;
16171614}
16181615
16191616static void ns_forward(struct ns_connection *from, struct ns_connection *to) {
r30821r30822
21782175    n = (int) strlen(ri->uri);
21792176    mg_url_decode(ri->uri, n, (char *) ri->uri, n + 1, 0);
21802177    if (*ri->uri == '/' || *ri->uri == '.') {
2181      remove_double_dots_and_double_slashes((char *) ri->uri);     
2178      remove_double_dots_and_double_slashes((char *) ri->uri);
21822179    }
21832180  }
21842181
r30821r30822
23782375     (header == NULL && http_version && !strcmp(http_version, "1.1")));
23792376}
23802377
2381int mg_write(struct mg_connection *c, const void *buf, int len) {
2378size_t mg_write(struct mg_connection *c, const void *buf, int len) {
23822379  struct connection *conn = MG_CONN_2_CONN(c);
2383  return ns_send(conn->ns_conn, buf, len);
2380  ns_send(conn->ns_conn, buf, len);
2381  return conn->ns_conn->send_iobuf.len;
23842382}
23852383
23862384void mg_send_status(struct mg_connection *c, int status) {
r30821r30822
24072405  }
24082406}
24092407
2410void mg_send_data(struct mg_connection *c, const void *data, int data_len) {
2408size_t mg_send_data(struct mg_connection *c, const void *data, int data_len) {
2409  struct connection *conn = MG_CONN_2_CONN(c);
24112410  terminate_headers(c);
24122411  write_chunk(MG_CONN_2_CONN(c), (const char *) data, data_len);
2412  return conn->ns_conn->send_iobuf.len;
24132413}
24142414
2415void mg_printf_data(struct mg_connection *c, const char *fmt, ...) {
2415size_t mg_printf_data(struct mg_connection *c, const char *fmt, ...) {
24162416  struct connection *conn = MG_CONN_2_CONN(c);
24172417  va_list ap;
24182418  int len;
r30821r30822
24302430  if (buf != mem && buf != NULL) {
24312431    free(buf);
24322432  }
2433  return conn->ns_conn->send_iobuf.len;
24332434}
24342435
24352436#if !defined(MONGOOSE_NO_WEBSOCKET) || !defined(MONGOOSE_NO_AUTH)
r30821r30822
26622663  return buffered;
26632664}
26642665
2665int mg_websocket_write(struct mg_connection* conn, int opcode,
2666size_t mg_websocket_write(struct mg_connection* conn, int opcode,
26662667                       const char *data, size_t data_len) {
26672668    unsigned char mem[4192], *copy = mem;
26682669    size_t copy_len = 0;
2669    int retval = -1;
26702670
26712671    if (data_len + 10 > sizeof(mem) &&
26722672        (copy = (unsigned char *) malloc(data_len + 10)) == NULL) {
2673      return -1;
2673      return 0;
26742674    }
26752675
26762676    copy[0] = 0x80 + (opcode & 0x0f);
r30821r30822
26982698    }
26992699
27002700    if (copy_len > 0) {
2701      retval = mg_write(conn, copy, copy_len);
2701      mg_write(conn, copy, copy_len);
27022702    }
27032703    if (copy != mem) {
27042704      free(copy);
27052705    }
27062706
2707    return retval;
2707    return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
27082708}
27092709
2710int mg_websocket_printf(struct mg_connection* conn, int opcode,
2711                        const char *fmt, ...) {
2710size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
2711                           const char *fmt, ...) {
27122712  char mem[4192], *buf = mem;
27132713  va_list ap;
27142714  int len;
r30821r30822
27232723    free(buf);
27242724  }
27252725
2726  return len;
2726  return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
27272727}
27282728
27292729static void send_websocket_handshake_if_requested(struct mg_connection *conn) {
r30821r30822
41234123  }
41244124}
41254125
4126static void open_local_endpoint(struct connection *conn, int skip_user) {
41274126#ifndef MONGOOSE_NO_FILESYSTEM
4127void mg_send_file(struct mg_connection *c, const char *file_name) {
4128  struct connection *conn = MG_CONN_2_CONN(c);
41284129  file_stat_t st;
41294130  char path[MAX_PATH_SIZE];
41304131  int exists = 0, is_directory = 0;
r30821r30822
41384139#else
41394140  const char *dir_lst = "yes";
41404141#endif
4142
4143  mg_snprintf(path, sizeof(path), "%s", file_name);
4144  exists = stat(path, &st) == 0;
4145  is_directory = S_ISDIR(st.st_mode);
4146 
4147  if (!exists || must_hide_file(conn, path)) {
4148    send_http_error(conn, 404, NULL);
4149  } else if (is_directory &&
4150             conn->mg_conn.uri[strlen(conn->mg_conn.uri) - 1] != '/') {
4151    conn->mg_conn.status_code = 301;
4152    mg_printf(&conn->mg_conn, "HTTP/1.1 301 Moved Permanently\r\n"
4153              "Location: %s/\r\n\r\n", conn->mg_conn.uri);
4154    close_local_endpoint(conn);
4155  } else if (is_directory && !find_index_file(conn, path, sizeof(path), &st)) {
4156    if (!mg_strcasecmp(dir_lst, "yes")) {
4157#ifndef MONGOOSE_NO_DIRECTORY_LISTING
4158      send_directory_listing(conn, path);
4159#else
4160      send_http_error(conn, 501, NULL);
41414161#endif
4162    } else {
4163      send_http_error(conn, 403, NULL);
4164    }
4165  } else if (mg_match_prefix(cgi_pat, strlen(cgi_pat), path) > 0) {
4166#if !defined(MONGOOSE_NO_CGI)
4167    open_cgi_endpoint(conn, path);
4168#else
4169    send_http_error(conn, 501, NULL);
4170#endif // !MONGOOSE_NO_CGI
4171#ifndef MONGOOSE_NO_SSI
4172  } else if (mg_match_prefix(conn->server->config_options[SSI_PATTERN],
4173                             strlen(conn->server->config_options[SSI_PATTERN]),
4174                             path) > 0) {
4175    handle_ssi_request(conn, path);
4176#endif
4177  } else if (is_not_modified(conn, &st)) {
4178    send_http_error(conn, 304, NULL);
4179  } else if ((conn->endpoint.fd = open(path, O_RDONLY | O_BINARY)) != -1) {
4180    // O_BINARY is required for Windows, otherwise in default text mode
4181    // two bytes \r\n will be read as one.
4182    open_file_endpoint(conn, path, &st);
4183  } else {
4184    send_http_error(conn, 404, NULL);
4185  }
4186}
4187#endif  // !MONGOOSE_NO_FILESYSTEM
41424188
4189static void open_local_endpoint(struct connection *conn, int skip_user) {
4190  char path[MAX_PATH_SIZE];
4191  file_stat_t st;
4192  int exists = 0;
4193
41434194  // If EP_USER was set in a prev call, reset it
41444195  conn->endpoint_type = EP_NONE;
41454196
r30821r30822
41724223    proxify_connection(conn);
41734224    return;
41744225  }
4175
4176#ifdef MONGOOSE_NO_FILESYSTEM
4226 
41774227  if (!strcmp(conn->mg_conn.request_method, "OPTIONS")) {
41784228    send_options(conn);
4179  } else {
4180    send_http_error(conn, 404, NULL);
4229    return;
41814230  }
4231 
4232#ifdef MONGOOSE_NO_FILESYSTEM
4233  send_http_error(conn, 404, NULL);
41824234#else
41834235  exists = convert_uri_to_file_name(conn, path, sizeof(path), &st);
4184  is_directory = S_ISDIR(st.st_mode);
41854236
41864237  if (!strcmp(conn->mg_conn.request_method, "OPTIONS")) {
41874238    send_options(conn);
r30821r30822
42034254  } else if (!strcmp(conn->mg_conn.request_method, "PUT")) {
42044255    handle_put(conn, path);
42054256#endif
4206  } else if (!exists || must_hide_file(conn, path)) {
4207    send_http_error(conn, 404, NULL);
4208  } else if (is_directory &&
4209             conn->mg_conn.uri[strlen(conn->mg_conn.uri) - 1] != '/') {
4210    conn->mg_conn.status_code = 301;
4211    mg_printf(&conn->mg_conn, "HTTP/1.1 301 Moved Permanently\r\n"
4212              "Location: %s/\r\n\r\n", conn->mg_conn.uri);
4213    close_local_endpoint(conn);
4214  } else if (is_directory && !find_index_file(conn, path, sizeof(path), &st)) {
4215    if (!mg_strcasecmp(dir_lst, "yes")) {
4216#ifndef MONGOOSE_NO_DIRECTORY_LISTING
4217      send_directory_listing(conn, path);
4218#else
4219      send_http_error(conn, 501, NULL);
4220#endif
4221    } else {
4222      send_http_error(conn, 403, NULL);
4223    }
4224  } else if (mg_match_prefix(cgi_pat, strlen(cgi_pat), path) > 0) {
4225#if !defined(MONGOOSE_NO_CGI)
4226    open_cgi_endpoint(conn, path);
4227#else
4228    send_http_error(conn, 501, NULL);
4229#endif // !MONGOOSE_NO_CGI
4230#ifndef MONGOOSE_NO_SSI
4231  } else if (mg_match_prefix(conn->server->config_options[SSI_PATTERN],
4232                             strlen(conn->server->config_options[SSI_PATTERN]),
4233                             path) > 0) {
4234    handle_ssi_request(conn, path);
4235#endif
4236  } else if (is_not_modified(conn, &st)) {
4237    send_http_error(conn, 304, NULL);
4238  } else if ((conn->endpoint.fd = open(path, O_RDONLY | O_BINARY)) != -1) {
4239    // O_BINARY is required for Windows, otherwise in default text mode
4240    // two bytes \r\n will be read as one.
4241    open_file_endpoint(conn, path, &st);
42424257  } else {
4243    send_http_error(conn, 404, NULL);
4258    mg_send_file(&conn->mg_conn, path);
42444259  }
42454260#endif  // MONGOOSE_NO_FILESYSTEM
42464261}
r30821r30822
44964511
44974512static void transfer_file_data(struct connection *conn) {
44984513  char buf[IOBUF_SIZE];
4499  int n = read(conn->endpoint.fd, buf, conn->cl < (int64_t) sizeof(buf) ?
4500               (int) conn->cl : (int) sizeof(buf));
4514  int n;
45014515
4516  // If output buffer is too big, don't send anything. Wait until
4517  // mongoose drains already buffered data to the client.
4518  if (conn->ns_conn->send_iobuf.len > sizeof(buf) * 2) return;
4519
4520  // Do not send anyt
4521  n = read(conn->endpoint.fd, buf, conn->cl < (int64_t) sizeof(buf) ?
4522           (int) conn->cl : (int) sizeof(buf));
4523
45024524  if (n <= 0) {
45034525    close_local_endpoint(conn);
45044526  } else if (n > 0) {
trunk/src/lib/web/mongoose.h
r30821r30822
9999// Connection management functions
100100void mg_send_status(struct mg_connection *, int status_code);
101101void mg_send_header(struct mg_connection *, const char *name, const char *val);
102void mg_send_data(struct mg_connection *, const void *data, int data_len);
103void mg_printf_data(struct mg_connection *, const char *format, ...);
102size_t mg_send_data(struct mg_connection *, const void *data, int data_len);
103size_t mg_printf_data(struct mg_connection *, const char *format, ...);
104size_t mg_write(struct mg_connection *, const void *buf, int len);
105size_t mg_printf(struct mg_connection *conn, const char *fmt, ...);
104106
105int mg_websocket_write(struct mg_connection *, int opcode,
106                       const char *data, size_t data_len);
107int mg_websocket_printf(struct mg_connection* conn, int opcode,
108                        const char *fmt, ...);
107size_t mg_websocket_write(struct mg_connection *, int opcode,
108                          const char *data, size_t data_len);
109size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
110                           const char *fmt, ...);
111                           
112void mg_send_file(struct mg_connection *, const char *path);
109113
110// Deprecated in favor of mg_send_* interface
111int mg_write(struct mg_connection *, const void *buf, int len);
112int mg_printf(struct mg_connection *conn, const char *fmt, ...);
113
114114const char *mg_get_header(const struct mg_connection *, const char *name);
115115const char *mg_get_mime_type(const char *name, const char *default_mime_type);
116116int mg_get_var(const struct mg_connection *conn, const char *var_name,
trunk/web/index.html
r30821r30822
187187
188188         // Now, actually update the status bar..
189189         updateStatusBar('',statusbar_ispaused.join(''),statusbar_runningdriver.join(''));
190         takeScreenshot();
190191        },
191192        error: function (request, status, error) { alert(status + ", " + error); }
192193      });   

Previous 199869 Revisions Next


© 1997-2024 The MAME Team