mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23141c2fef | ||
|
|
c8ba652f1c | ||
|
|
6ac2fa2ae6 | ||
|
|
0322ec5647 | ||
|
|
a5223a9850 | ||
|
|
016968ada1 | ||
|
|
710b888122 | ||
|
|
cf53959f34 | ||
|
|
30d29fb77f | ||
|
|
c05b51bbfc | ||
|
|
1ab704ac92 | ||
|
|
2bc77e065c | ||
|
|
790daabf7d | ||
|
|
a6598a1278 | ||
|
|
0af5502b74 | ||
|
|
f059e41cac | ||
|
|
2cce91de9a | ||
|
|
0ff5b5b044 | ||
|
|
0c5d9a98c2 | ||
|
|
c9fbdfc1b5 | ||
|
|
6193b5171c | ||
|
|
911115ccc0 | ||
|
|
2f3ddeccc5 | ||
|
|
ca3f5a3257 | ||
|
|
df206bc05a | ||
|
|
531fec34fd | ||
|
|
4c10d1f356 | ||
|
|
94dccdd6f4 | ||
|
|
544352b7d3 | ||
|
|
29c2ae4886 | ||
|
|
1a2e2ec2fd | ||
|
|
3e780d21fc | ||
|
|
63fcea0159 | ||
|
|
e5d21225be | ||
|
|
0c9caf3120 | ||
|
|
54ba36c1c9 | ||
|
|
5077350589 | ||
|
|
2d880c4f5c | ||
|
|
4ca4c862a5 | ||
|
|
0918df1566 | ||
|
|
aa2583cc26 | ||
|
|
e1b1d39635 | ||
|
|
3bf82dd541 | ||
|
|
2896965c97 | ||
|
|
53b784b143 | ||
|
|
8e91e3a305 | ||
|
|
dbc07c8b00 | ||
|
|
ce953575e2 | ||
|
|
80db048578 | ||
|
|
382d165574 | ||
|
|
0fb2f38cb7 | ||
|
|
aa007f1285 | ||
|
|
8752910330 | ||
|
|
2a5a8eec49 | ||
|
|
ceca52de30 | ||
|
|
8a3691055c | ||
|
|
56d12c89da | ||
|
|
2cfce4d8b2 | ||
|
|
f372faf614 | ||
|
|
882f3b3ac3 | ||
|
|
fac0e9b0ac | ||
|
|
a3cf67c380 | ||
|
|
2987cbdb5c | ||
|
|
6083b9c5c5 | ||
|
|
83237a02d9 | ||
|
|
965188bac9 | ||
|
|
66da41d401 | ||
|
|
cfd334ac6c | ||
|
|
b5f6254c1e | ||
|
|
dcbd1cbbd1 | ||
|
|
a3b568f460 | ||
|
|
75770aec80 | ||
|
|
3a8ae7ac17 | ||
|
|
b116b2fa82 | ||
|
|
7806609773 | ||
|
|
72f45aa7e2 | ||
|
|
5e3e6a6dce | ||
|
|
1388bb1db4 | ||
|
|
3cc0d16f65 | ||
|
|
b50095fa61 | ||
|
|
7ad85219d8 | ||
|
|
347a249d10 | ||
|
|
07d982129a | ||
|
|
73f2602ba0 | ||
|
|
44561d163a | ||
|
|
c941a1a39a | ||
|
|
bee22312bc | ||
|
|
bdb16c624c | ||
|
|
e389e70d05 | ||
|
|
695559f691 | ||
|
|
13be74b4c6 | ||
|
|
02a1032fd4 | ||
|
|
788f35b19c | ||
|
|
3721efe1e9 | ||
|
|
e0822ffb78 | ||
|
|
ae7d5a8f94 | ||
|
|
ced7a2e0b5 | ||
|
|
5ed6708468 | ||
|
|
9fe53f307b | ||
|
|
c64d30e1f6 | ||
|
|
b4c25fc7ba | ||
|
|
b67b618811 | ||
|
|
5a19438f70 | ||
|
|
860addf1e3 | ||
|
|
03d571a119 | ||
|
|
0d9ecffc53 | ||
|
|
d4c8384b85 | ||
|
|
bd40145301 | ||
|
|
9b42494316 | ||
|
|
2daff6959f | ||
|
|
e9c434a6a1 | ||
|
|
d6fba7e45d | ||
|
|
0a0130b90c | ||
|
|
facf2af66e | ||
|
|
cc54195f59 | ||
|
|
e2fb707d9f | ||
|
|
7dfff935d6 | ||
|
|
5727a5c0ed |
No files matched your search
+20
@@ -0,0 +1,20 @@
|
|||||||
|
language: cpp
|
||||||
|
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- MONGOOSE_NO_SOCKETPAIR
|
||||||
|
- MONGOOSE_NO_FILESYSTEM
|
||||||
|
- MONGOOSE_NO_AUTH
|
||||||
|
- MONGOOSE_NO_DAV
|
||||||
|
- MONGOOSE_NO_DIRECTORY_LISTING
|
||||||
|
- MONGOOSE_NO_LOGGING
|
||||||
|
- MONGOOSE_NO_SSI
|
||||||
|
- MONGOOSE_NO_DL
|
||||||
|
- MONGOOSE_NO_WEBSOCKET
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd test && make
|
||||||
File renamed without changes.
+4
-3
@@ -43,7 +43,7 @@ allowed to call `mg_set_option()` by the same thread that does
|
|||||||
`mg_poll_server()` (Mongoose thread) and change server configuration while it
|
`mg_poll_server()` (Mongoose thread) and change server configuration while it
|
||||||
is serving, in between `mg_poll_server()` calls.
|
is serving, in between `mg_poll_server()` calls.
|
||||||
|
|
||||||
void mg_poll_server(struct mg_server *server, int milliseconds);
|
int mg_poll_server(struct mg_server *server, int milliseconds);
|
||||||
|
|
||||||
Performs one iteration of IO loop by iterating over all
|
Performs one iteration of IO loop by iterating over all
|
||||||
active connections, performing `select()` syscall on all sockets with a timeout
|
active connections, performing `select()` syscall on all sockets with a timeout
|
||||||
@@ -121,6 +121,8 @@ of the websocket frame which URI handler can examine. Note that to
|
|||||||
reply to the websocket client, `mg_websocket_write()` should be used.
|
reply to the websocket client, `mg_websocket_write()` should be used.
|
||||||
To reply to the plain HTTP client, `mg_write_data()` should be used.
|
To reply to the plain HTTP client, `mg_write_data()` should be used.
|
||||||
|
|
||||||
|
Return value: number of active connections.
|
||||||
|
|
||||||
|
|
||||||
const char **mg_get_valid_option_names(void);
|
const char **mg_get_valid_option_names(void);
|
||||||
|
|
||||||
@@ -220,8 +222,7 @@ the length of the fetched value, or 0 if variable not found.
|
|||||||
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.
|
||||||
cookie-based way please refer to the examples/chat.c 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: 1 on success, 0 on error.
|
Return: 1 on success, 0 on error.
|
||||||
|
|||||||
+3
-11
@@ -123,17 +123,9 @@ http://127.0.0.1:8080/hello will say hello, and here's the code:
|
|||||||
|
|
||||||
## Example code
|
## Example code
|
||||||
|
|
||||||
Mongoose source code contains a well-commented example code, listed below:
|
Mongoose source code contains number of examples, located in the
|
||||||
|
[examples](https://github.com/cesanta/mongoose/blob/master/examples/) directory.
|
||||||
* [hello.c](https://github.com/cesanta/mongoose/blob/master/examples/hello.c)
|
To build any example, go to the respective directory and run `make`.
|
||||||
a minimalistic hello world example
|
|
||||||
* [post.c](https://github.com/cesanta/mongoose/blob/master/examples/post.c)
|
|
||||||
shows how to handle form input
|
|
||||||
* [upload.c](https://github.com/cesanta/mongoose/blob/master/examples/post.c)
|
|
||||||
shows how to upload files
|
|
||||||
* [websocket.c](https://github.com/cesanta/mongoose/blob/master/examples/websocket.c) demonstrates websocket usage
|
|
||||||
* [auth.c](https://github.com/cesanta/mongoose/blob/master/examples/auth.c) demonstrates API-controlled Digest authorization
|
|
||||||
* [mjpg.c](https://github.com/cesanta/mongoose/blob/master/examples/mjpg.c) demonstrates MJPEG streaming implementation
|
|
||||||
|
|
||||||
## Compilation flags
|
## Compilation flags
|
||||||
|
|
||||||
|
|||||||
+13
-7
@@ -69,6 +69,11 @@ A directory to serve. Default: current working directory.
|
|||||||
### enable\_directory\_listing
|
### enable\_directory\_listing
|
||||||
Enable directory listing, either `yes` or `no`. Default: `yes`.
|
Enable directory listing, either `yes` or `no`. Default: `yes`.
|
||||||
|
|
||||||
|
### enable\_proxy
|
||||||
|
Enable proxy functionality, either `yes` or `no`. If set to `yes`, then
|
||||||
|
browsers can be configured to use Mongoose as a proxy. Default: `no`.
|
||||||
|
|
||||||
|
|
||||||
### extra\_mime\_types
|
### extra\_mime\_types
|
||||||
Extra mime types to recognize, in form `extension1=type1,extension2=type2,...`.
|
Extra mime types to recognize, in form `extension1=type1,extension2=type2,...`.
|
||||||
Extension must include dot. Example:
|
Extension must include dot. Example:
|
||||||
@@ -94,16 +99,17 @@ not set.
|
|||||||
Comma-separated list of files to be treated as directory index
|
Comma-separated list of files to be treated as directory index
|
||||||
files. Default: `index.html,index.htm,index.cgi,index.shtml,index.php`
|
files. Default: `index.html,index.htm,index.cgi,index.shtml,index.php`
|
||||||
|
|
||||||
### ssl_certificate
|
|
||||||
Path to SSL certificate file. The file must be in PEM format,
|
|
||||||
and it must have both private key and certificate, see for example
|
|
||||||
[ssl_cert.pem](https://github.com/cesanta/mongoose/blob/master/build/ssl_cert.pem). If this option is set, then Mongoose serves SSL connections on
|
|
||||||
`listening_port`. Default: not set.
|
|
||||||
|
|
||||||
### listening_port
|
### listening_port
|
||||||
Port to listen on. Port could be prepended by the specific IP address to bind
|
Port to listen on. Port could be prepended by the specific IP address to bind
|
||||||
to, e.g. `mongoose -listening_port 127.0.0.1:8080`. Otherwise Mongoose
|
to, e.g. `mongoose -listening_port 127.0.0.1:8080`. Otherwise Mongoose
|
||||||
will bind to all addresses. Default: 8080.
|
will bind to all addresses. To enable SSL, build Mongoose with
|
||||||
|
`-DNS_ENABLE_SSL` compilation option, and specify `listening_port` as
|
||||||
|
`ssl://PORT:SSL_CERTIFICATE.PEM`. Example SSL listener:
|
||||||
|
`mongoose -listening_port ssl://8043:ssl_cert.pem`. Note that PEM file should
|
||||||
|
be in PEM format, and must have both certificate and private key in it,
|
||||||
|
concatenated together. More than one listening port can be specified,
|
||||||
|
separated by comma,
|
||||||
|
for example `mongoose -listening_port 8080,8000`. Default: 8080.
|
||||||
|
|
||||||
### run\_as\_user
|
### run\_as\_user
|
||||||
Switch to given user credentials after startup. UNIX-only. This option is
|
Switch to given user credentials after startup. UNIX-only. This option is
|
||||||
|
|||||||
@@ -1,5 +1,30 @@
|
|||||||
# Mongoose Release Notes
|
# Mongoose Release Notes
|
||||||
|
|
||||||
|
## Release 5.5, October 28 2014
|
||||||
|
|
||||||
|
Changes in Libmongoose library:
|
||||||
|
|
||||||
|
- Added new API function: `mg_forward()` for proxying functionality
|
||||||
|
- Added new API function: `mg_send_file_data()` for sending file data
|
||||||
|
- Added new utility API functions: `mg_mmap() and mg_munpap()`
|
||||||
|
- Changed the way SSL settings are handled: removed `ssl_certificate` and
|
||||||
|
`ssl_ca_certificate` options, and instead made `listening_port` accept
|
||||||
|
`ssl://PORT:SSL_CERT:CA_CERT` notation
|
||||||
|
- Added ability to listen on multiple ports, see `listening_port` documentation
|
||||||
|
- Added `enable_proxy` option
|
||||||
|
- Added [cookie_authentication](https://github.com/cesanta/mongoose/tree/master/examples/cookie_authentication) example
|
||||||
|
- Added [websocket\_ssl\_proxy](https://github.com/cesanta/mongoose/tree/master/examples/websocket_ssl_proxy) example
|
||||||
|
- Added [http_client](https://github.com/cesanta/mongoose/tree/master/examples/http_client) example
|
||||||
|
- Increased default 'idle connection' timeout from 30 to 300 seconds
|
||||||
|
- Fixed MinGW build
|
||||||
|
- Refactored all examples, put each in it's own directory with dedicated build
|
||||||
|
- Many smaller bugfixed, including SSL, CGI, API, proxy, etc
|
||||||
|
|
||||||
|
Changes in pre-compiled binaries:
|
||||||
|
|
||||||
|
- Support for multiple listening ports
|
||||||
|
- Fixed CGI handling for scripts that specify interpreter in the hashbang line
|
||||||
|
|
||||||
## Release 5.4, July 28 2014
|
## Release 5.4, July 28 2014
|
||||||
|
|
||||||
Changes in Libmongoose library:
|
Changes in Libmongoose library:
|
||||||
|
|||||||
+9
-72
@@ -1,78 +1,15 @@
|
|||||||
CFLAGS = -W -Wall -I.. -pthread -g -pipe $(CFLAGS_EXTRA)
|
# Copyright (c) 2014 Cesanta Software
|
||||||
RM = rm -rf
|
# All rights reserved
|
||||||
OUT = -o $@
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
SUBDIRS = $(sort $(filter-out csharp/, $(dir $(wildcard */))))
|
||||||
MSVC = ../../vc6
|
X = $(SUBDIRS)
|
||||||
RM = del /q /f
|
|
||||||
OUT =
|
|
||||||
CC = $(MSVC)/bin/cl
|
|
||||||
CFLAGS = /MD /TC /nologo /W3 /I$(MSVC)/include /I..
|
|
||||||
CFLAGS += /link /incremental:no /libpath:$(MSVC)/lib /machine:IX86
|
|
||||||
CFLAGS += $(CFLAGS_EXTRA)
|
|
||||||
else
|
|
||||||
UNAME_S := $(shell uname -s)
|
|
||||||
CC = g++
|
|
||||||
CFLAGS += -lssl -g -O0
|
|
||||||
|
|
||||||
ifeq ($(UNAME_S),Linux)
|
.PHONY: $(SUBDIRS)
|
||||||
CFLAGS += -ldl
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
all: $(SUBDIRS)
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: hello websocket server post multi_threaded upload auth
|
$(SUBDIRS):
|
||||||
|
@$(MAKE) -C $@
|
||||||
# To enable Lua in a server, uncomment following lines
|
|
||||||
LUA = ../lua-5.2.3/src
|
|
||||||
#CFLAGS += -I$(LUA) -L$(LUA) -llua -DMONGOOSE_USE_LUA
|
|
||||||
|
|
||||||
server: server.c ../mongoose.c
|
|
||||||
$(CC) server.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
hello: hello.c ../mongoose.c
|
|
||||||
$(CC) hello.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
websocket: websocket_html.c websocket.c ../mongoose.c
|
|
||||||
$(CC) websocket.c websocket_html.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
post: post.c ../mongoose.c
|
|
||||||
$(CC) post.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
multi_threaded: multi_threaded.c ../mongoose.c
|
|
||||||
$(CC) multi_threaded.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
upload: upload.c ../mongoose.c
|
|
||||||
$(CC) upload.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
auth: auth.c ../mongoose.c
|
|
||||||
$(CC) auth.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
file: file.c ../mongoose.c
|
|
||||||
$(CC) file.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
form: form.c ../mongoose.c
|
|
||||||
$(CC) form.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
mjpg: mjpg.c ../mongoose.c
|
|
||||||
$(CC) mjpg.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
pubsub: websocket2.c ../mongoose.c
|
|
||||||
$(CC) websocket2.c ../mongoose.c $(OUT) $(CFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
proxy: proxy.c ../mongoose.c
|
|
||||||
$(CC) proxy.c ../mongoose.c $(OUT) \
|
|
||||||
-I../../net_skeleton -DNS_ENABLE_SSL -lssl $(CFLAGS)
|
|
||||||
|
|
||||||
websocket_html.c: websocket.html
|
|
||||||
perl mkdata.pl $< > $@
|
|
||||||
|
|
||||||
u:
|
|
||||||
$(CC) unit_test.c $(OUT) $(CFLAGS)
|
|
||||||
./$@
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-@$(RM) hello mjpg upload post websocket auth file server multi_threaded proxy websocket_html.c *.exe *.dSYM *.obj .*o u a.out
|
for d in $(SUBDIRS) ; do $(MAKE) -C $$d clean ; done
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
struct file_data {
|
|
||||||
FILE *fp;
|
|
||||||
const char *data;
|
|
||||||
int data_len;
|
|
||||||
int written;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int handle_request(struct mg_connection *conn) {
|
|
||||||
const char *data;
|
|
||||||
int data_len;
|
|
||||||
char var_name[100], file_name[100], path[100];
|
|
||||||
|
|
||||||
if (strcmp(conn->uri, "/upload") == 0) {
|
|
||||||
if (mg_parse_multipart(conn->content, conn->content_len,
|
|
||||||
var_name, sizeof(var_name),
|
|
||||||
file_name, sizeof(file_name),
|
|
||||||
&data, &data_len) > 0) {
|
|
||||||
struct file_data *p = (struct file_data *) malloc(sizeof(*p));
|
|
||||||
snprintf(path, sizeof(path), "UPLOAD_%s", file_name);
|
|
||||||
p->fp = fopen(path, "wb");
|
|
||||||
p->data = data;
|
|
||||||
p->data_len = data_len;
|
|
||||||
p->written = 0;
|
|
||||||
conn->connection_param = p;
|
|
||||||
mg_send_header(conn, "Content-Type", "text/html");
|
|
||||||
}
|
|
||||||
return MG_MORE; // Tell mongoose to keep this connection open
|
|
||||||
} else {
|
|
||||||
mg_printf_data(conn, "%s",
|
|
||||||
"<html><body>Upload example."
|
|
||||||
"<form method=\"POST\" action=\"/upload\" "
|
|
||||||
" enctype=\"multipart/form-data\">"
|
|
||||||
"<input type=\"file\" name=\"file\" /> <br/>"
|
|
||||||
"<input type=\"submit\" value=\"Upload\" />"
|
|
||||||
"</form></body></html>");
|
|
||||||
return MG_TRUE; // Tell mongoose to close this connection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int handle_poll(struct mg_connection *conn) {
|
|
||||||
struct file_data *p = (struct file_data *) conn->connection_param;
|
|
||||||
if (p != NULL) {
|
|
||||||
// Write no more then 100 bytes in one go
|
|
||||||
int len = p->data_len - p->written;
|
|
||||||
int n = fwrite(p->data + p->written, 1, len > 100 ? 100 : len, p->fp);
|
|
||||||
if (n > 0) {
|
|
||||||
p->written += n;
|
|
||||||
mg_send_data(conn, " ", 1); // Send something back to wake up select()
|
|
||||||
}
|
|
||||||
|
|
||||||
// If everything is written, close the connection
|
|
||||||
if (p->written >= p->data_len) {
|
|
||||||
mg_printf_data(conn, "Written %d bytes.", p->written);
|
|
||||||
fclose(p->fp);
|
|
||||||
free(p);
|
|
||||||
conn->connection_param = NULL;
|
|
||||||
return MG_TRUE; // Tell mongoose to close this connection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MG_FALSE; // Tell mongoose to keep this connection open
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
|
||||||
switch (ev) {
|
|
||||||
case MG_AUTH: return MG_TRUE;
|
|
||||||
case MG_REQUEST: return handle_request(conn);
|
|
||||||
case MG_POLL: return handle_poll(conn);
|
|
||||||
default: return MG_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_server *server = mg_create_server(NULL, ev_handler);
|
|
||||||
mg_set_option(server, "listening_port", "8080");
|
|
||||||
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
mg_poll_server(server, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
mg_destroy_server(&server);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = big_upload
|
||||||
|
CFLAGS = -W -Wall -pthread -I../.. -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static int handle_request(struct mg_connection *conn) {
|
||||||
|
if (strcmp(conn->uri, "/upload") == 0) {
|
||||||
|
FILE *fp = (FILE *) conn->connection_param;
|
||||||
|
if (fp != NULL) {
|
||||||
|
fwrite(conn->content, 1, conn->content_len, fp); // Write last bits
|
||||||
|
mg_printf(conn, "HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Type: text/plain\r\n"
|
||||||
|
"Connection: close\r\n\r\n"
|
||||||
|
"Written %ld of POST data to a temp file:\n\n",
|
||||||
|
(long) ftell(fp));
|
||||||
|
|
||||||
|
// Temp file will be destroyed after fclose(), do something with the
|
||||||
|
// data here -- for example, parse it and extract uploaded files.
|
||||||
|
// As an example, we just echo the whole POST buffer back to the client.
|
||||||
|
rewind(fp);
|
||||||
|
mg_send_file_data(conn, fileno(fp));
|
||||||
|
return MG_MORE; // Tell Mongoose reply is not completed yet
|
||||||
|
} else {
|
||||||
|
mg_printf_data(conn, "%s", "Had no data to write...");
|
||||||
|
return MG_TRUE; // Tell Mongoose we're done with this request
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mg_printf_data(conn, "%s",
|
||||||
|
"<html><body>Upload example."
|
||||||
|
"<form method=\"POST\" action=\"/upload\" "
|
||||||
|
" enctype=\"multipart/form-data\">"
|
||||||
|
"<input type=\"file\" name=\"file\" /> <br/>"
|
||||||
|
"<input type=\"submit\" value=\"Upload\" />"
|
||||||
|
"</form></body></html>");
|
||||||
|
return MG_TRUE; // Tell mongoose to close this connection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mongoose sends MG_RECV for every received POST chunk.
|
||||||
|
// When last POST chunk is received, Mongoose sends MG_REQUEST, then MG_CLOSE.
|
||||||
|
static int handle_recv(struct mg_connection *conn) {
|
||||||
|
FILE *fp = (FILE *) conn->connection_param;
|
||||||
|
|
||||||
|
// Open temporary file where we going to write data
|
||||||
|
if (fp == NULL && ((conn->connection_param = fp = tmpfile())) == NULL) {
|
||||||
|
return -1; // Close connection on error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return number of bytes written to a temporary file: that is how many
|
||||||
|
// bytes we want to discard from the receive buffer
|
||||||
|
return fwrite(conn->content, 1, conn->content_len, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we free all allocated resources
|
||||||
|
static int handle_close(struct mg_connection *conn) {
|
||||||
|
if (conn->connection_param != NULL) {
|
||||||
|
fclose((FILE *) conn->connection_param);
|
||||||
|
conn->connection_param = NULL;
|
||||||
|
}
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
switch (ev) {
|
||||||
|
case MG_AUTH: return MG_TRUE;
|
||||||
|
case MG_REQUEST: return handle_request(conn);
|
||||||
|
case MG_RECV: return handle_recv(conn);
|
||||||
|
case MG_CLOSE: return handle_close(conn);
|
||||||
|
default: return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct mg_server *server = mg_create_server(NULL, ev_handler);
|
||||||
|
mg_set_option(server, "listening_port", "8080");
|
||||||
|
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
mg_poll_server(server, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
mg_destroy_server(&server);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEpAIBAAKCAQEA8FV466yTGIUkJqjBv2CTU/HeYKXYd7D6m8fY9daRLm9cKPhB
|
|
||||||
kPvLyhdenOH88uAAYqmKf2dZvP5SxFnBKT52Hr0XpUfC8Y3iVjHxwMgNRaiSkfDP
|
|
||||||
mIEb2qcpJoMrdos/ff46itqwr9wW3+7kjRlxM1Mu5pq4EibSHeVyaPWVCgENcA1m
|
|
||||||
4beQujI1SSBkLOfmgpw/SsyzyTgXm+kOdj7vKy3EbXseGPtHJ04oZ7qwol1NFrrq
|
|
||||||
HwO87HWHxyQr7uJ4TBH37gL7QCdjHsOdN94alxEUWTRfmzZFXVlsTnq5DBnnGhtq
|
|
||||||
ibpUC8WeI3QiFNtTBKkHviAm+6iWW6gG2TO4twIDAQABAoIBAHxLWBxaxkB6KzYr
|
|
||||||
NPirE8boYiAN5aQRTarfcp/B9pfTVBCERDSdZMoByBbO8akSnGBqWoyFgO2zgk62
|
|
||||||
NKYF/cTr+pyqPnH69UGq1uLjE6ohApyjtFmk/CjbJvcaA5JtdcrNfq1taM+qvdHW
|
|
||||||
lTE8JUVsEeeFwQjyNtzrW35Y9FmVLSmMNsESChLnrsa7IxwnfRpHc+hmj+7lxZO6
|
|
||||||
ZzAaCCo9qHR1Ddi5f+0DJoXGBBGOk6C4BWLaV+fHPcsYHESrepitGfS96AQ0Wspn
|
|
||||||
qqtAp6jv+iIfgpohYylIjOPcHf3dXpINTxwz/r3XicqBaSAx2lXb+vnxERmagGKC
|
|
||||||
RUpELVECgYEA/EHUDwJRBUMvGXjRQO9R0JLp59U2UZOvAjmIAHkLM/48k8//kpgJ
|
|
||||||
CDUVvuyQUfwCphmaiAm5BZfDbmhBEirjCai8fYkrGugQl9H1YrVsi+UhQudnSRM0
|
|
||||||
7plKIb9nz9by31J1iu5YHTpovO5MQjH5UP1boqAioBNoBuzFI0QK1uMCgYEA8+Za
|
|
||||||
0NDocnE+V2NpRag+oMbM/LBgSWyk49NXYUOhuv4CZ8f20nFYx6p9RLD0ICUOxC3B
|
|
||||||
TkHybnGhRjuR+LkbuynW2wM2+jwcLe+ZPnXZsNKJwST9fzus06BWHyBTJHfhUDO3
|
|
||||||
cq6PUDJua6NQa++rj+ur1LSFPuwnC+X2FxMd6x0CgYEAweyhZ4ByZMdHWB+nTnIs
|
|
||||||
xVmL9CvW/FO6gM1Vnndvg2L5kvCeG0ZB+0tEEmiucjh4mNSqFdbTpFcNaL1A+QR7
|
|
||||||
UZukfCWNO7wXtX81U9MBRXK6ZUKcBnN7h8nUUalh10f5onEz58BfgOi8SDIx8dmV
|
|
||||||
Pwvm/Fh7BfClUl2HGBtg8d0CgYBEDWwdg4y4EdzhKT3AT9dZqN6dSuEy23uOjfN9
|
|
||||||
kg9YS3OEXYkC4tlwrKNTPUSAi5Z5KoMbQM9R/aaQICL0kUGpkVz/sv/uBkOelZHe
|
|
||||||
madp7PS+zYFltNLeIYimGrDYJhLZ+/QdrZMTP18L7X+M/kySVaGWMeBT1DR432sw
|
|
||||||
uQbKCQKBgQC9D9fxDXCFxJmJc2Cp8ZYQha4Oc10JsanM1DM1YWIaOILfoExz46vZ
|
|
||||||
UJzRfe2LkkhhRN9YG4ZW6zJ1E/HZSjKC2iwHog/4bDjykVPrFIfPdWS2C1CQF/Jq
|
|
||||||
tYnHTpuxE3JFXZrLXbDobFKbxHOZRdlSUu8NK/V507Y34NaMPHnffw==
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIID4DCCAsigAwIBAgIJAM1yCH8CR4Z+MA0GCSqGSIb3DQEBBQUAMFMxFDASBgNV
|
|
||||||
BAMTC2Nlc2FudGEuY29tMR0wGwYDVQQKExRDZXNhbnRhIFNvZnR3YXJlIEx0ZDEL
|
|
||||||
MAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpbjAeFw0xNDA2MjcxMDUwNTBaFw0y
|
|
||||||
NDA2MjQxMDUwNTBaMFMxFDASBgNVBAMTC2Nlc2FudGEuY29tMR0wGwYDVQQKExRD
|
|
||||||
ZXNhbnRhIFNvZnR3YXJlIEx0ZDELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1Ymxp
|
|
||||||
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPBVeOuskxiFJCaowb9g
|
|
||||||
k1Px3mCl2Hew+pvH2PXWkS5vXCj4QZD7y8oXXpzh/PLgAGKpin9nWbz+UsRZwSk+
|
|
||||||
dh69F6VHwvGN4lYx8cDIDUWokpHwz5iBG9qnKSaDK3aLP33+OorasK/cFt/u5I0Z
|
|
||||||
cTNTLuaauBIm0h3lcmj1lQoBDXANZuG3kLoyNUkgZCzn5oKcP0rMs8k4F5vpDnY+
|
|
||||||
7ystxG17Hhj7RydOKGe6sKJdTRa66h8DvOx1h8ckK+7ieEwR9+4C+0AnYx7DnTfe
|
|
||||||
GpcRFFk0X5s2RV1ZbE56uQwZ5xobaom6VAvFniN0IhTbUwSpB74gJvuolluoBtkz
|
|
||||||
uLcCAwEAAaOBtjCBszAdBgNVHQ4EFgQUwvetHY2/J2F788UvFPADTlaUS10wgYMG
|
|
||||||
A1UdIwR8MHqAFML3rR2Nvydhe/PFLxTwA05WlEtdoVekVTBTMRQwEgYDVQQDEwtj
|
|
||||||
ZXNhbnRhLmNvbTEdMBsGA1UEChMUQ2VzYW50YSBTb2Z0d2FyZSBMdGQxCzAJBgNV
|
|
||||||
BAYTAklFMQ8wDQYDVQQHEwZEdWJsaW6CCQDNcgh/AkeGfjAMBgNVHRMEBTADAQH/
|
|
||||||
MA0GCSqGSIb3DQEBBQUAA4IBAQDA3QTlZ2aUe4IIDU+yZmu3XRxJ4FGpOlC0nD1j
|
|
||||||
uwHWDaHfr0WMDjwSoEHbhsc0tapXOpG+hFImHemDS82SuC2c8lNKEJeXgdF3Rqeo
|
|
||||||
aIB8sklgHsJG1DoCwC5TIMaccmbALWctouELGFb8aDF+dczKaaDTW+/dgR47GvD5
|
|
||||||
NBTka2A56U3emmXRpOOtzOz/68lxgACXc+M3yrxbYt9a95rl6wwzNlLHDwPzqhzd
|
|
||||||
ayQ9Q8wmZpWZK1oc8oKKuEXA3zG6jJkrmC8VD5j0WRLgC7SV/zlaAUR/zEisstrh
|
|
||||||
ZVMiJ0NoZmAPVRm0MyBHtBHJFcn/z/FlhqCBLsmDxJ/aOEMT
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_server *server = mg_create_server(NULL);
|
|
||||||
mg_set_option(server, "listening_port", "8080");
|
|
||||||
mg_set_option(server, "document_root", "chat_html_root");
|
|
||||||
|
|
||||||
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
|
||||||
for (;;) {
|
|
||||||
mg_poll_server(server, 1000);
|
|
||||||
}
|
|
||||||
mg_destroy_server(&server);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,73 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
|
|
||||||
<!-- This file is part of the Mongoose project,
|
|
||||||
http://code.google.com/p/mongoose -->
|
|
||||||
<head>
|
|
||||||
<title>Mongoose chat server</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
|
||||||
<link type="text/css" rel="stylesheet" href="style.css"/>
|
|
||||||
<script src="jquery.js"></script>
|
|
||||||
<script src="main.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="header">
|
|
||||||
<div id="logo"></div>
|
|
||||||
<div class="rounded infobox help-message" id="motd">
|
|
||||||
Chat room implemented using
|
|
||||||
<a href="http://code.google.com/p/mongoose" target="_blank">Mongoose</a>
|
|
||||||
embeddable web server.
|
|
||||||
This application was written for educational purposes demonstrating
|
|
||||||
how web interface could be decoupled from the business logic. Not a
|
|
||||||
single line of HTML is generated by the server, instead, server
|
|
||||||
gives data to the client in JSON format.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<div id="middle">
|
|
||||||
<div><center><span id="error" class="rounded"></span><center></div>
|
|
||||||
|
|
||||||
<div id="menu">
|
|
||||||
<div class="menu-item left-rounded menu-item-selected"
|
|
||||||
name="chat">Chat</div>
|
|
||||||
<div class="menu-item left-rounded" name="settings">Settings</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="content" class="rounded">
|
|
||||||
|
|
||||||
<div id="chat" class="main">
|
|
||||||
<div class="chat-window">
|
|
||||||
<span class="top-rounded chat-title">Main room</span>
|
|
||||||
<div class="bottom-rounded chat-content">
|
|
||||||
<div class="message-list" id="mml">
|
|
||||||
</div>
|
|
||||||
<input type="text" size="40" class="message-input"></input>
|
|
||||||
<span class="help-message">
|
|
||||||
Type your message here and press enter</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="settings" class="hidden main">
|
|
||||||
<div>
|
|
||||||
<span class="top-rounded chat-title">Settings</span>
|
|
||||||
<div class="bottom-rounded chat-content">
|
|
||||||
<table>
|
|
||||||
<tr><td>Max messages to display:</td><td>blah blah</td></tr>
|
|
||||||
<tr><td>Text color:</td><td>blah blah</td></tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="footer">
|
|
||||||
Copyright © 2004-2010 by Sergey Lyubka
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
-154
@@ -1,154 +0,0 @@
|
|||||||
/*!
|
|
||||||
* jQuery JavaScript Library v1.4.2
|
|
||||||
* http://jquery.com/
|
|
||||||
*
|
|
||||||
* Copyright 2010, John Resig
|
|
||||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
||||||
* http://jquery.org/license
|
|
||||||
*
|
|
||||||
* Includes Sizzle.js
|
|
||||||
* http://sizzlejs.com/
|
|
||||||
* Copyright 2010, The Dojo Foundation
|
|
||||||
* Released under the MIT, BSD, and GPL Licenses.
|
|
||||||
*
|
|
||||||
* Date: Sat Feb 13 22:33:48 2010 -0500
|
|
||||||
*/
|
|
||||||
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
|
|
||||||
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
|
|
||||||
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
|
|
||||||
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
|
|
||||||
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
|
|
||||||
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
|
|
||||||
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
|
|
||||||
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
|
|
||||||
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
|
|
||||||
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
|
|
||||||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
|
|
||||||
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
|
|
||||||
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
|
|
||||||
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
|
|
||||||
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
|
|
||||||
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
|
|
||||||
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
|
|
||||||
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
|
|
||||||
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
|
|
||||||
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
|
|
||||||
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
|
|
||||||
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
|
|
||||||
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
|
|
||||||
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
|
|
||||||
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
|
|
||||||
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
|
|
||||||
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
|
|
||||||
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
|
|
||||||
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
|
|
||||||
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
|
|
||||||
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
|
|
||||||
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
|
|
||||||
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
|
|
||||||
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
|
|
||||||
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
|
|
||||||
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
|
|
||||||
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
|
|
||||||
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
|
|
||||||
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
|
|
||||||
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
|
||||||
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
|
|
||||||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
|
|
||||||
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
|
|
||||||
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
|
|
||||||
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
|
|
||||||
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
|
|
||||||
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
|
|
||||||
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
|
|
||||||
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
|
|
||||||
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
|
|
||||||
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
|
|
||||||
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
|
|
||||||
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
|
|
||||||
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
|
|
||||||
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
|
||||||
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
|
|
||||||
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
|
|
||||||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
|
|
||||||
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
|
|
||||||
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
|
||||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
|
||||||
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
|
|
||||||
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
|
|
||||||
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
|
||||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
|
|
||||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
|
||||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
|
||||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
|
|
||||||
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
|
|
||||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
|
||||||
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
|
|
||||||
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
|
|
||||||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
|
|
||||||
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
|
|
||||||
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
|
|
||||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
|
|
||||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
|
|
||||||
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
|
|
||||||
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
|
||||||
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
|
|
||||||
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
|
|
||||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
|
||||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
|
||||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
|
|
||||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
|
|
||||||
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
|
|
||||||
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
|
||||||
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
|
|
||||||
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
|
|
||||||
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
|
|
||||||
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
|
|
||||||
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
|
||||||
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
|
|
||||||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
|
|
||||||
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
|
|
||||||
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
|
|
||||||
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
|
|
||||||
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
|
|
||||||
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
|
|
||||||
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
|
|
||||||
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
|
|
||||||
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
|
|
||||||
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
|
|
||||||
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
|
|
||||||
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
|
|
||||||
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
|
|
||||||
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
|
|
||||||
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
|
|
||||||
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
|
|
||||||
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
|
|
||||||
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
|
|
||||||
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
|
|
||||||
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
|
|
||||||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
|
|
||||||
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
|
|
||||||
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
|
|
||||||
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
|
|
||||||
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
|
|
||||||
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
|
|
||||||
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
|
|
||||||
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
|
|
||||||
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
|
|
||||||
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
|
|
||||||
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
|
|
||||||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
|
|
||||||
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
|
|
||||||
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
|
|
||||||
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
|
|
||||||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
|
|
||||||
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
|
|
||||||
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
|
|
||||||
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
|
|
||||||
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
|
|
||||||
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
|
|
||||||
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
|
|
||||||
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
|
|
||||||
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
|
|
||||||
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
|
|
||||||
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
|
|
||||||
<!-- This file is part of the Mongoose project,
|
|
||||||
http://code.google.com/p/mongoose -->
|
|
||||||
<head>
|
|
||||||
<title>Mongoose chat: login</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
|
||||||
<!--
|
|
||||||
Note that this page is self-sufficient, it does not load any other
|
|
||||||
CSS or Javascript file. This is done so because only this page is
|
|
||||||
allowed for non-authorized users. If we want to load other files
|
|
||||||
from the frontend, we need to change backend code to allow those
|
|
||||||
for non-authorized users. See chat.c :: must_authorize() function.
|
|
||||||
-->
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
window.onload = function() {
|
|
||||||
// Set correct action for the login form. We assume that the SSL port
|
|
||||||
// is the next one to insecure one.
|
|
||||||
var httpsPort = location.protocol.match(/https/) ? location.port :
|
|
||||||
parseInt(location.port) + 1;
|
|
||||||
document.forms[0].action = 'https://' + location.hostname + ':' +
|
|
||||||
httpsPort + '/authorize';
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<center>
|
|
||||||
<h2>Mongoose chat server login</h2>
|
|
||||||
<div style="max-width: 30em;">
|
|
||||||
Username and password can be any non-empty strings.
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
<form>
|
|
||||||
<input type="text" name="user"></input><br/>
|
|
||||||
<input type="text" name="password"></input><br/>
|
|
||||||
<input type="submit" value="Login"></input>
|
|
||||||
</form>
|
|
||||||
</center>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,106 +0,0 @@
|
|||||||
// This file is part of Mongoose project, http://code.google.com/p/mongoose
|
|
||||||
|
|
||||||
var chat = {
|
|
||||||
// Backend URL, string.
|
|
||||||
// 'http://backend.address.com' or '' if backend is the same as frontend
|
|
||||||
backendUrl: 'api.lp',
|
|
||||||
maxVisibleMessages: 10,
|
|
||||||
errorMessageFadeOutTimeoutMs: 2000,
|
|
||||||
errorMessageFadeOutTimer: null,
|
|
||||||
lastMessageId: 0,
|
|
||||||
getMessagesIntervalMs: 1000,
|
|
||||||
};
|
|
||||||
|
|
||||||
chat.normalizeText = function(text) {
|
|
||||||
return text.replace('<', '<').replace('>', '>');
|
|
||||||
};
|
|
||||||
|
|
||||||
chat.refresh = function(data) {
|
|
||||||
|
|
||||||
if (data === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.each(data, function(index, entry) {
|
|
||||||
var row = $('<div>').addClass('message-row').appendTo('#mml');
|
|
||||||
var timestamp = (new Date(entry.timestamp * 1000)).toLocaleTimeString();
|
|
||||||
$('<span>')
|
|
||||||
.addClass('message-timestamp')
|
|
||||||
.html('[' + timestamp + ']')
|
|
||||||
.prependTo(row);
|
|
||||||
$('<span>')
|
|
||||||
.addClass('message-user')
|
|
||||||
.addClass(entry.user ? '' : 'message-user-server')
|
|
||||||
.html(chat.normalizeText((entry.user || '[server]') + ':'))
|
|
||||||
.appendTo(row);
|
|
||||||
$('<span>')
|
|
||||||
.addClass('message-text')
|
|
||||||
.addClass(entry.user ? '' : 'message-text-server')
|
|
||||||
.html(chat.normalizeText(entry.text))
|
|
||||||
.appendTo(row);
|
|
||||||
chat.lastMessageId = Math.max(chat.lastMessageId, entry.id) + 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Keep only chat.maxVisibleMessages, delete older ones.
|
|
||||||
while ($('#mml').children().length > chat.maxVisibleMessages) {
|
|
||||||
$('#mml div:first-child').remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
chat.getMessages = function(enter_loop) {
|
|
||||||
$.ajax({
|
|
||||||
data: {last_id: chat.lastMessageId, cmd: 'get_messages'},
|
|
||||||
success: chat.refresh,
|
|
||||||
error: function() {
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (enter_loop) {
|
|
||||||
window.setTimeout('chat.getMessages(true)', chat.getMessagesIntervalMs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
chat.handleMenuItemClick = function(ev) {
|
|
||||||
$('.menu-item').removeClass('menu-item-selected'); // Deselect menu buttons
|
|
||||||
$(this).addClass('menu-item-selected'); // Select clicked button
|
|
||||||
$('.main').addClass('hidden'); // Hide all main windows
|
|
||||||
$('#' + $(this).attr('name')).removeClass('hidden'); // Show main window
|
|
||||||
};
|
|
||||||
|
|
||||||
chat.showError = function(message) {
|
|
||||||
$('#error').html(message).fadeIn('fast');
|
|
||||||
window.clearTimeout(chat.errorMessageFadeOutTimer);
|
|
||||||
chat.errorMessageFadeOutTimer = window.setTimeout(function() {
|
|
||||||
$('#error').fadeOut('slow');
|
|
||||||
}, chat.errorMessageFadeOutTimeoutMs);
|
|
||||||
};
|
|
||||||
|
|
||||||
chat.handleMessageInput = function(ev) {
|
|
||||||
var input = ev.target;
|
|
||||||
if (ev.keyCode != 13 || !input.value)
|
|
||||||
return;
|
|
||||||
//input.disabled = true;
|
|
||||||
$.ajax({
|
|
||||||
data: { text: input.value, cmd: 'send_message' },
|
|
||||||
success: function(ev) {
|
|
||||||
input.value = '';
|
|
||||||
input.disabled = false;
|
|
||||||
chat.getMessages(false);
|
|
||||||
},
|
|
||||||
error: function(ev) {
|
|
||||||
chat.showError('Error sending message');
|
|
||||||
input.disabled = false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
$.ajaxSetup({
|
|
||||||
dataType: 'json',
|
|
||||||
url: chat.backendUrl
|
|
||||||
});
|
|
||||||
$('.menu-item').click(chat.handleMenuItemClick);
|
|
||||||
$('.message-input').keypress(chat.handleMessageInput);
|
|
||||||
chat.getMessages(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
// vim:ts=2:sw=2:et
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* vim:ts=2:sw=2:et:ai
|
|
||||||
*/
|
|
||||||
|
|
||||||
body {
|
|
||||||
font: 13px Arial; margin: 0.5em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo {
|
|
||||||
background: url('logo.png') no-repeat ;
|
|
||||||
width: 160px;
|
|
||||||
height: 40px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
#motd {
|
|
||||||
margin-left: 170px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.infobox {
|
|
||||||
background: #eed;
|
|
||||||
padding: 1px 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.help-message {
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
#middle {
|
|
||||||
margin: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#error {
|
|
||||||
background: #c44;
|
|
||||||
color: white;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content, .menu-item-selected, .chat-title, .chat-content {
|
|
||||||
background: #c3d9ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
overflow: hidden;
|
|
||||||
min-height: 7em;
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-title {
|
|
||||||
padding: 1px 1ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
padding: 1ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-window {
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-row {
|
|
||||||
margin: 2px;
|
|
||||||
border-bottom: 1px solid #bbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-timestamp {
|
|
||||||
color: #484;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-user {
|
|
||||||
margin-left: 0.5em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-text {
|
|
||||||
margin-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-user-server {
|
|
||||||
color: purple;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-text-server {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
padding: 0.5em;
|
|
||||||
background: #f0fcff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#menu {
|
|
||||||
margin-top: 1em;
|
|
||||||
min-width: 7em;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
#footer {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
color: #ccc;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0.1em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item-selected {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-list {
|
|
||||||
min-height: 1em;
|
|
||||||
background: white;
|
|
||||||
margin: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded {
|
|
||||||
border-radius: 6px;
|
|
||||||
-moz-border-radius: 6px;
|
|
||||||
-webkit-border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-rounded {
|
|
||||||
border-radius: 6px 0 0 6px;
|
|
||||||
-moz-border-radius: 6px 0 0 6px;
|
|
||||||
-webkit-border-radius: 6px 0 0 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-rounded {
|
|
||||||
border-radius: 0 0 6px 6px;
|
|
||||||
-moz-border-radius: 0 0 6px 6px;
|
|
||||||
-webkit-border-radius: 0 0 6px 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-rounded {
|
|
||||||
border-radius: 6px 6px 0 0;
|
|
||||||
-moz-border-radius: 6px 6px 0 0;
|
|
||||||
-webkit-border-radius: 6px 6px 0 0;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEowIBAAKCAQEA4+LVrSV4kvgr2AM5NSIewSfGwK5fXUOoYQ4vpjq2+H2hhOPP
|
|
||||||
0WVyHkLWZXYek8ZmCqPFBvavzO9bveBprQIDTHexj83paaoV8IMugzymeWVONEwU
|
|
||||||
8E9S6sGihCF01yOO5g4X7lmX7mypUDNJHZd/0SuSGezwSd+c41pY/CWmCW+61hls
|
|
||||||
HjKdBp3Nked/u2aJ619D8NYPeu03V89P5x5hWrOWLSfmpd8pQ5tceVO56XjgmZLr
|
|
||||||
FwUTK5Dq/3hUv1lyxHoSWGp5sQirZ5artLgkqCI+K+dwc2YZeeJBACllSqVuzJYh
|
|
||||||
HSpnmKUwMXykJfKtTckfLoJX2VGgbqJWSZFkowIDAQABAoIBAHAKDR30p0QyyXOJ
|
|
||||||
mi26Wb6DbN88m9xBsF4PWHP0uBKRycCJNJpxstqX58q4eS4URAUFIZBb5nDuWX+P
|
|
||||||
/sS1kaOd0WmvRgvSOLkn9c1GG17h5MInib/gcBbFHr6xqD1B2TbYRQHFgMITIGcy
|
|
||||||
38axvoC7WDhw2m6nhv3sZIWLiQdnvsUWF+mXQoRwyK9Me/3/N9atRELPd9rvbwkz
|
|
||||||
ITyZQPE7IScSwVClspSBQMdJj4Bak8sQ8uKpxmIqpRGe9bqz2IO2hxkW9RiAT2CE
|
|
||||||
4KZ1eqSM8q+VUlFfEo7IJ1lh8Anuo/h/qVnN2JTyCWoAW/YLIWUreLAOVCm3feV/
|
|
||||||
fFO5sQkCgYEA8yzhvPegx1cPgtvEaAVJKbI9WBVCT7qAroDrfxBS3m37jHip8SDr
|
|
||||||
4qfh+5OWG6J0hXEKCf1FbhDCDQOf6sQCMlBgR5BU/ALqiFWfEp+ysC10VtdCpEhA
|
|
||||||
PgldtzLhXyApw536y05Ak3Yucii70m80bsXZR2alGWTfJ64e511hSM0CgYEA7+eI
|
|
||||||
QXh9kuKwM143Bk7HWvLNJ71TAb+mp0OkOjmzMe2duoGi0DzTBlSh6AYdSYkMYSbc
|
|
||||||
PW8bF88bTiq4rak9PuJGiFr7Iq5SMccpaZ+JIPnF2S8gdNB1hgfRsUDNHhb691/u
|
|
||||||
3Q/7gOUpiWGrP5uP55/yuFyKkrp+gPGKLhrFIy8CgYA096q34WxI30LGqx3t1nDo
|
|
||||||
PyWzgPXvrd0HpZcmFyUlw+kN4N6LYjNfLFhB1xTUMh+VTVj1chBkeAv8j7SOi2E7
|
|
||||||
GlzOWbbZKb1yMswyX0ypqUz0+XBPnlk36gxash96++N883VEQWg5dn2Jaiv3Gzfd
|
|
||||||
hQTd05LUpC8jUn7ywFlHZQKBgE3agWldxMKqNiw1Yv31CtUE/nbrBckHfPnDBcSv
|
|
||||||
fOuzBQDFmSSi2IixZml5sn9urknI5qg5Kj2rxFy1mIEi7vE9VU5i2CUFFT96NoJE
|
|
||||||
d6fv5rj4hjvieoEogHBZazdclc05oLa0vRWzSKuAuqZFwYmVaptRzNaZFvyZZhJY
|
|
||||||
NamZAoGBANL8Jqht1s1qcLuBis1jZdjzUuF3xNMuxwqszD0zFZFAIUN097460zw+
|
|
||||||
8LIeZgVMJOCmbVHja/RII9PI4vQ7h5rhTmeFWS80QMe22C1yukqEqljYO0POhxsu
|
|
||||||
sm3plGS3rfGkMp1URDgnJL6m/y8gC4+/O6NIEoVaHpraW8//qCD6
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDEjCCAfoCBRQDhmJSMA0GCSqGSIb3DQEBBQUAMFMxFDASBgNVBAMTC2Nlc2Fu
|
|
||||||
dGEuY29tMR0wGwYDVQQKExRDZXNhbnRhIFNvZnR3YXJlIEx0ZDELMAkGA1UEBhMC
|
|
||||||
SUUxDzANBgNVBAcTBkR1YmxpbjAeFw0xNDA2MjcxMDUwNTFaFw0yNDA2MjQxMDUw
|
|
||||||
NTFaMEcxFTATBgNVBAMTDDE5Mi4xNjguMS4yODEQMA4GA1UEChMHRm9vK0x0ZDEL
|
|
||||||
MAkGA1UEBhMCSUUxDzANBgNVBAcTBkdhbHdheTCCASIwDQYJKoZIhvcNAQEBBQAD
|
|
||||||
ggEPADCCAQoCggEBAOPi1a0leJL4K9gDOTUiHsEnxsCuX11DqGEOL6Y6tvh9oYTj
|
|
||||||
z9Flch5C1mV2HpPGZgqjxQb2r8zvW73gaa0CA0x3sY/N6WmqFfCDLoM8pnllTjRM
|
|
||||||
FPBPUurBooQhdNcjjuYOF+5Zl+5sqVAzSR2Xf9Erkhns8EnfnONaWPwlpglvutYZ
|
|
||||||
bB4ynQadzZHnf7tmietfQ/DWD3rtN1fPT+ceYVqzli0n5qXfKUObXHlTuel44JmS
|
|
||||||
6xcFEyuQ6v94VL9ZcsR6ElhqebEIq2eWq7S4JKgiPivncHNmGXniQQApZUqlbsyW
|
|
||||||
IR0qZ5ilMDF8pCXyrU3JHy6CV9lRoG6iVkmRZKMCAwEAATANBgkqhkiG9w0BAQUF
|
|
||||||
AAOCAQEAAxJSilcxos3v5aKllKTsx04Q/P39wQ07ywS1Yf9NsA7MlPU++qs3BqJJ
|
|
||||||
kAaCPpfeAl8GjQLh75XV7rLvycvrluthpHzMRZhnbd+DLCt+FrS5zWWhm6M7535V
|
|
||||||
FHGjuW59sAurARgcB530+bh6a0YNhKJbp3Si5ONhQfEuKPf+R6bPA1Slr2k/ts+K
|
|
||||||
GIzwJbNTVRSor/wlb4F0seHFEv2rdtHt1g+VYlFVwBFawIOx3dU7hHxgzeoRYnik
|
|
||||||
RGrPvhqK3u1wQ+2s/m2HPWj8CFjZ8V7f4sYRjLhpsbeJCy4A28nWvl+cCjAhCQKq
|
|
||||||
Rawa0TcZiQtsj0jaTe71jhAMSMC6qw==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = cookie_auth
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software
|
||||||
|
// All rights reserved
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static const char *s_login_uri = "/login.html";
|
||||||
|
static const char *s_secret = ":-)"; // Must be known only to server
|
||||||
|
|
||||||
|
static void generate_ssid(const char *user_name, const char *expiration_date,
|
||||||
|
char *ssid, size_t ssid_size) {
|
||||||
|
char hash[33];
|
||||||
|
mg_md5(hash, user_name, ":", expiration_date, ":", s_secret, NULL);
|
||||||
|
snprintf(ssid, ssid_size, "%s|%s|%s", user_name, expiration_date, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_auth(struct mg_connection *conn) {
|
||||||
|
char ssid[100], calculated_ssid[100], name[100], expire[100];
|
||||||
|
|
||||||
|
// Always authenticate requests to login page
|
||||||
|
if (strcmp(conn->uri, s_login_uri) == 0) {
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for session ID in the Cookie.
|
||||||
|
// That session ID can be validated against the database that stores
|
||||||
|
// current active sessions.
|
||||||
|
mg_parse_header(mg_get_header(conn, "Cookie"), "ssid", ssid, sizeof(ssid));
|
||||||
|
if (sscanf(ssid, "%[^|]|%[^|]|", name, expire) == 2) {
|
||||||
|
generate_ssid(name, expire, calculated_ssid, sizeof(calculated_ssid));
|
||||||
|
if (strcmp(ssid, calculated_ssid) == 0) {
|
||||||
|
return MG_TRUE; // Authenticate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth failed, do NOT authenticate, redirect to login page
|
||||||
|
mg_printf(conn, "HTTP/1.1 302 Moved\r\nLocation: %s\r\n\r\n", s_login_uri);
|
||||||
|
return MG_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_login_form_submission(struct mg_connection *conn) {
|
||||||
|
char name[100], password[100], ssid[100], expire[100], expire_epoch[100];
|
||||||
|
|
||||||
|
mg_get_var(conn, "name", name, sizeof(name));
|
||||||
|
mg_get_var(conn, "password", password, sizeof(password));
|
||||||
|
|
||||||
|
// A real authentication mechanism should be employed here.
|
||||||
|
// Also, the whole site should be served through HTTPS.
|
||||||
|
if (strcmp(name, "Joe") == 0 && strcmp(password, "Doe") == 0) {
|
||||||
|
// Generate expiry date
|
||||||
|
time_t t = time(NULL) + 3600; // Valid for 1 hour
|
||||||
|
snprintf(expire_epoch, sizeof(expire_epoch), "%lu", (unsigned long) t);
|
||||||
|
strftime(expire, sizeof(expire), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
|
||||||
|
generate_ssid(name, expire_epoch, ssid, sizeof(ssid));
|
||||||
|
// Set "session id" cookie, there could be some data encoded in it.
|
||||||
|
mg_printf(conn,
|
||||||
|
"HTTP/1.1 302 Moved\r\n"
|
||||||
|
"Set-Cookie: ssid=%s; expire=\"%s\"; http-only; HttpOnly;\r\n"
|
||||||
|
"Location: /\r\n\r\n",
|
||||||
|
ssid, expire);
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
return MG_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int serve_request(struct mg_connection *conn) {
|
||||||
|
if (strcmp(conn->uri, s_login_uri) == 0 &&
|
||||||
|
strcmp(conn->request_method, "POST") == 0) {
|
||||||
|
return check_login_form_submission(conn);
|
||||||
|
}
|
||||||
|
return MG_FALSE; // Serve files in the document_root
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
switch (ev) {
|
||||||
|
case MG_AUTH: return check_auth(conn);
|
||||||
|
case MG_REQUEST: return serve_request(conn);
|
||||||
|
default: return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct mg_server *server = mg_create_server(NULL, ev_handler);
|
||||||
|
mg_set_option(server, "listening_port", "8080");
|
||||||
|
mg_set_option(server, "document_root", ".");
|
||||||
|
|
||||||
|
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
||||||
|
for (;;) {
|
||||||
|
mg_poll_server(server, 1000);
|
||||||
|
}
|
||||||
|
mg_destroy_server(&server);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>WebSocket Test</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
background-color: #cde; margin: 0;
|
||||||
|
padding: 0; font: 14px Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
* { outline: none; }
|
||||||
|
div.content {
|
||||||
|
width: 800px; margin: 2em auto; padding: 20px 50px;
|
||||||
|
background-color: #fff; border-radius: 1em;
|
||||||
|
}
|
||||||
|
label { display: inline-block; min-width: 7em; }
|
||||||
|
input { border: 1px solid #ccc; padding: 0.4em; margin: 0 0 10px 0; }
|
||||||
|
a:link, a:visited { color: #69c; text-decoration: none; }
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
body { background-color: #fff; }
|
||||||
|
div.content {
|
||||||
|
width: auto; margin: 0 auto; border-radius: 0; padding: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h1>Mongoose Cookie Base Authentication</h1>
|
||||||
|
<p>This is an index page. Authentication succeeded.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>WebSocket Test</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
background-color: #cde; margin: 0;
|
||||||
|
padding: 0; font: 14px Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
* { outline: none; }
|
||||||
|
div.content {
|
||||||
|
width: 800px; margin: 2em auto; padding: 20px 50px;
|
||||||
|
background-color: #fff; border-radius: 1em;
|
||||||
|
}
|
||||||
|
label { display: inline-block; min-width: 7em; }
|
||||||
|
input { border: 1px solid #ccc; padding: 0.4em; margin: 0 0 10px 0; }
|
||||||
|
a:link, a:visited { color: #69c; text-decoration: none; }
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
body { background-color: #fff; }
|
||||||
|
div.content {
|
||||||
|
width: auto; margin: 0 auto; border-radius: 0; padding: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h1>Mongoose Cookie Based Authentication</h1>
|
||||||
|
<p>Use name "Joe", password "Doe" to login.</p>
|
||||||
|
<form method="POST">
|
||||||
|
<div>
|
||||||
|
<label>Name:</label>
|
||||||
|
<input type="text" name="name"/>
|
||||||
|
</div><div>
|
||||||
|
<label>Password:</label>
|
||||||
|
<input type="password" name="password"/>
|
||||||
|
</div><div>
|
||||||
|
<input type="submit" value="Login"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = digest_auth
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
File renamed without changes.
@@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = file_upload
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
run: $(PROG)
|
||||||
|
./$(PROG)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) Makefile
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
win:
|
||||||
|
wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
|
||||||
@@ -15,7 +15,6 @@ static int send_index_page(struct mg_connection *conn) {
|
|||||||
"<form method=\"POST\" action=\"/handle_post_request\" "
|
"<form method=\"POST\" action=\"/handle_post_request\" "
|
||||||
" enctype=\"multipart/form-data\">"
|
" enctype=\"multipart/form-data\">"
|
||||||
"<input type=\"file\" name=\"file\" /> <br/>"
|
"<input type=\"file\" name=\"file\" /> <br/>"
|
||||||
"<input type=\"text\" name=\"input1\" value=hello! /> <br/>"
|
|
||||||
"<input type=\"submit\" value=\"Upload\" />"
|
"<input type=\"submit\" value=\"Upload\" />"
|
||||||
"</form>");
|
"</form>");
|
||||||
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static int static_value = 123; // Exposed and changeable via the form
|
|
||||||
|
|
||||||
static void print_html_form(struct mg_connection *conn) {
|
|
||||||
mg_send_header(conn, "Content-Type", "text/html");
|
|
||||||
mg_send_header(conn, "Cache-Control", "max-age=0, post-check=0, "
|
|
||||||
"pre-check=0, no-store, no-cache, must-revalidate");
|
|
||||||
|
|
||||||
// Note that all the following normally should reside in static HTML page
|
|
||||||
mg_printf_data(conn, "%s", "<html><head>");
|
|
||||||
// It is better to use local copy though
|
|
||||||
mg_printf_data(conn, "<script src=\"%s\"></script>",
|
|
||||||
"http://code.jquery.com/jquery-1.11.0.min.js");
|
|
||||||
mg_printf_data(conn, "%s", "<script> jQuery(function() {\n");
|
|
||||||
// Here is the ajax call that fetches data from the device and
|
|
||||||
// updates the form
|
|
||||||
mg_printf_data(conn, "%s", "$.ajax({ url: '/get_value', dataType: 'json', "
|
|
||||||
"success: function(d) { $('#val').val(d.value); }});\n");
|
|
||||||
// This ajax call is triggered when submit button is pressed. It sends new
|
|
||||||
// value to the device.
|
|
||||||
mg_printf_data(conn, "%s", "$(document).on('click', '#button', function() {"
|
|
||||||
" $.ajax({ url: '/set_value', dataType: 'json', "
|
|
||||||
" data: { new_value: $('#val').val() } });\n"
|
|
||||||
" return false; });\n");
|
|
||||||
mg_printf_data(conn, "%s", "});</script>");
|
|
||||||
mg_printf_data(conn, "%s", "</head><body>");
|
|
||||||
mg_printf_data(conn, "%s", "<h1>Ajax form submission example</h1>");
|
|
||||||
mg_printf_data(conn, "%s", "<form>");
|
|
||||||
mg_printf_data(conn, "%s", "Device value: <input type=text id=val />");
|
|
||||||
mg_printf_data(conn, "%s", "<input type=submit id=button />");
|
|
||||||
mg_printf_data(conn, "%s", "</form>");
|
|
||||||
mg_printf_data(conn, "%s", "</body></html>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
|
||||||
if (ev == MG_REQUEST) {
|
|
||||||
if (strcmp(conn->uri, "/get_value") == 0) {
|
|
||||||
mg_printf_data(conn, "{\"value\": %d}", static_value);
|
|
||||||
} else if (strcmp(conn->uri, "/set_value") == 0) {
|
|
||||||
// This Ajax endpoint sets the new value for the device variable
|
|
||||||
char buf[100] = "";
|
|
||||||
mg_get_var(conn, "new_value", buf, sizeof(buf)); // Get form variable
|
|
||||||
static_value = atoi(buf); // Set new value
|
|
||||||
mg_printf_data(conn, "%s", "{\"success\": true}");
|
|
||||||
printf("Setting value to [%d]\n", static_value); // Debug trace
|
|
||||||
} else {
|
|
||||||
// Better way is to set "document_root" option, put "index.html" file
|
|
||||||
// into document_root and return MG_FALSE here. We're printing HTML
|
|
||||||
// page by hands just to keep everything in one C file.
|
|
||||||
print_html_form(conn);
|
|
||||||
}
|
|
||||||
return MG_TRUE;
|
|
||||||
} else if (ev == MG_AUTH) {
|
|
||||||
return MG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_server *server;
|
|
||||||
|
|
||||||
// Create and configure the server
|
|
||||||
server = mg_create_server(NULL, ev_handler);
|
|
||||||
mg_set_option(server, "listening_port", "8000");
|
|
||||||
|
|
||||||
// Serve request. Hit Ctrl-C to terminate the program
|
|
||||||
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
|
||||||
for (;;) {
|
|
||||||
mg_poll_server(server, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup, and free server instance
|
|
||||||
mg_destroy_server(&server);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = form_submit
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
File renamed without changes.
@@ -1,4 +0,0 @@
|
|||||||
<? mg.write('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') ?>
|
|
||||||
<html><body>
|
|
||||||
<span>Today is:</span> <? mg.write(os.date("%A")) ?>
|
|
||||||
</body></html>
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = hello_world
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
run: $(PROG)
|
||||||
|
./$(PROG)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) Makefile
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
win:
|
||||||
|
wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
|
||||||
|
wine $(PROG).exe
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This example demostrates basic use of Mongoose embedded web server.
|
||||||
|
// $Date: 2014-09-09 22:20:23 UTC $
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
int result = MG_FALSE;
|
switch (ev) {
|
||||||
|
case MG_AUTH: return MG_TRUE;
|
||||||
if (ev == MG_REQUEST) {
|
case MG_REQUEST:
|
||||||
mg_printf_data(conn, "Hello! Requested URI is [%s]", conn->uri);
|
mg_printf_data(conn, "Hello! Requested URI is [%s]", conn->uri);
|
||||||
result = MG_TRUE;
|
return MG_TRUE;
|
||||||
} else if (ev == MG_AUTH) {
|
default: return MG_FALSE;
|
||||||
result = MG_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = http_client
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
unix: $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This example demostrates how to connect to the remote Web server,
|
||||||
|
// download data, process it and send back a reply.
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static int s_received_signal = 0;
|
||||||
|
static struct mg_server *s_server = NULL;
|
||||||
|
static const char *s_remote_addr = "glosbe.com:80";
|
||||||
|
|
||||||
|
static void signal_handler(int sig_num) {
|
||||||
|
signal(sig_num, signal_handler);
|
||||||
|
s_received_signal = sig_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
struct mg_connection *client, *orig;
|
||||||
|
|
||||||
|
switch (ev) {
|
||||||
|
case MG_AUTH:
|
||||||
|
return MG_TRUE;
|
||||||
|
|
||||||
|
case MG_CONNECT:
|
||||||
|
// Send request to the remote host.
|
||||||
|
// TODO(lsm): handle connect error here.
|
||||||
|
mg_printf(conn, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n",
|
||||||
|
"/gapi/translate?from=eng&dest=fra&format=json&phrase=cat",
|
||||||
|
s_remote_addr);
|
||||||
|
return MG_TRUE;
|
||||||
|
|
||||||
|
case MG_REPLY:
|
||||||
|
// Send reply to the original connection
|
||||||
|
orig = (struct mg_connection *) conn->connection_param;
|
||||||
|
mg_send_status(orig, conn->status_code);
|
||||||
|
mg_send_header(orig, "Content-Type", "text/plain");
|
||||||
|
mg_send_data(orig, conn->content, conn->content_len);
|
||||||
|
mg_send_data(orig, "", 0); // Last chunk: mark the end of reply
|
||||||
|
|
||||||
|
// Disconnect connections
|
||||||
|
orig->connection_param = NULL;
|
||||||
|
conn->connection_param = NULL;
|
||||||
|
return MG_TRUE;
|
||||||
|
|
||||||
|
case MG_REQUEST:
|
||||||
|
if ((client = mg_connect(s_server, s_remote_addr)) != NULL) {
|
||||||
|
// Interconnect requests
|
||||||
|
client->connection_param = conn;
|
||||||
|
conn->connection_param = client;
|
||||||
|
return MG_MORE;
|
||||||
|
} else {
|
||||||
|
mg_printf_data(conn, "%s", "cannot send API request");
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
s_server = mg_create_server(NULL, ev_handler);
|
||||||
|
|
||||||
|
mg_set_option(s_server, "listening_port", "8080");
|
||||||
|
|
||||||
|
// Setup signal handlers
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
printf("Listening on port %s\n", mg_get_option(s_server, "listening_port"));
|
||||||
|
while (s_received_signal == 0) {
|
||||||
|
mg_poll_server(s_server, 1000);
|
||||||
|
}
|
||||||
|
mg_destroy_server(&s_server);
|
||||||
|
printf("Existing on signal %d\n", s_received_signal);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
HTTP/1.0 200 OK
|
|
||||||
Content-Type: text/plain
|
|
||||||
|
|
||||||
<?
|
|
||||||
-- Directory scanning example
|
|
||||||
|
|
||||||
function scandir(dir)
|
|
||||||
local t = {}
|
|
||||||
for f in io.popen('dir ' .. dir):lines() do table.insert(t, f) end
|
|
||||||
return t
|
|
||||||
end
|
|
||||||
|
|
||||||
local tab = scandir('C:\\')
|
|
||||||
for k,v in pairs(tab) do mg.write(v, '\n') end
|
|
||||||
?>
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
HTTP/1.0 200 OK
|
|
||||||
Content-Type: text/html
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<p>Prime numbers from 0 to 100, calculated by Lua:</p>
|
|
||||||
<?
|
|
||||||
function is_prime(n)
|
|
||||||
if n <= 0 then return false end
|
|
||||||
if n <= 2 then return true end
|
|
||||||
if (n % 2 == 0) then return false end
|
|
||||||
for i = 3, n / 2, 2 do
|
|
||||||
if (n % i == 0) then return false end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, 100 do
|
|
||||||
if is_prime(i) then mg.write('<span>' .. i .. '</span> ') end
|
|
||||||
end
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<p>Reading POST data from Lua (click submit):</p>
|
|
||||||
<form method="POST" ><input type="text" name="t1"/><input type="submit"></form>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
POST data: [<? mg.write(mg.request_info.content) ?>]
|
|
||||||
request method: [<? mg.write(mg.request_info.request_method) ?>]
|
|
||||||
IP/port: [<?mg.write(mg.request_info.remote_ip, ':',
|
|
||||||
mg.request_info.remote_port) ?>]
|
|
||||||
URI: [<? mg.write(mg.request_info.uri) ?>]
|
|
||||||
HTTP version [<? mg.write(mg.request_info.http_version) ?>]
|
|
||||||
Content Len: [<? mg.write(mg.request_info.content_len) ?>]
|
|
||||||
HEADERS:
|
|
||||||
<?
|
|
||||||
for name, value in pairs(mg.request_info.http_headers) do
|
|
||||||
mg.write(name, ':', value, '\n')
|
|
||||||
end
|
|
||||||
?>
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
</html>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "lua_5.2.1.h"
|
|
||||||
|
|
||||||
static int smile(lua_State *L) {
|
|
||||||
(void) L; // Unused
|
|
||||||
printf("%s\n", ":-)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LUA_API luaopen_lua_dll(lua_State *L) {
|
|
||||||
static const struct luaL_Reg api[] = {
|
|
||||||
{"smile", smile},
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
||||||
luaL_openlib(L, "lua_dll", api, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static void send_file(struct mg_connection *conn, const char *path) {
|
|
||||||
char buf[1024];
|
|
||||||
struct stat st;
|
|
||||||
int n;
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
if (stat(path, &st) == 0 && (fp = fopen(path, "rb")) != NULL) {
|
|
||||||
mg_printf(conn, "--myboundary\r\nContent-Type: image/jpeg\r\n"
|
|
||||||
"Content-Length: %llu\r\n\r\n", (unsigned long long) st.st_size);
|
|
||||||
while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
|
|
||||||
mg_write(conn, buf, n);
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
mg_write(conn, "\r\n", 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct conn_state {
|
|
||||||
int file_index;
|
|
||||||
time_t last_poll;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
|
||||||
const char **file_names = (const char **) conn->server_param;
|
|
||||||
struct conn_state *state;
|
|
||||||
int result = MG_FALSE;
|
|
||||||
|
|
||||||
if (ev == MG_REQUEST) {
|
|
||||||
mg_printf(conn, "%s",
|
|
||||||
"HTTP/1.0 200 OK\r\n" "Cache-Control: no-cache\r\n"
|
|
||||||
"Pragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\n"
|
|
||||||
"Connection: close\r\nContent-Type: multipart/x-mixed-replace; "
|
|
||||||
"boundary=--myboundary\r\n\r\n");
|
|
||||||
|
|
||||||
send_file(conn, file_names[0]);
|
|
||||||
|
|
||||||
state = (struct conn_state *) malloc(sizeof(*state));
|
|
||||||
conn->connection_param = state;
|
|
||||||
state->file_index = 1; // First file is already sent
|
|
||||||
state->last_poll = time(NULL);
|
|
||||||
result = MG_MORE;
|
|
||||||
|
|
||||||
} else if (ev == MG_POLL) {
|
|
||||||
|
|
||||||
time_t now = time(NULL);
|
|
||||||
state = (struct conn_state *) conn->connection_param;
|
|
||||||
|
|
||||||
if (state != NULL && now > state->last_poll) {
|
|
||||||
if (file_names[state->file_index] != NULL) {
|
|
||||||
send_file(conn, file_names[state->file_index]);
|
|
||||||
state->file_index++;
|
|
||||||
if (file_names[state->file_index] == NULL) {
|
|
||||||
result = MG_TRUE; // No more images, close connection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state->last_poll = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (ev == MG_CLOSE) {
|
|
||||||
free(conn->connection_param);
|
|
||||||
conn->connection_param = NULL;
|
|
||||||
} else if (ev == MG_AUTH) {
|
|
||||||
result = MG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
struct mg_server *server;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("Usage: %s image1.jpg image2.jpg ...\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
server = mg_create_server(&argv[1], ev_handler);
|
|
||||||
mg_set_option(server, "listening_port", "8080");
|
|
||||||
|
|
||||||
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
|
||||||
for (;;) {
|
|
||||||
mg_poll_server(server, 1000);
|
|
||||||
}
|
|
||||||
mg_destroy_server(&server);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = mjpg_streamer
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static void send_file(struct mg_connection *conn, const char *path) {
|
||||||
|
char buf[1024];
|
||||||
|
struct stat st;
|
||||||
|
int n;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (stat(path, &st) == 0 && (fp = fopen(path, "rb")) != NULL) {
|
||||||
|
mg_printf(conn, "--w00t\r\nContent-Type: image/jpeg\r\n"
|
||||||
|
"Content-Length: %lu\r\n\r\n", (unsigned long) st.st_size);
|
||||||
|
while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
|
||||||
|
mg_write(conn, buf, n);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
mg_write(conn, "\r\n", 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct conn_state {
|
||||||
|
int file_index;
|
||||||
|
time_t last_poll;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
const char **file_names = (const char **) conn->server_param;
|
||||||
|
struct conn_state *state;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
switch (ev) {
|
||||||
|
|
||||||
|
case MG_AUTH:
|
||||||
|
return MG_TRUE;
|
||||||
|
|
||||||
|
case MG_REQUEST:
|
||||||
|
if (strcmp(conn->uri, "/stream") != 0) {
|
||||||
|
mg_send_header(conn, "Content-Type", "text/html");
|
||||||
|
mg_printf_data(conn, "%s",
|
||||||
|
"Go to <a href=/stream>/stream</a> for MJPG stream");
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mg_printf(conn, "%s",
|
||||||
|
"HTTP/1.0 200 OK\r\n" "Cache-Control: no-cache\r\n"
|
||||||
|
"Pragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\n"
|
||||||
|
"Connection: close\r\nContent-Type: multipart/x-mixed-replace; "
|
||||||
|
"boundary=--w00t\r\n\r\n");
|
||||||
|
|
||||||
|
send_file(conn, file_names[0]);
|
||||||
|
|
||||||
|
state = (struct conn_state *) malloc(sizeof(*state));
|
||||||
|
conn->connection_param = state;
|
||||||
|
state->file_index = 1; // First file is already sent
|
||||||
|
state->last_poll = time(NULL);
|
||||||
|
return MG_MORE;
|
||||||
|
|
||||||
|
case MG_POLL:
|
||||||
|
state = (struct conn_state *) conn->connection_param;
|
||||||
|
|
||||||
|
if (state != NULL && now > state->last_poll) {
|
||||||
|
if (file_names[state->file_index] != NULL) {
|
||||||
|
send_file(conn, file_names[state->file_index]);
|
||||||
|
state->file_index++;
|
||||||
|
if (file_names[state->file_index] == NULL) {
|
||||||
|
return MG_TRUE; // No more images, close connection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state->last_poll = now;
|
||||||
|
}
|
||||||
|
return MG_FALSE;
|
||||||
|
|
||||||
|
case MG_CLOSE:
|
||||||
|
free(conn->connection_param);
|
||||||
|
conn->connection_param = NULL;
|
||||||
|
return MG_FALSE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
struct mg_server *server;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
printf("Usage: %s image1.jpg image2.jpg ...\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
server = mg_create_server(&argv[1], ev_handler);
|
||||||
|
mg_set_option(server, "listening_port", "8080");
|
||||||
|
|
||||||
|
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
||||||
|
for (;;) {
|
||||||
|
mg_poll_server(server, 1000);
|
||||||
|
}
|
||||||
|
mg_destroy_server(&server);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = multi_threaded_server
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -26,9 +26,9 @@ int main(void) {
|
|||||||
server1 = mg_create_server((void *) "1", ev_handler);
|
server1 = mg_create_server((void *) "1", ev_handler);
|
||||||
server2 = mg_create_server((void *) "2", ev_handler);
|
server2 = mg_create_server((void *) "2", ev_handler);
|
||||||
|
|
||||||
// Make both server1 and server2 listen on the same socket
|
// Make both server1 and server2 listen on the same sockets
|
||||||
mg_set_option(server1, "listening_port", "8080");
|
mg_set_option(server1, "listening_port", "8080");
|
||||||
mg_set_listening_socket(server2, mg_get_listening_socket(server1));
|
mg_copy_listeners(server1, server2);
|
||||||
|
|
||||||
// server1 goes to separate thread, server 2 runs in main thread.
|
// server1 goes to separate thread, server 2 runs in main thread.
|
||||||
// IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER.
|
// IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = proxy_server
|
||||||
|
FLAGS = -I../.. -DNS_ENABLE_SSL
|
||||||
|
CFLAGS = -W -Wall -g -O0 -pthread -lssl $(FLAGS) $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
unix: $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -11,7 +11,20 @@
|
|||||||
// Configure your browser to use localhost:2014 as a proxy for all protocols
|
// Configure your browser to use localhost:2014 as a proxy for all protocols
|
||||||
// Then, navigate to https://cesanta.com
|
// Then, navigate to https://cesanta.com
|
||||||
|
|
||||||
#include "net_skeleton.h"
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define sleep(x) Sleep((x) * 1000)
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
static int s_received_signal = 0;
|
static int s_received_signal = 0;
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = restful_api
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>RESTful API demo</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<style type="text/css">
|
||||||
|
* { outline: none; font: 16px/1.4 Helvetica, Arial, sans-serif; }
|
||||||
|
body {
|
||||||
|
background-color: #cde; margin: 0;
|
||||||
|
padding: 0; font: 16px/1.4 Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
div.content {
|
||||||
|
width: 800px; margin: 2em auto; padding: 20px 50px;
|
||||||
|
background-color: #fff; border-radius: 1em;
|
||||||
|
}
|
||||||
|
label { display: inline-block; min-width: 7em; }
|
||||||
|
input { border: 1px solid #ccc; padding: 0.2em; }
|
||||||
|
a:link, a:visited { color: #69c; text-decoration: none; }
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
body { background-color: #fff; }
|
||||||
|
div.content { width: auto; margin: 0 auto; padding: 1em; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||||
|
<script language="javascript" type="text/javascript">
|
||||||
|
jQuery(function() {
|
||||||
|
|
||||||
|
$(document).on('keyup', '#n1, #n2', function() {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/sum',
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { n1: $('#n1').val(), n2: $('#n2').val() },
|
||||||
|
success: function(json) {
|
||||||
|
$('#result').html(json.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h1>RESTful API demo.</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This page demonstrates how Mongoose web server could be used to implement
|
||||||
|
RESTful APIs. Enter numbers below, and press Submit. Browser will send
|
||||||
|
two numbers to <tt>/api/sum</tt> URI, Mongoose calclulates the sum of
|
||||||
|
two and returns the result.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>Number 1:</label> <input type="text" id="n1" />
|
||||||
|
</div><div>
|
||||||
|
<label>Number 2:</label> <input type="text" id="n2" />
|
||||||
|
</div><div>
|
||||||
|
<label>Result:</label> <span id="result"> </span>
|
||||||
|
</div><div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static const char *s_no_cache_header =
|
||||||
|
"Cache-Control: max-age=0, post-check=0, "
|
||||||
|
"pre-check=0, no-store, no-cache, must-revalidate\r\n";
|
||||||
|
|
||||||
|
static void handle_restful_call(struct mg_connection *conn) {
|
||||||
|
char n1[100], n2[100];
|
||||||
|
|
||||||
|
// Get form variables
|
||||||
|
mg_get_var(conn, "n1", n1, sizeof(n1));
|
||||||
|
mg_get_var(conn, "n2", n2, sizeof(n2));
|
||||||
|
|
||||||
|
mg_printf_data(conn, "{ \"result\": %lf }", strtod(n1, NULL) + strtod(n2, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
switch (ev) {
|
||||||
|
case MG_AUTH: return MG_TRUE;
|
||||||
|
case MG_REQUEST:
|
||||||
|
if (!strcmp(conn->uri, "/api/sum")) {
|
||||||
|
handle_restful_call(conn);
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
mg_send_file(conn, "index.html", s_no_cache_header);
|
||||||
|
return MG_MORE;
|
||||||
|
default: return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct mg_server *server;
|
||||||
|
|
||||||
|
// Create and configure the server
|
||||||
|
server = mg_create_server(NULL, ev_handler);
|
||||||
|
mg_set_option(server, "listening_port", "8000");
|
||||||
|
|
||||||
|
// Serve request. Hit Ctrl-C to terminate the program
|
||||||
|
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
|
||||||
|
for (;;) {
|
||||||
|
mg_poll_server(server, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup, and free server instance
|
||||||
|
mg_destroy_server(&server);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = send_file
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
run: $(PROG)
|
||||||
|
./$(PROG)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) Makefile
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
win:
|
||||||
|
wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /I../.. /Fe$(PROG).exe
|
||||||
|
wine $(PROG).exe
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This example demostrates how to send arbitrary files to the client.
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
case MG_REQUEST:
|
case MG_REQUEST:
|
||||||
mg_send_file(conn, "file.c");
|
mg_send_file(conn, "send_file.c", NULL); // Also could be a dir, or CGI
|
||||||
return MG_MORE; // It is important to return MG_MORE after mg_send_file!
|
return MG_MORE; // It is important to return MG_MORE after mg_send_file!
|
||||||
case MG_AUTH: return MG_TRUE;
|
case MG_AUTH: return MG_TRUE;
|
||||||
default: return MG_FALSE;
|
default: return MG_FALSE;
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEpQIBAAKCAQEAtafk8OvgJX6SLEtnwRmE1oEmk3zsDD0UGW+qD+DtIPOb37xR
|
|
||||||
NIpOGFU8GXAn2GmIIkk7L53bnyh08osTnJKnhprBMDIpwZoMp4HECH4Dk0M7H2S3
|
|
||||||
CMJRT+wYG4GJZt3Tp2U5y9T+T+4YMGCVXOOC7MiEq1nA/iQnljhhGJO61yVgDb/d
|
|
||||||
asnI6igrDQUY30NHIBdtws2s+ysWLYh/LugLZurEtvnzwnt/qQoe7UF/MW51gvu7
|
|
||||||
ywfSvxRksCKZKOFjLIMcEmkReA28Y+mhfKT1bjU6Gte2XZj+5f2TqYvCO+n/d5dY
|
|
||||||
41/Nuk9ujjo/G19dUUOZu3OLL59Q9Rg+6j1FVwIDAQABAoIBAQCE7iW0v4c5KNQi
|
|
||||||
odN9FQWGSuBF0YaStid9LZ+PGxOrp1kLcq0h+4uGdukR3GbsEN3T6S7se2H5qAtc
|
|
||||||
abWiQBdjgt+YOz0fNXHJKkafyEcpfmtHX9YpDLmf+K7zgelgYze9KXAP3v9y0lLV
|
|
||||||
I/hpDvwB9gJPudBmqWJmpT84UvLI+I1HtJ1Q3EgMxFSlx+TrGxqIQmYCaXIIZqdk
|
|
||||||
c1B2neQLGZQ1Dbulr7/KYOkkcPkAQKRY73WHvhhN/0LsD25U6P00etz1VQmLBcWe
|
|
||||||
Y9RaCBD7D3UqSat6ZABv7mtFp8USAEy4a8clayQRdolGTb+gxBUnEMDtRzwcE4zF
|
|
||||||
uh/SGFEBAoGBAPBU/19v82Jqy41D8nqjTN6WXRX37kN1ElS5yvstIdO3oHEywll8
|
|
||||||
tV8Bm+L0ODn/dOWmCZxKWO3hwr8KoEgk8ouv/vDsMRBuwtqZmmdtue5kPEnw3kMB
|
|
||||||
F6RR4Pd9dqmwbF/s4NwpIVFaQEZE6JkhEsXHAJSivKm4m0MadSfm6F5BAoGBAMF/
|
|
||||||
oArSDqsz5BvTZ3pbhUxIMY98IR7jf1ewjsgpthqZFhTggD0KxVcfUYSzg3BXUkl9
|
|
||||||
NFKPQgfOfgW2fiEe999/CRPB0lTtlMybs3L+gb74SmUWxkVmm4mjhfnPoh9AKga2
|
|
||||||
AFtZEcx+1bzkVvyZoSV4s0R61jJcVptutWFcDG2XAoGAKcltmad6dvtApzBQQdiQ
|
|
||||||
7gbQ6pfwOpRpeofPbjrbrdc4s1XzCuIvGvTJqP1zpUnwhlmHREB9E+d0GAl98u1R
|
|
||||||
qs4QEs3Ofh/0C1Q3z5H5iSSuguC5lIblGHIQHpgXAMwnG8qxEjaoj1+U22Lx2mYw
|
|
||||||
wGiohi+BhDUP8evwwN5aOsECgYEAq3qN+2jihQhsi9hSqNW4kLyd5zmrJHOaI70d
|
|
||||||
G/gTIQkvz3qRSwdjkWz40jBAOGu6SdRCbTP14XM2rZtntbR7GL687Zxj6M3Pg3As
|
|
||||||
nKk9lF73lxSSy2g+SMD490TxuN4lIGNkd4+8vUxd4JM/H4aKj+mifPqbHnBEdGSt
|
|
||||||
K0Xm4asCgYEAxM1MNlaS6BD8jLcEQZ/PX9G+ReN7u5zMiw62KQj0wsMy+p92ib1l
|
|
||||||
Jvsv2LI4Ps6SEf4XdDctoAjgk7wsv45rS2RxiBg3wSVz5SSR513+VjlIgmNGWTlI
|
|
||||||
U7tngF/p+qh2Kd5XtqSj5TK3Ts9UPfv3TjBe85LaxxT9WJ8SH3NiEAg=
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDEjCCAfoCBRQDhmJRMA0GCSqGSIb3DQEBBQUAMFMxFDASBgNVBAMTC2Nlc2Fu
|
|
||||||
dGEuY29tMR0wGwYDVQQKExRDZXNhbnRhIFNvZnR3YXJlIEx0ZDELMAkGA1UEBhMC
|
|
||||||
SUUxDzANBgNVBAcTBkR1YmxpbjAeFw0xNDA2MjcxMDUwNTBaFw0yNDA2MjQxMDUw
|
|
||||||
NTBaMEcxFTATBgNVBAMTDDE5Mi4xNjguMS4yODEQMA4GA1UEChMHRm9vK0x0ZDEL
|
|
||||||
MAkGA1UEBhMCSUUxDzANBgNVBAcTBkdhbHdheTCCASIwDQYJKoZIhvcNAQEBBQAD
|
|
||||||
ggEPADCCAQoCggEBALWn5PDr4CV+kixLZ8EZhNaBJpN87Aw9FBlvqg/g7SDzm9+8
|
|
||||||
UTSKThhVPBlwJ9hpiCJJOy+d258odPKLE5ySp4aawTAyKcGaDKeBxAh+A5NDOx9k
|
|
||||||
twjCUU/sGBuBiWbd06dlOcvU/k/uGDBglVzjguzIhKtZwP4kJ5Y4YRiTutclYA2/
|
|
||||||
3WrJyOooKw0FGN9DRyAXbcLNrPsrFi2Ify7oC2bqxLb588J7f6kKHu1BfzFudYL7
|
|
||||||
u8sH0r8UZLAimSjhYyyDHBJpEXgNvGPpoXyk9W41OhrXtl2Y/uX9k6mLwjvp/3eX
|
|
||||||
WONfzbpPbo46PxtfXVFDmbtziy+fUPUYPuo9RVcCAwEAATANBgkqhkiG9w0BAQUF
|
|
||||||
AAOCAQEAtWSuAbC62J0rdSu5GZg7k7hu6e9s11dc5PS/VRk4h+99RoLxWYO7c6Bp
|
|
||||||
PdDGt6IAWDu2u/aowlKr0sWwThR+nAlQHlufSieS6udfFR1O6cjXa0hRUCKU5Ant
|
|
||||||
+mgPNsfmxV6A6pBSfwgYiv6KLaCRr7tvJqyaNl0MbxMCPmUHy+/Fplab6+h91DsO
|
|
||||||
FxECw/P73iNmSrx9sYrbl83snXMDoMgHq08LwebBcdfiKXGB7mobi0lRfNbh7rqv
|
|
||||||
xVZZ26shxUKLZrtDH0+ACPO6/e6dogOIO9/Frlp+E955Y6F+SeF4QexfbZn5mW8X
|
|
||||||
c7pDVtADI3bClzuYM6PPvOp+sXKM9Q==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = web_server
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -1,23 +1,5 @@
|
|||||||
// Copyright (c) 2004-2013 Sergey Lyubka
|
// Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
// Copyright (c) 2013-2014 Cesanta Software Limited
|
// Copyright (c) 2013-2014 Cesanta Software Limited
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
#undef UNICODE // Use ANSI WinAPI functions
|
#undef UNICODE // Use ANSI WinAPI functions
|
||||||
#undef _UNICODE // Use multibyte encoding on Windows
|
#undef _UNICODE // Use multibyte encoding on Windows
|
||||||
@@ -145,7 +127,7 @@ static void show_usage_and_exit(void) {
|
|||||||
fprintf(stderr, "Mongoose version %s (c) Sergey Lyubka, built on %s\n",
|
fprintf(stderr, "Mongoose version %s (c) Sergey Lyubka, built on %s\n",
|
||||||
MVER, __DATE__);
|
MVER, __DATE__);
|
||||||
fprintf(stderr, "Usage:\n");
|
fprintf(stderr, "Usage:\n");
|
||||||
#ifndef MONGOOSE_NO_AUTH
|
#if !defined(MONGOOSE_NO_AUTH) && !defined(MONGOOSE_NO_FILESYSTEM)
|
||||||
fprintf(stderr, " mongoose -A <htpasswd_file> <realm> <user> <passwd>\n");
|
fprintf(stderr, " mongoose -A <htpasswd_file> <realm> <user> <passwd>\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, " mongoose [config_file]\n");
|
fprintf(stderr, " mongoose [config_file]\n");
|
||||||
@@ -335,7 +317,7 @@ static void set_absolute_path(char *options[], const char *option_name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MONGOOSE_NO_AUTH
|
#if !defined(MONGOOSE_NO_AUTH) && !defined(MONGOOSE_NO_FILESYSTEM)
|
||||||
int modify_passwords_file(const char *fname, const char *domain,
|
int modify_passwords_file(const char *fname, const char *domain,
|
||||||
const char *user, const char *pass) {
|
const char *user, const char *pass) {
|
||||||
int found;
|
int found;
|
||||||
@@ -406,7 +388,7 @@ static void start_mongoose(int argc, char *argv[]) {
|
|||||||
die("%s", "Failed to start Mongoose.");
|
die("%s", "Failed to start Mongoose.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MONGOOSE_NO_AUTH
|
#if !defined(MONGOOSE_NO_AUTH) && !defined(MONGOOSE_NO_FILESYSTEM)
|
||||||
// Edit passwords file if -A option is specified
|
// Edit passwords file if -A option is specified
|
||||||
if (argc > 1 && !strcmp(argv[1], "-A")) {
|
if (argc > 1 && !strcmp(argv[1], "-A")) {
|
||||||
if (argc != 6) {
|
if (argc != 6) {
|
||||||
@@ -474,6 +456,7 @@ static void set_options(char *argv[]) {
|
|||||||
// scripts can use relative paths.
|
// scripts can use relative paths.
|
||||||
chdir(mg_get_option(server, "document_root"));
|
chdir(mg_get_option(server, "document_root"));
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Add an ability to pass listening socket to mongoose
|
// Add an ability to pass listening socket to mongoose
|
||||||
{
|
{
|
||||||
const char *env = getenv("MONGOOSE_LISTENING_SOCKET");
|
const char *env = getenv("MONGOOSE_LISTENING_SOCKET");
|
||||||
@@ -481,6 +464,7 @@ static void set_options(char *argv[]) {
|
|||||||
mg_set_listening_socket(server, atoi(env));
|
mg_set_listening_socket(server, atoi(env));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Setup signal handler: quit on Ctrl-C
|
// Setup signal handler: quit on Ctrl-C
|
||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = websocket_chat
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
File renamed without changes.
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright (c) 2013-2014 Cesanta Software Limited
|
||||||
|
// $Date: 2014-09-09 17:07:55 UTC $
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -46,7 +49,7 @@ static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
|||||||
handle_websocket_message(conn);
|
handle_websocket_message(conn);
|
||||||
return MG_TRUE;
|
return MG_TRUE;
|
||||||
} else {
|
} else {
|
||||||
mg_send_file(conn, "pubsub.html"); // Return MG_MORE after mg_send_file()
|
mg_send_file(conn, "index.html", NULL); // Return MG_MORE after!
|
||||||
return MG_MORE;
|
return MG_MORE;
|
||||||
}
|
}
|
||||||
case MG_WS_CONNECT:
|
case MG_WS_CONNECT:
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = websocket_echo_server
|
||||||
|
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
File renamed without changes.
@@ -1,27 +1,24 @@
|
|||||||
|
// Copyright (c) 2013-2014 Cesanta Software Limited
|
||||||
|
// $Date: 2014-09-09 17:07:55 UTC $
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
static void push_message(struct mg_server *server, time_t current_time) {
|
||||||
#define snprintf _snprintf
|
struct mg_connection *c;
|
||||||
#endif
|
char buf[20];
|
||||||
|
int len = sprintf(buf, "%lu", (unsigned long) current_time);
|
||||||
|
|
||||||
extern const char *find_embedded_file(const char *, size_t *);
|
// Iterate over all connections, and push current time message to websocket ones.
|
||||||
|
for (c = mg_next(server, NULL); c != NULL; c = mg_next(server, c)) {
|
||||||
static int iterate_callback(struct mg_connection *c, enum mg_event ev) {
|
if (c->is_websocket) {
|
||||||
if (ev == MG_POLL && c->is_websocket) {
|
mg_websocket_write(c, 1, buf, len);
|
||||||
char buf[20];
|
}
|
||||||
int len = snprintf(buf, sizeof(buf), "%lu",
|
|
||||||
(unsigned long) * (time_t *) c->callback_param);
|
|
||||||
mg_websocket_write(c, 1, buf, len);
|
|
||||||
}
|
}
|
||||||
return MG_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_reply(struct mg_connection *conn) {
|
static int send_reply(struct mg_connection *conn) {
|
||||||
size_t index_size;
|
|
||||||
const char *index_html = find_embedded_file("websocket.html", &index_size);
|
|
||||||
|
|
||||||
if (conn->is_websocket) {
|
if (conn->is_websocket) {
|
||||||
// This handler is called for each incoming websocket frame, one or more
|
// This handler is called for each incoming websocket frame, one or more
|
||||||
// times for connection lifetime.
|
// times for connection lifetime.
|
||||||
@@ -30,19 +27,16 @@ static int send_reply(struct mg_connection *conn) {
|
|||||||
return conn->content_len == 4 && !memcmp(conn->content, "exit", 4) ?
|
return conn->content_len == 4 && !memcmp(conn->content, "exit", 4) ?
|
||||||
MG_FALSE : MG_TRUE;
|
MG_FALSE : MG_TRUE;
|
||||||
} else {
|
} else {
|
||||||
mg_send_header(conn, "Content-Type", "text/html");
|
mg_send_file(conn, "index.html", NULL);
|
||||||
mg_send_data(conn, index_html, index_size);
|
return MG_MORE;
|
||||||
return MG_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
if (ev == MG_REQUEST) {
|
switch (ev) {
|
||||||
return send_reply(conn);
|
case MG_AUTH: return MG_TRUE;
|
||||||
} else if (ev == MG_AUTH) {
|
case MG_REQUEST: return send_reply(conn);
|
||||||
return MG_TRUE;
|
default: return MG_FALSE;
|
||||||
} else {
|
|
||||||
return MG_FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +52,7 @@ int main(void) {
|
|||||||
current_timer = time(NULL);
|
current_timer = time(NULL);
|
||||||
if (current_timer - last_timer > 0) {
|
if (current_timer - last_timer > 0) {
|
||||||
last_timer = current_timer;
|
last_timer = current_timer;
|
||||||
mg_iterate_over_connections(server, iterate_callback, ¤t_timer);
|
push_message(server, current_timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = ws_ssl
|
||||||
|
CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = ws_ssl.c ../../mongoose.c ssl_wrapper.c
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES)
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) \
|
||||||
|
-DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY -lssl $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAwizPnrCx+/kPSdEeSJFLDXrBH+cSQsSLrCm99G1hCjzqSlIk
|
||||||
|
1BhkZMEHxBaiVLky4+M/nwhjwwRHI10h6U2Or3tbPLv7z94cPf+uCx1aF7TE3Fm3
|
||||||
|
6YnDk+CjrYVFN5GRPGOPPdFxGoc+vFvQJyAAimvchnS1ZoEQFvermwzOnKspA6gc
|
||||||
|
Px+7wnOeju9TyJuDr5ngtDXFnkcpkBNPxz3En4MJY4xJiaueafh9pIES2vSl7uP0
|
||||||
|
J/qot9v2rdiL7nt1H1vwseeEkZhQ+NLB5e2z4psyktJcwDX7wQ6j7JnKfHeP+ixO
|
||||||
|
TUORgV4foBMVOqo//Guo92Q5HoLNK77V0y4+ZQIDAQABAoIBAGEsx+LlDs3JQQty
|
||||||
|
KjOq8uKWElyC6bKcZkIMydGvg6b6AU6ceW3jnyqFJ/vMUAUSghNmQQq3yiVo2Kks
|
||||||
|
DLKTa9sKYwisE0NeJsgoUtOhJttCTlrwU4f+t/AjtgY68f7zTLnqIV+Ql4ftM0pU
|
||||||
|
sIFEFMExZbWsZrQb1w+Hd0wrRqNEbSOfSjHeigvuw1T3GH2tSBUTGTpcoewCzy7U
|
||||||
|
PKS5pkYyiKySQQNqZTac3NHPjxdK6xxzwURZp1irKdiPdt04KHLVLX8KXelt/J0k
|
||||||
|
AeYkVbpFIeQ9rNBerMEp6uRBt+nE5mvP+xx1XPqKRxuxbMyTnBXeOM2zS/a/dBiz
|
||||||
|
fwokwcECgYEA9RSsv9AQ/AR8tt+aPEQvjhJ5pn/YbCb1DA9IDXpaq3tzacGd8JHj
|
||||||
|
3kUtb79nosu85LvSkAYmtzgfJs6xZyUkscra6q+xlsJ12QRxLzqfxcp9Y0wsdqM4
|
||||||
|
AcOwuiPKrjkWxOQpyWPWRwbmAefLfRMekHt4Y/QY0CwhslpnsOsj3O0CgYEAytOE
|
||||||
|
8I4GBfSQfSjXwfrso++Oi75VSsl5ZeiMGihfEhYFTE8/3rEZf7nf9iFSkN3TT+7f
|
||||||
|
pFqQzddzPBZXlpVM6k1jcEjdpJizbeR8DmICpABFrZvKz1o8pQ2Yw+FYI86ih0x4
|
||||||
|
806snMNgg/RgcVijXKFrC5joJOI+DVgwWoQyMFkCgYBxt4MkiV2oIkjf7ca6GgVa
|
||||||
|
zbXGjOGV5Umkq96J6nDxyplVw/IN8xOhScX4aP6kahaep4vfKguCzjaeIh/stS5e
|
||||||
|
lLqZVKZ5Roe6B7ag7HnAI+GkVm73KWrOXse8xui/iFvJRfkhqgJ9+HR3A9/GjD2N
|
||||||
|
Ws0Uy+lLhn6oLAya6bA9TQKBgAVfZP4aRP6TY+Bs3Io+41XUWqpI+GlqvNR+PHfU
|
||||||
|
6e/ItYs37jEv78T6X3xdlZpQxfAwG6x22a8aLetBjEBo5Aiw1Bl9VKGvidE3ZDHd
|
||||||
|
VsSRXUckAVNMyJ52pb1KktMf/h4nYGzRgLEGW+Ai8QsPlgQ2ImfEPSH8/DfORjmf
|
||||||
|
ltTBAoGBAMxIZ52DrJvuxogSOfA1MoCD6a90trkXCquvi+A/fXojZ8BHmMQshvhK
|
||||||
|
rAO7SDIV1i1Nh3jQ/oFWE8KOprqrOLO6jNTyF65vh+zk7ztGsEME9FkDhHasUiXf
|
||||||
|
t5PE9KeTChHRvIa4FGCl9We9GftE5Ii77LWMOIq22pyxYbvHQFEf
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDlDCCAnygAwIBAgIJAIOoO+AapJ5WMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNV
|
||||||
|
BAMTA3dzMTEMMAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVi
|
||||||
|
bGluMB4XDTE0MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMD
|
||||||
|
d3MxMQwwCgYDVQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZEdWJsaW4w
|
||||||
|
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCLM+esLH7+Q9J0R5IkUsN
|
||||||
|
esEf5xJCxIusKb30bWEKPOpKUiTUGGRkwQfEFqJUuTLj4z+fCGPDBEcjXSHpTY6v
|
||||||
|
e1s8u/vP3hw9/64LHVoXtMTcWbfpicOT4KOthUU3kZE8Y4890XEahz68W9AnIACK
|
||||||
|
a9yGdLVmgRAW96ubDM6cqykDqBw/H7vCc56O71PIm4OvmeC0NcWeRymQE0/HPcSf
|
||||||
|
gwljjEmJq55p+H2kgRLa9KXu4/Qn+qi32/at2Ivue3UfW/Cx54SRmFD40sHl7bPi
|
||||||
|
mzKS0lzANfvBDqPsmcp8d4/6LE5NQ5GBXh+gExU6qj/8a6j3ZDkegs0rvtXTLj5l
|
||||||
|
AgMBAAGjgZwwgZkwHQYDVR0OBBYEFL54xAgtJTW6US4Mbr4QG0yKzvaxMGoGA1Ud
|
||||||
|
IwRjMGGAFL54xAgtJTW6US4Mbr4QG0yKzvaxoT6kPDA6MQwwCgYDVQQDEwN3czEx
|
||||||
|
DDAKBgNVBAoTA3dzMTELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAIOo
|
||||||
|
O+AapJ5WMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJz/RzMa9Wa2
|
||||||
|
eEXed7ijH1gcWtgVsVT1xZo0ksFl+QJ5Be1AJpOIe8nKdzYjxPWUkofIoaGHdMLL
|
||||||
|
Uc/udRzsXncup+0mD+Yos6Cqyo9yHq7L1HbXfKYZtBXIjWHdF2+RP8j9tHfITXYI
|
||||||
|
Pb2zsQ+A6PYpp5OLGZTDAnI2qffqsmwXFNhPfFhOANrGlOjsvy1P7JDzvymj/90m
|
||||||
|
NomlO3vjxLHOf6MvedTgCB0dRcAoUWPgbxPWifjBmGBjQjA4ukMQ58wbBQgvIoCW
|
||||||
|
obrXmLCNZIkpWTw4gMRYquY880IYK/OuFNJH/dawxx/WzuVr7IdLmbFY15zf5TUb
|
||||||
|
ZpIpwqRCysg=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpQIBAAKCAQEAwOp1RS9RnE8L5TszDPIOmpf/1pqb+ki99l/sGhqB/KZBKCuq
|
||||||
|
uoCc2VPK3PCByBE15/xJ7t691FnJfForI9DO5p2R0FPD6o357hqRsh0dJNBm0VgG
|
||||||
|
iNtLQ8lyYoE72HJbkgCAUZW4N0OBibOmvp/s3Fmr7rEjW5LmZxOtX+iULKIUZ0w6
|
||||||
|
gJlM8G5QA1SuqndN0PbPx+RZKSXZCoJj+Nboqw03nyJUexzs+lynR9ITMziUaaVM
|
||||||
|
4rzG+P6joQAnUkDNydxo/d4tj4xaioZdKxWLYEbj2BUtOlJJydotWo2wcG85ONrT
|
||||||
|
Gw0ltR1vku1hidMm2QL30uGIL5SeqyE8TqWk4QIDAQABAoIBAQCxHtKauc45MA4g
|
||||||
|
4hCGAzvLTmETnRI2YlEfAoTYlpvf5pkOE8GFyI25r4gjACJ4GO0gWG9dBF7Pt7wZ
|
||||||
|
EwRmttEvxV3aIv5OvRnKNdSs7rQSV9D+xc4CGy1oSG1f6X2TxbMzQoiN32OqQa2O
|
||||||
|
S0Z94IFs8lu8JCDtc9tcqiFVXEmnC3RvJZOShWpsCsbmh5ue1Xed0MQQ47vt7Zt7
|
||||||
|
I0cutvwSFJMsZkZUJp5+KjVNYo9TEJxVD3m2NJNJxBfBoRVHXNii3hUEHcTIdIAz
|
||||||
|
omtRwBU8AKgJirGIRo1h2ZFyubI8ScGOJWIiWMQvQqTHKiOaz3yUar1NSG+kFn0U
|
||||||
|
cj7s3FhdAoGBAOQbx8Jwhtp4iOkP6aW1nVTgiaTj4LMlyJZioFwgPFRIcA3oRHt9
|
||||||
|
5SRetmgFZNvcuNw1udfeaObKmlzxwUruprwOpihgAQWJFTtOjQNrt2gsYuX4l3W6
|
||||||
|
T46dO2W1pV+mW4A5gt0aqhLv7pCS4lpreNAqyHSPqcQWcCeiTzmp/LfDAoGBANiB
|
||||||
|
FQOTyMElR9OzKwmcGfIvnhUfJQwi5qNE3R+xXiP5x36a9HQBey5ri2lnBle0Ksr/
|
||||||
|
G+RKoflmk1eFXVHN0w35yw0dVco//WE4vOknldNEnIT85k02ld8lDTa2Q/EJZtPH
|
||||||
|
un6zeU0Q2/4SZ/GXPssEZPlpPM7WtQzztlH3+sqLAoGBAKnhppvAgi4ippQsLa4j
|
||||||
|
29BiiSAsNiQ1d3XIbfUubL+4UvuIh7gQwp6biu1dVwgHEgWuXYHPOgDn0p51zaao
|
||||||
|
pbRYlJZtKVWeChnpHkv15NnIdL8grGwZHTbxElNlPIxHsM2GB1fzi8YeumUhf0In
|
||||||
|
2AnwUum8NIq8yzo5PxeK6ZNRAoGBAIEA2Q6ankJH/nZsCbbeJq+iI+Wd+ysyGI8s
|
||||||
|
Vz2tJ9Tz3iTYG9SLlWRhfF4/nw3fMqhmPa5Xsg+zSRQbSTGXHKz1LEISOq4aVtX5
|
||||||
|
QscCaUnLVh//uRJE9iRSJX92NyGGYpjKJ5ubQSnkY9EOEpVnc2jwo2HhjPQKBzNC
|
||||||
|
fF53Dh5lAoGALwTN5uxrBZLPu4DtZkOosKkv4l+kzFoOjLJR4vA7ONBx2CSe9G7F
|
||||||
|
tSsH7lZS3b0mxBWjO90WhaSvtMWWrfqq8vrqmoTE795fYxNoLfCLK13W31aTDUsI
|
||||||
|
pQRJIL30MPvASbcFHN2MD2dXz2nQzY8C9lvtvap/krYiDKDU2L7+iP8=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC7DCCAdQCBRQHBXNHMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMTEM
|
||||||
|
MAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
|
||||||
|
MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMDd3MxMQwwCgYD
|
||||||
|
VQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA6nVFL1GcTwvlOzMM8g6al//Wmpv6SL32
|
||||||
|
X+waGoH8pkEoK6q6gJzZU8rc8IHIETXn/Enu3r3UWcl8Wisj0M7mnZHQU8Pqjfnu
|
||||||
|
GpGyHR0k0GbRWAaI20tDyXJigTvYcluSAIBRlbg3Q4GJs6a+n+zcWavusSNbkuZn
|
||||||
|
E61f6JQsohRnTDqAmUzwblADVK6qd03Q9s/H5FkpJdkKgmP41uirDTefIlR7HOz6
|
||||||
|
XKdH0hMzOJRppUzivMb4/qOhACdSQM3J3Gj93i2PjFqKhl0rFYtgRuPYFS06UknJ
|
||||||
|
2i1ajbBwbzk42tMbDSW1HW+S7WGJ0ybZAvfS4YgvlJ6rITxOpaThAgMBAAEwDQYJ
|
||||||
|
KoZIhvcNAQEFBQADggEBABPLmq6zKOMY0WRjtBoSymq6f+vXeEwtWCfVejdG6RlG
|
||||||
|
/PTdCKNvp3OL7FDnmQQ+r5rMs4+Os4fX/g315QFKXu01rqxmFb2XVNhhaECdUWtK
|
||||||
|
QP6ZoVZviUiDjhK6a+05aerPCJpkGy/lz0W6gmj4qhuAQbobxb6UbzqTRYY+ZwGk
|
||||||
|
+SI3TAVCdmXFlxN/M9b0DbmkseRG8GGFmyRYyRb84vbV6zemFI++5ROUT9zXT7ey
|
||||||
|
nYfFJvAAk5jJhY5UP2aMlVWYYa4jUZrrPLoiBLUuRrp67EKGebCH9mgCIf8ztNJF
|
||||||
|
fpuvcz++LUeRyTlAGDefe+FyHGIwFzIfZn39D7CaRvM=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEAyal0BZKRYd+Wpxv4MB8LjjgXv/MxSN5oSAKThlCZ/AWG0FEP
|
||||||
|
d4nrBACT2xUxwo+xbYl3joiwL/eCPAp6QNKRGhvXVOnSIFVSjKZWbdX+toqK9pDS
|
||||||
|
QMDTL4ZJvK6pLZXknyHjEr0PxZh22F7iS1+C8HxBPj0Xgg/u5/+jPhFPPZ1d5elv
|
||||||
|
4cm/z+xy6RjFlA80aIeK7dcWssOsOIPjUNFfmoYgR63ScZIlUZj6j8VX9oX7fJID
|
||||||
|
jumGajDxgD2nBWFbHcGKin6bz/wZ+OIhXOCDdY7oKuMW4JiBwbfBtedkQuQYS11s
|
||||||
|
PRFFYDLoZH59Ivcu0c4F2tomE86qM8THsI910wIDAQABAoIBAG55FAQRfO8/C0rU
|
||||||
|
eavy9eOdOvV+hltC66G3N5X3BcQYSvhHz89OkJ6KqnT0MWRCT5KQIhzFKK++SWwW
|
||||||
|
2U41jCPfaKEtzlzEIQrH/MUC3Byn3OSiBWxPteFtEWv5ytgcKzg52iljxQYcNc7m
|
||||||
|
e9WKpzKS/zLXSM+JZvlVA9p2pRA88kUZ/EE5H+FW3kHj5eGNqX+cxUVpL0VKTiLv
|
||||||
|
aXWjYotpmDJW/Rn9wRQethm6Gdx3bvo+LEVlJRELNq8NM5H/tZIVRzudJOgzsw5v
|
||||||
|
3OQGhfKB6Eg/vqSFoZxX6ApXDxmtaSO83B0kK550bDVv4sBnOExGjKCzybt04tet
|
||||||
|
KtLPPoECgYEA5WUD+mFL99sCX6pzIyUVlxp9eUhVy5nvhoF6u3mvhay2XsZUY0wy
|
||||||
|
+/qVqYSZTvuvJ6JSXc4iVIX8u/gj7914805AwujepIF/8E0AaXLBMndzDE4ze5S5
|
||||||
|
2RHI7Cy4/3AWOcQ9wFFmUdSs7/6oAkcQtvzP40hGg3J2jAEhIdCqmbMCgYEA4Q0G
|
||||||
|
BYP9XeTdh0C+BcP9B5VUEC0jerYS8VqVqriB+9JfT3InI7K08sOG2DiQQBhAHuzL
|
||||||
|
RhCECU2a9j0+u5F5JNeY5m3IhU73Lw+lOlUkMaAO6x7JJEzhXhonE7Kv8fWygr/0
|
||||||
|
OB7yzqz+YsWdQ2VOPZ88ntlAYE65vzcaVswZY2ECgYEAr7Gt2VA6Ei0A5Wq0Yr+d
|
||||||
|
iKz2WzUG2TkelqOG8B4kTDrbNz2qFp+fERV9GWgAz9i+75lIgqZF7vzsdL96LtYv
|
||||||
|
NBLEUURwegjhh5hCb4E/7bpFOLCQh9+CdHpFrHYYfzRHIZlnPmxZ9OTyS6J85bmu
|
||||||
|
WKjLRKXvs++wUkzvJmoesDcCgYEAkTOB6xUZ5/a+J4HSGI43NylVr4owFgBbgHVd
|
||||||
|
k2SwGPXGoM+aCSJINUmKOv9jsrbyyAEntfD5/7aegLlLPGHDs82WzTWP5tLoEOkb
|
||||||
|
ReOhEpOejHy0ckNYNQrSo5bqhkZsAogu3fa52jcrejbeHJnEPWX8CtFJA9pHZeP7
|
||||||
|
jnzo9IECgYBefHg0dymSj2xxN0XmC+S5cvQu2K/NYUpatoWvHnPiQ87wIM0AWz0O
|
||||||
|
D0ghEI+Ze57NbtSrrcTE7hY/LHrAqXGAB9XNIM5g9Pp/lM+XjzKVr1FMf4xpuHf1
|
||||||
|
VJJRHrOU14CvMvKbgbPrL6B0d5yrYmeex7GxNw0ZVvtjCa502Eck+w==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC7DCCAdQCBRQHBXNGMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMTEM
|
||||||
|
MAoGA1UEChMDd3MxMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
|
||||||
|
MDgwMzA5MTU0NVoXDTI0MDczMTA5MTU0NVowOjEMMAoGA1UEAxMDd3MxMQwwCgYD
|
||||||
|
VQQKEwN3czExCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJqXQFkpFh35anG/gwHwuOOBe/8zFI3mhI
|
||||||
|
ApOGUJn8BYbQUQ93iesEAJPbFTHCj7FtiXeOiLAv94I8CnpA0pEaG9dU6dIgVVKM
|
||||||
|
plZt1f62ior2kNJAwNMvhkm8rqktleSfIeMSvQ/FmHbYXuJLX4LwfEE+PReCD+7n
|
||||||
|
/6M+EU89nV3l6W/hyb/P7HLpGMWUDzRoh4rt1xayw6w4g+NQ0V+ahiBHrdJxkiVR
|
||||||
|
mPqPxVf2hft8kgOO6YZqMPGAPacFYVsdwYqKfpvP/Bn44iFc4IN1jugq4xbgmIHB
|
||||||
|
t8G152RC5BhLXWw9EUVgMuhkfn0i9y7RzgXa2iYTzqozxMewj3XTAgMBAAEwDQYJ
|
||||||
|
KoZIhvcNAQEFBQADggEBAE20gAykuuaCoP49GnZ/Z6ZItFry4Fl6iCWBDdEsWI9R
|
||||||
|
wRNYumeaeejdFPXfSJdTT7UlrVK1WWGLQLq+ixHRDX+V9T67ou85F92H/OxbUoPr
|
||||||
|
iz/TZAEBTC1GvTJl49lsfPl1dTWH8T4Ej2hxCUvIJrkCkI2Ov4Wwef6A26USrwBt
|
||||||
|
S/CPInjCe6qkE5E8xfTDl8k5IIgMadTPhi5sbV2piBJoN4floJPqR0hdDKbgUymn
|
||||||
|
5WNSiRkuI6UIDZwQEp+A8TmFBHbSwfTGt2Sz5iI27P8J6pFvR5eRA1k57dRUWNXC
|
||||||
|
WAU1nqteP3QAjj9L3o8IO0T62scaiJX8x01gTmVVe2I=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAwXIMpHuTNsro2pxe6y1mu27md2Olhvfx26rO3maO0/stIC2z
|
||||||
|
G/xQatFDLIWzfKFYOT0iSEj252ENFDCw6aDRKpiaUFtXcMAWkNkkKntEyoEgE45k
|
||||||
|
rTrvpay0v0B+ojwjA1Jz/9v35cgvDwTs3vNFno5HhI0m2YF4ocTmeHJ6u0xRL/qy
|
||||||
|
atfKsfuVq5s5CXOYCXp3Ux6kJ1c22J0EdZMvS75SVjAZgRkqQpqt9L3e2ZBCEgUr
|
||||||
|
w0KwlERvpeJF+sJJOshXjfrDzvwL8IpPnGZLJNINFbSJMk5MFGcMyq/28pSZLB9E
|
||||||
|
Dh8vk5D5gUnxM60ONUy2nYPcYr5p1PLDiC8hfQIDAQABAoIBAB0Twpi6xn8W8vdh
|
||||||
|
R9c75NRJsDTD8q6d+GnXe+7sJY3xlG/gzqpnO8NCn0FC+57BNdystsl8xjgzW17s
|
||||||
|
jrsfZDFt7MwlXrhg90NgkFIeY1G5JRQrdDChykHx+t1AmYhTV8P5EdykuNd+RqyQ
|
||||||
|
RfahRJa3tkJTYUKSdoqCaU4zjwU2CSxltuJx24V+WoZE12EwewJ8HPg2XTnbsGE7
|
||||||
|
Fnx5s29O4ItM70CC0536AY/OgfuPix5z573VQiilqqfOQkVkKa1fHd6tGpWU+3kH
|
||||||
|
X9FnhEBf9cN9tVgmaB0sCSVVrfgqSXg1EwKHqe/+FCumuesA68Q35+/K3b+QrNiR
|
||||||
|
ka2yliECgYEA+V/4pbgG/lPYvTwWhKxGXXdJmrSPgZC0mwE+fRuYkeptbIkS0pwt
|
||||||
|
/UDTXk9nttj1f1ZJ3NgQbT/1w8jpXfsCJ8VeGzL9+ADhRKWVFRlu/nyFCMXawLEV
|
||||||
|
rot7SEr8BW/m8moHgY5lYipM3dXJPk0F+KLrN60U/aNmFUtPGW802BkCgYEAxpWy
|
||||||
|
FGL2sEQ0QaRDTcqqF5faVqw+5rVGvN+EX5o26E0QWWnoo3L2c2/5X93iBl+Fqtnm
|
||||||
|
9jSIQUC3rYOawKnZ/HcIE2ergFit/p6JaV9NiLDRtDUmSzlffEGVCj0neYFsnWp5
|
||||||
|
zcmkUyZ6fr19EmKQWfdteNBlXue32TjVlFbfUQUCgYAfMbgi0sBdNBPaqBeRBRPQ
|
||||||
|
QUm9xnRlGrrc4Oz2LWuKZS7G8uad3deK5H8MPxaUMtOS2DJpI8X6RJPzp8A5d1qv
|
||||||
|
quq4sEpAqauEMMpTV1khEGZ70HQqwnwZ12zWgDrCW1siW80QkcVw4CW5YjLITk4+
|
||||||
|
6fJOhqInkDcG1uLQJa8QkQKBgQCfs8l4DbJ4RRGFbLXXvNGXkb68j18yqLxPrq3F
|
||||||
|
OL9JiJhKYBsAP7clVPrG9ykLmQxlP0I35D1jxMkymLD+mlo9Z/itqmTJHggnyZWW
|
||||||
|
kVdIQ3MSKuA2BNjek9tpVY8Gb2hLHFMChVRKrpo6jOclvvB5+bsnOukbLtyyq7tP
|
||||||
|
xaFohQKBgByCmlltjOBWZLFLeA1x8j3inm9zM/FAJuANbHUOZ1RwrRcNFbDv/FXm
|
||||||
|
rLPnPCaH5AwAWhVRJcNHo37Ee0s/xqe+Q4dG4xL943k+6KlopAw1SXhuXF6PnBfF
|
||||||
|
y+ArVlh9d2oWN5cBEzRddnWnKJuMi70kMzYf6dIW9s/dHbq/gFDy
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDlDCCAnygAwIBAgIJAJDtcXU2wiJIMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNV
|
||||||
|
BAMTA3dzMjEMMAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVi
|
||||||
|
bGluMB4XDTE0MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMD
|
||||||
|
d3MyMQwwCgYDVQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZEdWJsaW4w
|
||||||
|
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBcgyke5M2yujanF7rLWa7
|
||||||
|
buZ3Y6WG9/Hbqs7eZo7T+y0gLbMb/FBq0UMshbN8oVg5PSJISPbnYQ0UMLDpoNEq
|
||||||
|
mJpQW1dwwBaQ2SQqe0TKgSATjmStOu+lrLS/QH6iPCMDUnP/2/flyC8PBOze80We
|
||||||
|
jkeEjSbZgXihxOZ4cnq7TFEv+rJq18qx+5WrmzkJc5gJendTHqQnVzbYnQR1ky9L
|
||||||
|
vlJWMBmBGSpCmq30vd7ZkEISBSvDQrCURG+l4kX6wkk6yFeN+sPO/Avwik+cZksk
|
||||||
|
0g0VtIkyTkwUZwzKr/bylJksH0QOHy+TkPmBSfEzrQ41TLadg9xivmnU8sOILyF9
|
||||||
|
AgMBAAGjgZwwgZkwHQYDVR0OBBYEFLK4flD5QD/mRufsPx63xlEKM8pwMGoGA1Ud
|
||||||
|
IwRjMGGAFLK4flD5QD/mRufsPx63xlEKM8pwoT6kPDA6MQwwCgYDVQQDEwN3czIx
|
||||||
|
DDAKBgNVBAoTA3dzMjELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAJDt
|
||||||
|
cXU2wiJIMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEYD+CReikYr
|
||||||
|
Rzvk+/Vdi/7IcaH9CFknIdtineSIw1y98nxnbnNJqxwfNaRblbYvg6OFdUI3POuI
|
||||||
|
+rdYLCFl8z3tWqRHLkGqHSJA9xcng3jLJxz0+ctiVcekJvXaB3O6eSZjhGbmmI/s
|
||||||
|
CQhdy2zpEIVOeUq50DrSJp9CknyGu/IkaGx5GOZtkiHMrpig50CRjX1lS6qrMNYp
|
||||||
|
vB8gfuqpjsL4Ar3vg+lgMSwNWXBNHrIRPHB5VEzBEdmLFZlvueR0ooEMCklpwX/a
|
||||||
|
lFImVc6JcY1pBEkHTiTLGMpGAHG3I1aVUaWb3L+V+2ym/KNRNL5C2+1eiqql5u8m
|
||||||
|
HUaOcNC90ew=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEA0ucemqFwBFziVOgTgx4mZII4WnGDpA/rWAGHvUZOqy2dQ3Pz
|
||||||
|
woGKxBaVPAl5kxEosROVGa7dTuq5yFZ4XIGvwCKxF30vCmdGCytqq6MMp904jG32
|
||||||
|
KikkmjCApIMGxMO4eoBHZZxiyVvKTbg9M2CRXErwnYWhFH/qGdPnuo0CEaHJA4VK
|
||||||
|
A9incT9dpeEhU30R6ajAe/je9rCj2OMLMFSMfd51L/VYfO60zDwUNY7YVIghQZgJ
|
||||||
|
e44EVGsp1pXaqaD6o3PvGY3ohw2aZjJzlJ7MJHbKV9lft98R3pklbpBzMH849cEy
|
||||||
|
Q/51L/rlfTUgCpTy7wEZpWHQNtHfu/1rhJjpNQIDAQABAoIBAQCUNIHXG/dBuZv7
|
||||||
|
GpMLotZL7w520Co30lAJqhmfMpb5x7YpvoPffXTsUwpQBECAzqAPv7kZMT6nxF8F
|
||||||
|
n245Y5EDrd1QqlGyN9yK4Nm2/39XPygL1wITopHsIIVmFgVdpEQxIZAKoZjx8yT4
|
||||||
|
9K1dO1Eq0CbCKzOE2lbCC51eBNUdWZIMxwC6O/j/KoIkZ/HwlG2hpUuXg8x/XawA
|
||||||
|
ZJDCoTcWHCjYP10FxKVN3vAyWM2IM44o9IbsAGEOswR4gUwRsgq6Ehc1U59XUHi+
|
||||||
|
x30oda55I1/8xD+SfP/zk2dDPHkv/hq5+258GU/THsw2+AAexocvSIS/g9EppTEg
|
||||||
|
biFaDKzJAoGBAPqey10JeyiOlHbBjoSSa7lJYUjocQANFQ4ayOAgfNX72iyabrKF
|
||||||
|
p9sVAeO/nM00+DPrm2wWws03ScsPeh+9BDJMPRBUHfSNp7+F+oyj7PWHBEFHbyO9
|
||||||
|
5HnYZP+1vhdG2dYPIY2gRSFXpiGn3j0M1D0w9c7Ilm8ee3krdR4E/mw3AoGBANdu
|
||||||
|
EfS1dK3+m7sEgc2+3U32z83GpuCHeUIKGPYMLI0fIb1CPpboHU9YjOFJZH9iIIdl
|
||||||
|
00JC963O3+pqLe0XbMOmBVt9QjZfhfB+AY+JHtbPgoQVLtq9X/WvW7h3xn6S971r
|
||||||
|
Crkhqay3Cs4BzsgYDYraQCTw3oq4twR9Nuy4etfzAoGAXOsG5wWe3diO/sCggFJx
|
||||||
|
Eg88vHVBgA1ZoxMXKtGgtw1bRHI1XIblRvqw6qmeDw72fvl5dEe0DbXT7C9ezemc
|
||||||
|
ZrGRaj5lpMfoS7/2trIIJrfaQgGkGRJMZUhvmcbeJW8lUJHnlMS5HLWMaKn+YZAi
|
||||||
|
GFXQrMv9ylD44mHUWD7tvV0CgYBNctPfvvCQsQ05ofgsiKa1Jbs1hmpuJCYy2MB6
|
||||||
|
jIvjvEJ78PnhdNc8tGAJikIoDZYWN0RI+RxkDxCvDLcwGpDOkbwxVQnd1F+pwxM6
|
||||||
|
kBhXL8kDRT5QA28hO4bk/aKN1LZeEcKMJg8C+ddXkozNoOAVgDs5TKMlCh057u41
|
||||||
|
EmmPgwKBgQDOlYi7fPYOCy0yjHMxSrp2SZOS06AMWGbbCoGkjRtvuP+FmKSNB+LZ
|
||||||
|
pOSEPJgzjsRutKjneww4LpV6dViAyTcP5JoeQpokHf7UVo7yq2QH/iwF3zJwsC/S
|
||||||
|
OuVLkqpZzWuye/QCH5NOTfw27ye8jG8VcQW2QPbcbkLXLM7zg2yX7g==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC7DCCAdQCBRQHBXNJMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMjEM
|
||||||
|
MAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
|
||||||
|
MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMDd3MyMQwwCgYD
|
||||||
|
VQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDS5x6aoXAEXOJU6BODHiZkgjhacYOkD+tY
|
||||||
|
AYe9Rk6rLZ1Dc/PCgYrEFpU8CXmTESixE5UZrt1O6rnIVnhcga/AIrEXfS8KZ0YL
|
||||||
|
K2qrowyn3TiMbfYqKSSaMICkgwbEw7h6gEdlnGLJW8pNuD0zYJFcSvCdhaEUf+oZ
|
||||||
|
0+e6jQIRockDhUoD2KdxP12l4SFTfRHpqMB7+N72sKPY4wswVIx93nUv9Vh87rTM
|
||||||
|
PBQ1jthUiCFBmAl7jgRUaynWldqpoPqjc+8ZjeiHDZpmMnOUnswkdspX2V+33xHe
|
||||||
|
mSVukHMwfzj1wTJD/nUv+uV9NSAKlPLvARmlYdA20d+7/WuEmOk1AgMBAAEwDQYJ
|
||||||
|
KoZIhvcNAQEFBQADggEBACCCAJypO9DFU6GeOH+FwE0JCLTypHoIwERWxNL7xfjg
|
||||||
|
rwVqIxwAEo+fJjL+QY7JbAb/eqKaXIBYkAF2lFc4iEmecXX/A3Aqw95AYi78o7HD
|
||||||
|
MwRPqJha9mxLcCWwjX8XK8pT152BvYFPNhi+6jd++rDRxKDfmNvgdUQ2/YW6a5Wv
|
||||||
|
zEmLDPUWRIuMQIEmOa2/JhlllDviMExTw51nbqYgCghycRvDACyQAuu8re7P6gcg
|
||||||
|
bXObNlfxcU/8Ph6MFI+2S9ODtQ4BHyuKd4kRNsYn8vV42a0h3bCYSGPk3kSIgxd7
|
||||||
|
XijwHT/o8E9ddH2BvDv+6Nhno9C6/MbezEOIs4nlhRk=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpQIBAAKCAQEA29iFnMf4pjty6knOt4wT0joPUlU2dGCFWxQ5Eg77Yx3Lou2a
|
||||||
|
FOzNGp7zLYH8gauOK+mgY+B9cBv8PvVtUQQKB0SKTTV8ZNKVyP3O5F2gRSJ+tHtT
|
||||||
|
FqaPfG0WPOn/f02YbOpAe6Rk+NnlJoeuBxG4uapUSq7r0mTGJQe+52y1LcMs23ID
|
||||||
|
ENBfDoUMVt5vCnF+cYK5ndeFVLyPO3JjohDH1zv3a9ECG28rtjKHLpNYFDsPJaD7
|
||||||
|
UPuyyk3hIvfPCZoJOUlEVfpLT/lM+9oCPnq9PwIp5NqYofkuc3eKooCo7N4r4IlP
|
||||||
|
Ajktaao6b0ScNwNQB3leOIdEUFSIYy8N1JszVwIDAQABAoIBAFlIvjrGG/2m9yyf
|
||||||
|
fQyeHw6p9b8CTHNHH+G1fNgQrZe7ahBpXsJQyZueIjTBLcOb4MmEwFbPvSHiu7b2
|
||||||
|
Bcd5VHlPJLvmlPZ9b8eJDJVCUOzC7aJu03fHfU6THwzuG42f/d9942JTiY5nL+FO
|
||||||
|
CSdl0xfUTRdnou53buFrG+TxCUPj13HP1HY6DAVzEIq1H4TZwIZo7KRRTIYpTB3P
|
||||||
|
6yvr9xsISLlnmfQ4tp2pApl5o+bHJEhr1VO6SAT/pSyShi79KmMMqYtyTmOMz7w6
|
||||||
|
VJkre5ybnXBDN6tfMHWqdobJ4gRWK9rqf+LIZig5XQnyzkue8k+I7aPgO4xNFh56
|
||||||
|
dkejQcECgYEA9MDCWViqpfvof+epiKzccqnIRnz1EfHdRQjiKsKGRe39+K+pyaqJ
|
||||||
|
FOOPFy3aOw6M4cFWwcdMYzKTItvzyLVhDqMzT5eup/NVqo5tPoy93XPf2qRYiTl4
|
||||||
|
2j5wvm0RVkYEONd3pk2lbfbUmn7XQXj0+AG60SvsqErF/UhIBGec/xsCgYEA5fLC
|
||||||
|
EdiiC98kr4sVaE8G854WI+aAkStqO5YXyrnsMzRsqk8KVVYE1yCC9rYyymDBYmlx
|
||||||
|
uEW+vbWqLc8PO3v4ty3o5ff303lPMWIrvKiUldjqMjS6ncWxsQjU0bygGVgOgHO7
|
||||||
|
c8rjiDH5M0JgWSREYUVFT5mW/5+Y1LVT8mYNlHUCgYEAhMSX6N23XGkFW3Twu2qB
|
||||||
|
/1Vohgw86OoaDNvfzDBPpFmQ3rlz0ijHSeSTd5BxBH5FICXACUgygNErjcphOSxj
|
||||||
|
JQyUxgVTQlo2y1mNm1O/nwS/lxx1xqK9ky4x/Kqvr+w1WBxSFI2kQr2V4OUTobma
|
||||||
|
sXpGvDcmnrhJJLd0EaefO6cCgYEA3Xw/S9tC8nZjqqYn34nHI16Q6tF54tpTf8Np
|
||||||
|
dT4x8Xw8cqqhRGMPVHsfSi1irKYXfwgbnienuqlBmtAHVv9pKF+TJfb7gXkmO2XY
|
||||||
|
xOYIAHGn2uYJHjCun9vmyYKLHv4/MaDH3Jd/I88mviXgEdyp9Js5UJua4utB1Rg3
|
||||||
|
HJMJ34UCgYEAr0PpHEBMbZXZBybNU96+jRTgkrNeJpzlnMy7et2IsRAtLjZ0mpbn
|
||||||
|
NaX8i8eO+ubweqFdhOvbh7Hd0zr7BzrYcUG1e3njhtxJE1MgWL5plnLVUbIyDAm3
|
||||||
|
iBpIHIBASNCN3sqeq+VqXvavRmeZh5O0vyLP46/kxZx0rzR/NCi9xxU=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC7DCCAdQCBRQHBXNIMA0GCSqGSIb3DQEBBQUAMDoxDDAKBgNVBAMTA3dzMjEM
|
||||||
|
MAoGA1UEChMDd3MyMQswCQYDVQQGEwJJRTEPMA0GA1UEBxMGRHVibGluMB4XDTE0
|
||||||
|
MDgwMzA5MTU0OFoXDTI0MDczMTA5MTU0OFowOjEMMAoGA1UEAxMDd3MyMQwwCgYD
|
||||||
|
VQQKEwN3czIxCzAJBgNVBAYTAklFMQ8wDQYDVQQHEwZHYWx3YXkwggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb2IWcx/imO3LqSc63jBPSOg9SVTZ0YIVb
|
||||||
|
FDkSDvtjHcui7ZoU7M0anvMtgfyBq44r6aBj4H1wG/w+9W1RBAoHRIpNNXxk0pXI
|
||||||
|
/c7kXaBFIn60e1MWpo98bRY86f9/TZhs6kB7pGT42eUmh64HEbi5qlRKruvSZMYl
|
||||||
|
B77nbLUtwyzbcgMQ0F8OhQxW3m8KcX5xgrmd14VUvI87cmOiEMfXO/dr0QIbbyu2
|
||||||
|
Mocuk1gUOw8loPtQ+7LKTeEi988Jmgk5SURV+ktP+Uz72gI+er0/Aink2pih+S5z
|
||||||
|
d4qigKjs3ivgiU8COS1pqjpvRJw3A1AHeV44h0RQVIhjLw3UmzNXAgMBAAEwDQYJ
|
||||||
|
KoZIhvcNAQEFBQADggEBALi/RmqeXGazT/WRj9+ZqdcnbcHwK5wwr2/YkpFPJ0Hf
|
||||||
|
ZDm+2vgjDdTT6cJS6fau0M5nliYdz89aQQo1j9RSRZnzlc/2YCFXyRLCOJYaINbj
|
||||||
|
1MEUAvNDGL7xTpepK9hVkXASRkbyNXERXRKFI1N+vpKu6UorT6/osEV/qM+MFJ3s
|
||||||
|
24xE8/J3J4MirVQVt6eY6Jb+tkliOPMIugr6YQlLsqJygEWATP8Qsr81XSfcZhVq
|
||||||
|
rXzVt7QV8dO0nStMjKK5omrtEAhVnASk7w1tFHkpBF1rqXGoo9ML40RnFZ+E5zqi
|
||||||
|
iZtzp+NzzLnEnWMNs+fJpPJ96P0kbq2bQzuSBcUynq0=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
|
// published by the Free Software Foundation. For the terms of this
|
||||||
|
// license, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// You are free to use this software under the terms of the GNU General
|
||||||
|
// Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Alternatively, you can license this software under a commercial
|
||||||
|
// license, as set out in <http://cesanta.com/>.
|
||||||
|
//
|
||||||
|
// $Date: 2014-09-28 05:04:41 UTC $
|
||||||
|
|
||||||
|
#ifndef NS_SKELETON_HEADER_INCLUDED
|
||||||
|
#define NS_SKELETON_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#define NS_SKELETON_VERSION "2.1.0"
|
||||||
|
|
||||||
|
#undef UNICODE // Use ANSI WinAPI functions
|
||||||
|
#undef _UNICODE // Use multibyte encoding on Windows
|
||||||
|
#define _MBCS // Use multibyte encoding on Windows
|
||||||
|
#define _INTEGRAL_MAX_BITS 64 // Enable _stati64() on Windows
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005+
|
||||||
|
#undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
|
||||||
|
#define _XOPEN_SOURCE 600 // For flockfile() on Linux
|
||||||
|
#define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
|
||||||
|
#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
|
||||||
|
#ifndef _LARGEFILE_SOURCE
|
||||||
|
#define _LARGEFILE_SOURCE // Enable fseeko() and ftello() functions
|
||||||
|
#endif
|
||||||
|
#define _FILE_OFFSET_BITS 64 // Enable 64-bit file offsets
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning (disable : 4127) // FD_SET() emits warning, disable it
|
||||||
|
#pragma warning (disable : 4204) // missing c99 support
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "ws2_32.lib") // Linking with winsock library
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
#ifndef EINPROGRESS
|
||||||
|
#define EINPROGRESS WSAEINPROGRESS
|
||||||
|
#endif
|
||||||
|
#ifndef EWOULDBLOCK
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#endif
|
||||||
|
#ifndef __func__
|
||||||
|
#define STRX(x) #x
|
||||||
|
#define STR(x) STRX(x)
|
||||||
|
#define __func__ __FILE__ ":" STR(__LINE__)
|
||||||
|
#endif
|
||||||
|
#ifndef va_copy
|
||||||
|
#define va_copy(x,y) x = y
|
||||||
|
#endif // MINGW #defines va_copy
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
#define sleep(x) Sleep((x) * 1000)
|
||||||
|
#define to64(x) _atoi64(x)
|
||||||
|
typedef int socklen_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
typedef __int64 int64_t;
|
||||||
|
typedef SOCKET sock_t;
|
||||||
|
typedef struct _stati64 ns_stat_t;
|
||||||
|
#ifndef S_ISDIR
|
||||||
|
#define S_ISDIR(x) ((x) & _S_IFDIR)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h> // For inet_pton() when NS_ENABLE_IPV6 is defined
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#define closesocket(x) close(x)
|
||||||
|
#define __cdecl
|
||||||
|
#define INVALID_SOCKET (-1)
|
||||||
|
#define to64(x) strtoll(x, NULL, 10)
|
||||||
|
typedef int sock_t;
|
||||||
|
typedef struct stat ns_stat_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_ENABLE_DEBUG
|
||||||
|
#define DBG(x) do { printf("%-20s ", __func__); printf x; putchar('\n'); \
|
||||||
|
fflush(stdout); } while(0)
|
||||||
|
#else
|
||||||
|
#define DBG(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARRAY_SIZE
|
||||||
|
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_ENABLE_SSL
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#endif
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#else
|
||||||
|
typedef void *SSL;
|
||||||
|
typedef void *SSL_CTX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
union socket_address {
|
||||||
|
struct sockaddr sa;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
#ifdef NS_ENABLE_IPV6
|
||||||
|
struct sockaddr_in6 sin6;
|
||||||
|
#else
|
||||||
|
struct sockaddr sin6;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// Describes chunk of memory
|
||||||
|
struct ns_str {
|
||||||
|
const char *p;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
// IO buffers interface
|
||||||
|
struct iobuf {
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
void iobuf_init(struct iobuf *, size_t initial_size);
|
||||||
|
void iobuf_free(struct iobuf *);
|
||||||
|
size_t iobuf_append(struct iobuf *, const void *data, size_t data_size);
|
||||||
|
void iobuf_remove(struct iobuf *, size_t data_size);
|
||||||
|
void iobuf_resize(struct iobuf *, size_t new_size);
|
||||||
|
|
||||||
|
// Callback function (event handler) prototype, must be defined by user.
|
||||||
|
// Net skeleton will call event handler, passing events defined above.
|
||||||
|
struct ns_connection;
|
||||||
|
typedef void (*ns_callback_t)(struct ns_connection *, int event_num, void *evp);
|
||||||
|
|
||||||
|
// Events. Meaning of event parameter (evp) is given in the comment.
|
||||||
|
#define NS_POLL 0 // Sent to each connection on each call to ns_mgr_poll()
|
||||||
|
#define NS_ACCEPT 1 // New connection accept()-ed. union socket_address *addr
|
||||||
|
#define NS_CONNECT 2 // connect() succeeded or failed. int *success_status
|
||||||
|
#define NS_RECV 3 // Data has benn received. int *num_bytes
|
||||||
|
#define NS_SEND 4 // Data has been written to a socket. int *num_bytes
|
||||||
|
#define NS_CLOSE 5 // Connection is closed. NULL
|
||||||
|
|
||||||
|
|
||||||
|
struct ns_mgr {
|
||||||
|
struct ns_connection *active_connections;
|
||||||
|
const char *hexdump_file; // Debug hexdump file path
|
||||||
|
sock_t ctl[2]; // Socketpair for mg_wakeup()
|
||||||
|
void *user_data; // User data
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ns_connection {
|
||||||
|
struct ns_connection *next, *prev; // ns_mgr::active_connections linkage
|
||||||
|
struct ns_connection *listener; // Set only for accept()-ed connections
|
||||||
|
struct ns_mgr *mgr;
|
||||||
|
|
||||||
|
sock_t sock; // Socket
|
||||||
|
union socket_address sa; // Peer address
|
||||||
|
struct iobuf recv_iobuf; // Received data
|
||||||
|
struct iobuf send_iobuf; // Data scheduled for sending
|
||||||
|
SSL *ssl;
|
||||||
|
SSL_CTX *ssl_ctx;
|
||||||
|
void *user_data; // User-specific data
|
||||||
|
void *proto_data; // Application protocol-specific data
|
||||||
|
time_t last_io_time; // Timestamp of the last socket IO
|
||||||
|
ns_callback_t callback; // Event handler function
|
||||||
|
|
||||||
|
unsigned int flags;
|
||||||
|
#define NSF_FINISHED_SENDING_DATA (1 << 0)
|
||||||
|
#define NSF_BUFFER_BUT_DONT_SEND (1 << 1)
|
||||||
|
#define NSF_SSL_HANDSHAKE_DONE (1 << 2)
|
||||||
|
#define NSF_CONNECTING (1 << 3)
|
||||||
|
#define NSF_CLOSE_IMMEDIATELY (1 << 4)
|
||||||
|
#define NSF_WANT_READ (1 << 5)
|
||||||
|
#define NSF_WANT_WRITE (1 << 6)
|
||||||
|
#define NSF_LISTENING (1 << 7)
|
||||||
|
#define NSF_UDP (1 << 8)
|
||||||
|
|
||||||
|
#define NSF_USER_1 (1 << 20)
|
||||||
|
#define NSF_USER_2 (1 << 21)
|
||||||
|
#define NSF_USER_3 (1 << 22)
|
||||||
|
#define NSF_USER_4 (1 << 23)
|
||||||
|
#define NSF_USER_5 (1 << 24)
|
||||||
|
#define NSF_USER_6 (1 << 25)
|
||||||
|
};
|
||||||
|
|
||||||
|
void ns_mgr_init(struct ns_mgr *, void *user_data);
|
||||||
|
void ns_mgr_free(struct ns_mgr *);
|
||||||
|
time_t ns_mgr_poll(struct ns_mgr *, int milli);
|
||||||
|
void ns_broadcast(struct ns_mgr *, ns_callback_t, void *, size_t);
|
||||||
|
|
||||||
|
struct ns_connection *ns_next(struct ns_mgr *, struct ns_connection *);
|
||||||
|
struct ns_connection *ns_add_sock(struct ns_mgr *, sock_t,
|
||||||
|
ns_callback_t, void *);
|
||||||
|
struct ns_connection *ns_bind(struct ns_mgr *, const char *,
|
||||||
|
ns_callback_t, void *);
|
||||||
|
struct ns_connection *ns_connect(struct ns_mgr *, const char *,
|
||||||
|
ns_callback_t, void *);
|
||||||
|
|
||||||
|
int ns_send(struct ns_connection *, const void *buf, int len);
|
||||||
|
int ns_printf(struct ns_connection *, const char *fmt, ...);
|
||||||
|
int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
void *ns_start_thread(void *(*f)(void *), void *p);
|
||||||
|
int ns_socketpair(sock_t [2]);
|
||||||
|
int ns_socketpair2(sock_t [2], int sock_type); // SOCK_STREAM or SOCK_DGRAM
|
||||||
|
void ns_set_close_on_exec(sock_t);
|
||||||
|
void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
|
||||||
|
int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
|
||||||
|
int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
||||||
|
int ns_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif // NS_SKELETON_HEADER_INCLUDED
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
|
// published by the Free Software Foundation. For the terms of this
|
||||||
|
// license, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// You are free to use this software under the terms of the GNU General
|
||||||
|
// Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Alternatively, you can license this software under a commercial
|
||||||
|
// license, as set out in <http://cesanta.com/products.html>.
|
||||||
|
//
|
||||||
|
// $Date$
|
||||||
|
|
||||||
|
#include "net_skeleton.h"
|
||||||
|
#include "ssl_wrapper.h"
|
||||||
|
|
||||||
|
static void ev_handler(struct ns_connection *nc, int ev, void *p) {
|
||||||
|
const char *target_addr = (const char *) nc->mgr->user_data;
|
||||||
|
struct ns_connection *pc = (struct ns_connection *) nc->user_data;
|
||||||
|
struct iobuf *io = &nc->recv_iobuf;
|
||||||
|
|
||||||
|
(void) p;
|
||||||
|
switch (ev) {
|
||||||
|
case NS_ACCEPT:
|
||||||
|
// Create a connection to the target, and interlink both connections
|
||||||
|
nc->user_data = ns_connect(nc->mgr, target_addr, ev_handler, nc);
|
||||||
|
if (nc->user_data == NULL) {
|
||||||
|
nc->flags |= NSF_CLOSE_IMMEDIATELY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NS_CLOSE:
|
||||||
|
// If either connection closes, unlink them and shedule closing
|
||||||
|
if (pc != NULL) {
|
||||||
|
pc->flags |= NSF_FINISHED_SENDING_DATA;
|
||||||
|
pc->user_data = NULL;
|
||||||
|
}
|
||||||
|
nc->user_data = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NS_RECV:
|
||||||
|
// Forward arrived data to the other connection, and discard from buffer
|
||||||
|
if (pc != NULL) {
|
||||||
|
ns_send(pc, io->buf, io->len);
|
||||||
|
iobuf_remove(io, io->len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ssl_wrapper_init(const char *local_addr, const char *target_addr,
|
||||||
|
const char **err_msg) {
|
||||||
|
struct ns_mgr *mgr = (struct ns_mgr *) calloc(1, sizeof(mgr[0]));
|
||||||
|
*err_msg = NULL;
|
||||||
|
|
||||||
|
if (mgr == NULL) {
|
||||||
|
*err_msg = "malloc failed";
|
||||||
|
} else {
|
||||||
|
ns_mgr_init(mgr, (void *) target_addr);
|
||||||
|
if (ns_bind(mgr, local_addr, ev_handler, NULL) == NULL) {
|
||||||
|
*err_msg = "ns_bind() failed: bad listening_port";
|
||||||
|
ns_mgr_free(mgr);
|
||||||
|
free(mgr);
|
||||||
|
mgr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_wrapper_serve(void *param, volatile int *quit) {
|
||||||
|
struct ns_mgr *mgr = (struct ns_mgr *) param;
|
||||||
|
|
||||||
|
while (*quit == 0) {
|
||||||
|
ns_mgr_poll(mgr, 1000);
|
||||||
|
}
|
||||||
|
ns_mgr_free(mgr);
|
||||||
|
free(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SSL_WRAPPER_USE_AS_LIBRARY
|
||||||
|
static int s_received_signal = 0;
|
||||||
|
|
||||||
|
static void signal_handler(int sig_num) {
|
||||||
|
signal(sig_num, signal_handler);
|
||||||
|
s_received_signal = sig_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_usage_and_exit(const char *prog) {
|
||||||
|
fprintf(stderr, "Usage: %s <listening_address> <target_address>\n", prog);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
void *wrapper;
|
||||||
|
const char *err_msg;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
show_usage_and_exit(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup signal handlers
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
if ((wrapper = ssl_wrapper_init(argv[1], argv[2], &err_msg)) == NULL) {
|
||||||
|
fprintf(stderr, "Error: %s\n", err_msg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
ssl_wrapper_serve(wrapper, &s_received_signal);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif // SSL_WRAPPER_USE_AS_LIBRARY
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
|
// published by the Free Software Foundation. For the terms of this
|
||||||
|
// license, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// You are free to use this software under the terms of the GNU General
|
||||||
|
// Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Alternatively, you can license this software under a commercial
|
||||||
|
// license, as set out in <http://cesanta.com/products.html>.
|
||||||
|
//
|
||||||
|
// $Date$
|
||||||
|
|
||||||
|
#ifndef SSL_WRAPPER_HEADER_INCLUDED
|
||||||
|
#define SSL_WRAPPER_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
void *ssl_wrapper_init(const char *listen_addr, const char *target_addr,
|
||||||
|
const char **err_msg);
|
||||||
|
void ssl_wrapper_serve(void *, volatile int *stop_marker);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif // SSL_WRAPPER_HEADER_INCLUDED
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
// Copyright (c) 2014 Cesanta Software
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This example demostrates proxying of WebSocket traffic, regardless of the
|
||||||
|
// protocol (ws:// or wss://).
|
||||||
|
// To use this example:
|
||||||
|
// 1. configure your browser to use a proxy on port 2014
|
||||||
|
// 2. import certs/ws1_ca.pem and certs/ws2_ca.pem into the trusted
|
||||||
|
// certificates list on your browser
|
||||||
|
// 3. make && ./ws_ssl
|
||||||
|
// 4. Point your browser to http://ws_ssl.com
|
||||||
|
// A page with 4 sections should appear, showing websocket echoes
|
||||||
|
|
||||||
|
#include "net_skeleton.h"
|
||||||
|
#include "mongoose.h"
|
||||||
|
#include "ssl_wrapper.h"
|
||||||
|
|
||||||
|
#define S1_PEM "certs/ws1_server.pem"
|
||||||
|
#define C1_PEM "certs/ws1_client.pem"
|
||||||
|
#define CA1_PEM "certs/ws1_ca.pem"
|
||||||
|
#define S2_PEM "certs/ws2_server.pem"
|
||||||
|
#define C2_PEM "certs/ws2_client.pem"
|
||||||
|
#define CA2_PEM "certs/ws2_ca.pem"
|
||||||
|
|
||||||
|
struct config {
|
||||||
|
const char *uri;
|
||||||
|
const char *wrapper_server_addr;
|
||||||
|
const char *wrapper_client_addr;
|
||||||
|
const char *target_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config s_wrappers[] = {
|
||||||
|
{
|
||||||
|
"ws1:80",
|
||||||
|
"tcp://127.0.0.1:7001",
|
||||||
|
"tcp://127.0.0.1:7001",
|
||||||
|
"tcp://127.0.0.1:9001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ws1:443",
|
||||||
|
"ssl://127.0.0.1:7002:" S1_PEM,
|
||||||
|
"tcp://127.0.0.1:7002",
|
||||||
|
"tcp://127.0.0.1:9001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ws2:80",
|
||||||
|
"tcp://127.0.0.1:7003",
|
||||||
|
"tcp://127.0.0.1:7003",
|
||||||
|
"ssl://127.0.0.1:9002:" C2_PEM ":" CA2_PEM
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ws2:443",
|
||||||
|
"ssl://127.0.0.1:7004:" S2_PEM,
|
||||||
|
"tcp://127.0.0.1:7004",
|
||||||
|
"ssl://127.0.0.1:9002:" C2_PEM ":" CA2_PEM
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int s_received_signal = 0;
|
||||||
|
|
||||||
|
static void signal_handler(int sig_num) {
|
||||||
|
signal(sig_num, signal_handler);
|
||||||
|
s_received_signal = sig_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (ev) {
|
||||||
|
case MG_AUTH:
|
||||||
|
return MG_TRUE;
|
||||||
|
|
||||||
|
case MG_REQUEST:
|
||||||
|
printf("==> [%s] [%s]\n", conn->request_method, conn->uri);
|
||||||
|
|
||||||
|
if (strcmp(conn->request_method, "CONNECT") == 0) {
|
||||||
|
// Iterate over configured wrappers, see if we can use one of them
|
||||||
|
for (i = 0; i < (int) ARRAY_SIZE(s_wrappers); i++) {
|
||||||
|
if (strcmp(conn->uri, s_wrappers[i].uri) == 0) {
|
||||||
|
mg_forward(conn, s_wrappers[i].wrapper_client_addr);
|
||||||
|
return MG_MORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No suitable wrappers found. Disallow that CONNECT request.
|
||||||
|
mg_send_status(conn, 405);
|
||||||
|
return MG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a CONNECT request, serve HTML file.
|
||||||
|
mg_send_file(conn, "ws_ssl.html", NULL);
|
||||||
|
return MG_MORE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ws_handler(struct mg_connection *conn, enum mg_event ev) {
|
||||||
|
switch (ev) {
|
||||||
|
case MG_AUTH:
|
||||||
|
return MG_TRUE;
|
||||||
|
case MG_REQUEST:
|
||||||
|
if (conn->is_websocket) {
|
||||||
|
// Simple websocket echo server
|
||||||
|
mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT,
|
||||||
|
conn->content, conn->content_len);
|
||||||
|
} else {
|
||||||
|
mg_printf_data(conn, "%s", "websocket connection expected");
|
||||||
|
}
|
||||||
|
return MG_TRUE;
|
||||||
|
default:
|
||||||
|
return MG_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *serve_thread_func(void *param) {
|
||||||
|
struct mg_server *server = (struct mg_server *) param;
|
||||||
|
printf("Listening on port %s\n", mg_get_option(server, "listening_port"));
|
||||||
|
while (s_received_signal == 0) {
|
||||||
|
mg_poll_server(server, 1000);
|
||||||
|
}
|
||||||
|
mg_destroy_server(&server);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *wrapper_thread_func(void *param) {
|
||||||
|
struct config *c = (struct config *) param;
|
||||||
|
const char *err_msg;
|
||||||
|
void *wrapper;
|
||||||
|
|
||||||
|
wrapper = ssl_wrapper_init(c->wrapper_server_addr, c->target_addr, &err_msg);
|
||||||
|
if (wrapper == NULL) {
|
||||||
|
fprintf(stderr, "Error: %s\n", err_msg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
//((struct ns_mgr *) wrapper)->hexdump_file = "/dev/stderr";
|
||||||
|
ssl_wrapper_serve(wrapper, &s_received_signal);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct mg_server *proxy_server = mg_create_server(NULL, ev_handler);
|
||||||
|
struct mg_server *ws1_server = mg_create_server(NULL, ws_handler);
|
||||||
|
struct mg_server *ws2_server = mg_create_server(NULL, ws_handler);
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
((struct ns_mgr *) proxy_server)->hexdump_file = "/dev/stderr";
|
||||||
|
|
||||||
|
// Configure proxy server to listen on port 2014
|
||||||
|
mg_set_option(proxy_server, "listening_port", "2014");
|
||||||
|
//mg_set_option(proxy_server, "enable_proxy", "yes");
|
||||||
|
|
||||||
|
// Configure two websocket echo servers:
|
||||||
|
// ws1 is WS, listening on 9001
|
||||||
|
// ws2 is WSS, listening on 9002
|
||||||
|
// Note that HTML page thinks that ws1 is WSS, and ws2 is WS,
|
||||||
|
// where in reality it is vice versa and proxy server makes the decision.
|
||||||
|
mg_set_option(ws1_server, "listening_port", "tcp://127.0.0.1:9001");
|
||||||
|
mg_set_option(ws2_server, "listening_port",
|
||||||
|
"ssl://127.0.0.1:9002:" S2_PEM ":" CA2_PEM);
|
||||||
|
|
||||||
|
// Setup signal handlers
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
// Start SSL wrappers, each in it's own thread
|
||||||
|
for (i = 0; i < ARRAY_SIZE(s_wrappers); i++) {
|
||||||
|
ns_start_thread(wrapper_thread_func, &s_wrappers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start websocket servers in separate threads
|
||||||
|
mg_start_thread(serve_thread_func, ws1_server);
|
||||||
|
mg_start_thread(serve_thread_func, ws2_server);
|
||||||
|
|
||||||
|
// Finally, start proxy server in this thread: this call blocks
|
||||||
|
serve_thread_func(proxy_server);
|
||||||
|
|
||||||
|
printf("Existing on signal %d\n", s_received_signal);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Websocket Proxy SSL Test</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script>
|
||||||
|
window.onload = function() {
|
||||||
|
var protocols = ['ws://', 'wss://'];
|
||||||
|
var websocketServers = ['ws1', 'ws2'];
|
||||||
|
//protocols = ['wss://'];
|
||||||
|
//websocketServers = ['ws1']
|
||||||
|
|
||||||
|
var createWebsocketConnection = function(proto, server) {
|
||||||
|
var conn = new WebSocket(proto + server);
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
var h2 = document.createElement('h2');
|
||||||
|
h2.innerHTML = 'Connection to ' + proto + server;
|
||||||
|
document.body.appendChild(h2);
|
||||||
|
document.body.appendChild(div);
|
||||||
|
|
||||||
|
conn.onmessage = function(ev) {
|
||||||
|
var el = document.createElement('div');
|
||||||
|
el.innerHTML = 'websocket message: ' + ev.data;
|
||||||
|
div.appendChild(el);
|
||||||
|
// Keep only last 5 messages in the list
|
||||||
|
while (div.childNodes.length > 5) div.removeChild(div.firstChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send some string to the websocket connection periodically.
|
||||||
|
// websocket server much echo it back.
|
||||||
|
window.setInterval(function() { conn.send(Math.random()); }, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < protocols.length; i++) {
|
||||||
|
for (var j = 0; j < websocketServers.length; j++) {
|
||||||
|
createWebsocketConnection(protocols[i], websocketServers[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
body > div {
|
||||||
|
border: 1px solid #ccc; background: #f0f0f0; padding: 0 1em;
|
||||||
|
margin: 0 2em; min-height: 4em; max-width: 40em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+675
-482
File diff suppressed because it is too large.
Load diff
+15
-9
@@ -15,12 +15,12 @@
|
|||||||
// Alternatively, you can license this library under a commercial
|
// Alternatively, you can license this library under a commercial
|
||||||
// license, as set out in <http://cesanta.com/>.
|
// license, as set out in <http://cesanta.com/>.
|
||||||
//
|
//
|
||||||
// NOTE: Detailed API documentation is at http://cesanta.com/#docs
|
// $Date: 2014-09-09 17:07:55 UTC $
|
||||||
|
|
||||||
#ifndef MONGOOSE_HEADER_INCLUDED
|
#ifndef MONGOOSE_HEADER_INCLUDED
|
||||||
#define MONGOOSE_HEADER_INCLUDED
|
#define MONGOOSE_HEADER_INCLUDED
|
||||||
|
|
||||||
#define MONGOOSE_VERSION "5.4"
|
#define MONGOOSE_VERSION "5.5"
|
||||||
|
|
||||||
#include <stdio.h> // required for FILE
|
#include <stdio.h> // required for FILE
|
||||||
#include <stddef.h> // required for size_t
|
#include <stddef.h> // required for size_t
|
||||||
@@ -55,7 +55,7 @@ struct mg_connection {
|
|||||||
int wsbits; // First byte of the websocket frame
|
int wsbits; // First byte of the websocket frame
|
||||||
void *server_param; // Parameter passed to mg_add_uri_handler()
|
void *server_param; // Parameter passed to mg_add_uri_handler()
|
||||||
void *connection_param; // Placeholder for connection-specific data
|
void *connection_param; // Placeholder for connection-specific data
|
||||||
void *callback_param; // Needed by mg_iterate_over_connections()
|
void *callback_param;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mg_server; // Opaque structure describing server instance
|
struct mg_server; // Opaque structure describing server instance
|
||||||
@@ -66,6 +66,9 @@ enum mg_event {
|
|||||||
MG_AUTH, // If callback returns MG_FALSE, authentication fails
|
MG_AUTH, // If callback returns MG_FALSE, authentication fails
|
||||||
MG_REQUEST, // If callback returns MG_FALSE, Mongoose continues with req
|
MG_REQUEST, // If callback returns MG_FALSE, Mongoose continues with req
|
||||||
MG_REPLY, // If callback returns MG_FALSE, Mongoose closes connection
|
MG_REPLY, // If callback returns MG_FALSE, Mongoose closes connection
|
||||||
|
MG_RECV, // Mongoose has received POST data chunk.
|
||||||
|
// Callback should return a number of bytes to discard from
|
||||||
|
// the receive buffer, or -1 to close the connection.
|
||||||
MG_CLOSE, // Connection is closed, callback return value is ignored
|
MG_CLOSE, // Connection is closed, callback return value is ignored
|
||||||
MG_WS_HANDSHAKE, // New websocket connection, handshake request
|
MG_WS_HANDSHAKE, // New websocket connection, handshake request
|
||||||
MG_WS_CONNECT, // New websocket connection established
|
MG_WS_CONNECT, // New websocket connection established
|
||||||
@@ -90,13 +93,11 @@ const char *mg_set_option(struct mg_server *, const char *opt, const char *val);
|
|||||||
int mg_poll_server(struct mg_server *, int milliseconds);
|
int mg_poll_server(struct mg_server *, int milliseconds);
|
||||||
const char **mg_get_valid_option_names(void);
|
const char **mg_get_valid_option_names(void);
|
||||||
const char *mg_get_option(const struct mg_server *server, const char *name);
|
const char *mg_get_option(const struct mg_server *server, const char *name);
|
||||||
void mg_set_listening_socket(struct mg_server *, int sock);
|
void mg_copy_listeners(struct mg_server *from, struct mg_server *to);
|
||||||
int mg_get_listening_socket(struct mg_server *);
|
|
||||||
void mg_iterate_over_connections(struct mg_server *, mg_handler_t, void *);
|
|
||||||
struct mg_connection *mg_next(struct mg_server *, struct mg_connection *);
|
struct mg_connection *mg_next(struct mg_server *, struct mg_connection *);
|
||||||
void mg_wakeup_server(struct mg_server *);
|
void mg_wakeup_server(struct mg_server *);
|
||||||
void mg_wakeup_server_ex(struct mg_server *, mg_handler_t, const char *, ...);
|
void mg_wakeup_server_ex(struct mg_server *, mg_handler_t, const char *, ...);
|
||||||
struct mg_connection *mg_connect(struct mg_server *, const char *, int, int);
|
struct mg_connection *mg_connect(struct mg_server *, const char *);
|
||||||
|
|
||||||
// Connection management functions
|
// Connection management functions
|
||||||
void mg_send_status(struct mg_connection *, int status_code);
|
void mg_send_status(struct mg_connection *, int status_code);
|
||||||
@@ -111,7 +112,8 @@ size_t mg_websocket_write(struct mg_connection *, int opcode,
|
|||||||
size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
|
size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
|
|
||||||
void mg_send_file(struct mg_connection *, const char *path);
|
void mg_send_file(struct mg_connection *, const char *path, const char *);
|
||||||
|
void mg_send_file_data(struct mg_connection *, int fd);
|
||||||
|
|
||||||
const char *mg_get_header(const struct mg_connection *, const char *name);
|
const char *mg_get_header(const struct mg_connection *, const char *name);
|
||||||
const char *mg_get_mime_type(const char *name, const char *default_mime_type);
|
const char *mg_get_mime_type(const char *name, const char *default_mime_type);
|
||||||
@@ -123,6 +125,7 @@ int mg_parse_multipart(const char *buf, int buf_len,
|
|||||||
char *file_name, int file_name_len,
|
char *file_name, int file_name_len,
|
||||||
const char **data, int *data_len);
|
const char **data, int *data_len);
|
||||||
|
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
void *mg_start_thread(void *(*func)(void *), void *param);
|
void *mg_start_thread(void *(*func)(void *), void *param);
|
||||||
char *mg_md5(char buf[33], ...);
|
char *mg_md5(char buf[33], ...);
|
||||||
@@ -130,6 +133,10 @@ int mg_authorize_digest(struct mg_connection *c, FILE *fp);
|
|||||||
int mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len);
|
int mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len);
|
||||||
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int);
|
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int);
|
||||||
int mg_terminate_ssl(struct mg_connection *c, const char *cert);
|
int mg_terminate_ssl(struct mg_connection *c, const char *cert);
|
||||||
|
int mg_forward(struct mg_connection *c, const char *addr);
|
||||||
|
void *mg_mmap(FILE *fp, size_t size);
|
||||||
|
void mg_munmap(void *p, size_t size);
|
||||||
|
|
||||||
|
|
||||||
// Templates support
|
// Templates support
|
||||||
struct mg_expansion {
|
struct mg_expansion {
|
||||||
@@ -139,7 +146,6 @@ struct mg_expansion {
|
|||||||
void mg_template(struct mg_connection *, const char *text,
|
void mg_template(struct mg_connection *, const char *text,
|
||||||
struct mg_expansion *expansions);
|
struct mg_expansion *expansions);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|||||||
File renamed without changes.
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2014 Cesanta Software
|
||||||
|
# All rights reserved
|
||||||
|
|
||||||
|
PROG = unit_test
|
||||||
|
PROF_FLAGS = -fprofile-arcs -ftest-coverage -g -O0 -DGUI
|
||||||
|
CFLAGS = -W -Wall -pthread -I.. $(PROF_FLAGS) $(CFLAGS_EXTRA)
|
||||||
|
SOURCES = $(PROG).c
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
./$(PROG)
|
||||||
|
gcov -b $(PROG).c | egrep '^(File|Lines)'
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) Makefile ../mongoose.c clean
|
||||||
|
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS) -ldl -lssl
|
||||||
|
|
||||||
|
win:
|
||||||
|
wine cl $(SOURCES) /MD /nologo /DNDEBUG /O1 /Fe$(PROG).exe
|
||||||
|
wine $(PROG).exe
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib *.gc*
|
||||||
@@ -396,9 +396,9 @@ static const char *test_server(void) {
|
|||||||
ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL);
|
ASSERT(mg_set_option(server, "listening_port", LISTENING_ADDR) == NULL);
|
||||||
ASSERT(mg_set_option(server, "document_root", ".") == NULL);
|
ASSERT(mg_set_option(server, "document_root", ".") == NULL);
|
||||||
|
|
||||||
ASSERT((conn = mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0)) != NULL);
|
ASSERT((conn = mg_connect(server, "127.0.0.1:" HTTP_PORT)) != NULL);
|
||||||
conn->connection_param = buf1;
|
conn->connection_param = buf1;
|
||||||
ASSERT((conn = mg_connect(server, "127.0.0.1", atoi(HTTP_PORT), 0)) != NULL);
|
ASSERT((conn = mg_connect(server, "127.0.0.1:" HTTP_PORT)) != NULL);
|
||||||
conn->connection_param = buf2;
|
conn->connection_param = buf2;
|
||||||
|
|
||||||
{ int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
|
{ int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
|
||||||
@@ -483,7 +483,7 @@ static const char *test_mg_set_option(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *test_rewrites(void) {
|
static const char *test_rewrites(void) {
|
||||||
char buf1[100] = "xx";
|
char buf1[100] = "xx", addr[50];
|
||||||
struct mg_server *server = mg_create_server(NULL, evh2);
|
struct mg_server *server = mg_create_server(NULL, evh2);
|
||||||
struct mg_connection *conn;
|
struct mg_connection *conn;
|
||||||
const char *port;
|
const char *port;
|
||||||
@@ -492,7 +492,8 @@ static const char *test_rewrites(void) {
|
|||||||
ASSERT(mg_set_option(server, "document_root", ".") == NULL);
|
ASSERT(mg_set_option(server, "document_root", ".") == NULL);
|
||||||
ASSERT(mg_set_option(server, "url_rewrites", "/xx=unit_test.c") == NULL);
|
ASSERT(mg_set_option(server, "url_rewrites", "/xx=unit_test.c") == NULL);
|
||||||
ASSERT((port = mg_get_option(server, "listening_port")) != NULL);
|
ASSERT((port = mg_get_option(server, "listening_port")) != NULL);
|
||||||
ASSERT((conn = mg_connect(server, "127.0.0.1", atoi(port), 0)) != NULL);
|
snprintf(addr, sizeof(addr), "127.0.0.1:%s", port);
|
||||||
|
ASSERT((conn = mg_connect(server, addr)) != NULL);
|
||||||
conn->connection_param = buf1;
|
conn->connection_param = buf1;
|
||||||
|
|
||||||
{ int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
|
{ int i; for (i = 0; i < 50; i++) mg_poll_server(server, 1); }
|
||||||
Reference in new issue
Block a user