mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63be1ebd38 | ||
|
|
796dc18cfb | ||
|
|
14e116553f | ||
|
|
c82ccd6cf7 | ||
|
|
0adb080319 | ||
|
|
dbb38fffae | ||
|
|
672a68219a | ||
|
|
22cb0efd00 | ||
|
|
a68d3d63b2 | ||
|
|
cf48c7280a | ||
|
|
1295973028 | ||
|
|
d5b9eda0f2 | ||
|
|
41c078d25c | ||
|
|
5614224e7d | ||
|
|
9ba44cb0d5 | ||
|
|
c18828af7b | ||
|
|
8a5f8439b4 | ||
|
|
8f0374569e | ||
|
|
09dde636d2 | ||
|
|
d347247bf3 | ||
|
|
a6c66fb669 | ||
|
|
b4dbc825b1 | ||
|
|
4a0cc8223e | ||
|
|
7db10857b3 | ||
|
|
7e927b43ad | ||
|
|
9eea072f2a | ||
|
|
aa2ff674db | ||
|
|
de24bfdf2f | ||
|
|
2a084c3d98 | ||
|
|
db8df41396 | ||
|
|
bda05d9372 | ||
|
|
59bc2af4d6 | ||
|
|
00a23ee330 | ||
|
|
51ad50a641 | ||
|
|
148e1926e8 | ||
|
|
96c023df41 | ||
|
|
44f37f49a1 | ||
|
|
a8a30f6d3f | ||
|
|
ba80b1cd55 | ||
|
|
b56e985ccc | ||
|
|
67521fd9f6 | ||
|
|
8c394f44b8 | ||
|
|
77b4fff268 | ||
|
|
f56a0c6075 | ||
|
|
9ce8486059 | ||
|
|
04a321150a | ||
|
|
d333c3c09e |
No files matched your search
@@ -0,0 +1,8 @@
|
|||||||
|
People who have agreed to the
|
||||||
|
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
|
||||||
|
can make contributions. Note that the CLA isn't a copyright
|
||||||
|
_assigment_ but rather a copyright _license_.
|
||||||
|
You retain the copyright on your contributions.
|
||||||
|
|
||||||
|
We follow the Google C/C++ style guide: https://google.github.io/styleguide/cppguide.html
|
||||||
|
We'd appreciate if your contribution follows the same style guide.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
||||||
Copyright (c) 2013-2015 Cesanta Software Limited
|
Copyright (c) 2013-2016 Cesanta Software Limited
|
||||||
All rights reserved
|
All rights reserved
|
||||||
|
|
||||||
This software is dual-licensed: you can redistribute it and/or modify
|
This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# <img src="http://www.cesanta.com/hubfs/www.cesanta.com/Images/mongoose_library.png" width="64" height="64"> Mongoose - Embedded Web Server
|
# <img src="http://www.cesanta.com/hubfs/www.cesanta.com/Images/mongoose_library.png" width="64" height="64"> Mongoose - Embedded Web Server / Embedded Networking Library
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -14,13 +14,19 @@ Mongoose helps developers to manage the complexity of network programming
|
|||||||
and let them concentrate on the logic, saving time and money.
|
and let them concentrate on the logic, saving time and money.
|
||||||
|
|
||||||
- [Download Mongoose Source Code here](http://hubs.ly/H01bWvx0)
|
- [Download Mongoose Source Code here](http://hubs.ly/H01bWvx0)
|
||||||
- [Ask questions on support forum](http://forum.cesanta.com/index.php?p=/categories/mongoose)
|
- [Check our latest releases] (https://github.com/cesanta/mongoose/releases)
|
||||||
- [Read User Guide and API reference](https://docs.cesanta.com/mongoose)
|
- [Read User Guide and API reference](https://docs.cesanta.com/mongoose)
|
||||||
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
|
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
|
||||||
|
|
||||||
> Nothing overdone. Nothing less. So unbelievably easy to use.
|
> Nothing overdone. Nothing less. So unbelievably easy to use.
|
||||||
> Just how good software should be! -- Pritin Tyagaraj, SAP
|
> Just how good software should be! -- Pritin Tyagaraj, SAP
|
||||||
|
|
||||||
|
If you are looking for a complete IoT platform with firmware and cloud compotent, check out [Smart.js.] (https://github.com/cesanta/smart.js)
|
||||||
|
|
||||||
|
# Support
|
||||||
|
- [Support Forum - Ask your technical questions here] (http://forum.cesanta.com/index.php?p=/categories/smart-js)
|
||||||
|
- [Chat - Visit www.cesanta.com for our live chat] (http://www.cesanta.com)
|
||||||
|
- [Commercial one-to-one support - Available to all commercial license holders] (https://www.cesanta.com/services-support)
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
@@ -32,7 +38,7 @@ and let them concentrate on the logic, saving time and money.
|
|||||||
* Builtin protocols:
|
* Builtin protocols:
|
||||||
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
|
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
|
||||||
- HTTP client, HTTP server
|
- HTTP client, HTTP server
|
||||||
- Websocket client, Websocket server
|
- WebSocket client, WebSocket server
|
||||||
- JSON-RPC client, JSON-RPC server
|
- JSON-RPC client, JSON-RPC server
|
||||||
- MQTT client, MQTT broker
|
- MQTT client, MQTT broker
|
||||||
- CoAP client, CoAP server
|
- CoAP client, CoAP server
|
||||||
@@ -43,7 +49,16 @@ and let them concentrate on the logic, saving time and money.
|
|||||||
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
|
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
|
||||||
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
|
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
|
||||||
files to your build tree
|
files to your build tree
|
||||||
* Extensively tested and production-ready, trusted by many blue chip businesses
|
|
||||||
|
# Licensing
|
||||||
|
|
||||||
|
Mongoose is released under commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses.
|
||||||
|
|
||||||
|
Commercial Projects:
|
||||||
|
Once your project becomes commercialised GPLv2 licensing dictates that you need to either open your source fully or purchase a commercial license. Cesanta offer full, royalty-free commercial licenses without any GPL restrictions. If your needs require a custom license, we’d be happy to work on a solution with you. [Contact us for pricing.] (https://www.cesanta.com/contact)
|
||||||
|
|
||||||
|
Prototyping:
|
||||||
|
While your project is still in prototyping stage and not for sale, you can use Mongoose’s open source code without license restrictions.
|
||||||
|
|
||||||
# Dashboard Example
|
# Dashboard Example
|
||||||
|
|
||||||
@@ -58,47 +73,6 @@ the functionality:
|
|||||||
|
|
||||||
# Contributions
|
# Contributions
|
||||||
|
|
||||||
People who have agreed to the
|
People who have agreed to the [Cesanta CLA] (https://docs.cesanta.com/contributors_la.shtml) can make contributions. Note that the CLA isn't a copyright assigment but rather a copyright license. You retain the copyright on your contributions.
|
||||||
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
|
|
||||||
can make contributions. Note that the CLA isn't a copyright
|
|
||||||
_assigment_ but rather a copyright _license_.
|
|
||||||
You retain the copyright on your contributions.
|
|
||||||
|
|
||||||
# Licensing
|
[](https://github.com/cesanta/mongoose)
|
||||||
|
|
||||||
You are using Mongoose under
|
|
||||||
[GPLv2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
|
||||||
and until you commercialize your
|
|
||||||
application, can continue to use Mongoose free of charge.
|
|
||||||
|
|
||||||
Once you commercialize your product, in order to comply with GPLv2
|
|
||||||
you need to either open the source code of your product fully or
|
|
||||||
alternatively purchase a commercial license.
|
|
||||||
We offer [three levels of commercial licensing](https://www.cesanta.com/products):
|
|
||||||
|
|
||||||
- Mongoose Lite: cross platform integration, SSL/TLS, HTTP support
|
|
||||||
- Mongoose: Mongoose Lite + HTTP CGI, HTTP SSI, HTTP Digest Auth,
|
|
||||||
WebSocket support
|
|
||||||
- Mongoose Premium: Mongoose + Plain TCP, UDP, JSON-RPC, MQTT, DNS,
|
|
||||||
CoAP support
|
|
||||||
|
|
||||||
|
|
||||||
[Enquire about commercial licensing here](https://www.cesanta.com/contact)
|
|
||||||
|
|
||||||
# Mongoose Binary
|
|
||||||
|
|
||||||
This is our easy to use web server for web developers (PHP, Ruby, Python, etc)
|
|
||||||
and web designers. Available in three editions to suit your needs: free, pro
|
|
||||||
(USD 5) and dev edition (from USD 8). To install, simply download, double-click
|
|
||||||
to start and run browser - that's all!
|
|
||||||
|
|
||||||
[Download Mongoose Binary here](https://www.cesanta.com/products#binary)
|
|
||||||
|
|
||||||
# Other products by Cesanta
|
|
||||||
|
|
||||||
- [Smart.js](https://github.com/cesanta/smart.js) -
|
|
||||||
Generic, hardware independent, full-stack IoT software platform
|
|
||||||
- [V7](https://github.com/cesanta/v7) - Embedded JavaScript engine
|
|
||||||
- [Frozen](https://github.com/cesanta/frozen) - JSON parser and generator
|
|
||||||
- [SLRE](https://github.com/cesanta/slre) - Super Light Regular Expression
|
|
||||||
library
|
|
||||||
@@ -55,7 +55,7 @@ LINKFLAGS_eagle.app.v6 = \
|
|||||||
-u call_user_start \
|
-u call_user_start \
|
||||||
-Wl,-static \
|
-Wl,-static \
|
||||||
-Wl,--start-group \
|
-Wl,--start-group \
|
||||||
-lcirom \
|
-lc \
|
||||||
-lgcc \
|
-lgcc \
|
||||||
-lhal \
|
-lhal \
|
||||||
-lphy \
|
-lphy \
|
||||||
|
|||||||
@@ -23,11 +23,14 @@ endif
|
|||||||
# makefile at its root level - these are then overridden
|
# makefile at its root level - these are then overridden
|
||||||
# for a subtree within the makefile rooted therein
|
# for a subtree within the makefile rooted therein
|
||||||
#
|
#
|
||||||
DEFINES += -DMG_DISABLE_DAV -DMG_DISABLE_SYNC_RESOLVER -DMG_DISABLE_CGI \
|
DEFINES += -DMG_LOCALS \
|
||||||
-DMG_DISABLE_SOCKETPAIR -DMG_DISABLE_DIRECTORY_LISTING \
|
-DMG_NO_BSD_SOCKETS \
|
||||||
|
-DMG_DISABLE_FILESYSTEM \
|
||||||
|
-DMG_DISABLE_STDIO \
|
||||||
-DMG_MAX_HTTP_HEADERS=20 -DMG_MAX_HTTP_REQUEST_SIZE=1024 \
|
-DMG_MAX_HTTP_HEADERS=20 -DMG_MAX_HTTP_REQUEST_SIZE=1024 \
|
||||||
-DMG_MAX_PATH=40 -DMG_MAX_HTTP_SEND_IOBUF=1024 \
|
-DMG_MAX_PATH=40 -DMG_MAX_HTTP_SEND_MBUF=1024 \
|
||||||
-DMG_ESP8266 -DRTOS_SDK -DMG_LWIP
|
-DRTOS_SDK -DMG_LWIP -DLWIP_TIMEVAL_PRIVATE=0 \
|
||||||
|
-DMG_INTERNAL=
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
# Recursion Magic - Don't touch this!!
|
# Recursion Magic - Don't touch this!!
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "esp_common.h"
|
#include "esp_common.h"
|
||||||
|
|
||||||
/* Makes fprintf(stdout) and stderr work. */
|
/* Makes fprintf(stdout) and stderr work. */
|
||||||
|
/*
|
||||||
_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) {
|
_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) {
|
||||||
if (fd == 1 || fd == 2) {
|
if (fd == 1 || fd == 2) {
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -26,6 +27,7 @@ _ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* You'll need to implement _open_r and friends if you want file operations. See
|
* You'll need to implement _open_r and friends if you want file operations. See
|
||||||
@@ -42,7 +44,6 @@ void abort(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _exit(int status) {
|
void _exit(int status) {
|
||||||
printf("_exit(%d)\n", status);
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,3 +53,7 @@ int _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tzp) {
|
|||||||
tp->tv_usec = time % 1000000;
|
tp->tv_usec = time % 1000000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long int random(void) {
|
||||||
|
return os_random();
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
|||||||
case MG_EV_HTTP_REQUEST: {
|
case MG_EV_HTTP_REQUEST: {
|
||||||
char addr[32];
|
char addr[32];
|
||||||
struct http_message *hm = (struct http_message *) p;
|
struct http_message *hm = (struct http_message *) p;
|
||||||
|
(void) hm;
|
||||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||||
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
|
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
|
||||||
LOG(LL_INFO,
|
LOG(LL_INFO,
|
||||||
@@ -100,9 +101,13 @@ xTaskHandle s_mg_task_handle;
|
|||||||
void user_init(void) {
|
void user_init(void) {
|
||||||
uart_div_modify(0, UART_CLK_FREQ / 115200);
|
uart_div_modify(0, UART_CLK_FREQ / 115200);
|
||||||
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
// setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
setvbuf(stderr, NULL, _IONBF, 0);
|
// setvbuf(stderr, NULL, _IONBF, 0);
|
||||||
|
|
||||||
xTaskCreate(mg_task, (const signed char *) "mongoose", MG_TASK_STACK_SIZE,
|
xTaskCreate(mg_task, (const signed char *) "mongoose", MG_TASK_STACK_SIZE,
|
||||||
NULL, MG_TASK_PRIORITY, &s_mg_task_handle);
|
NULL, MG_TASK_PRIORITY, &s_mg_task_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void call_user_start(void) {
|
||||||
|
user_init();
|
||||||
|
}
|
||||||
@@ -10,9 +10,9 @@ static struct mg_serve_http_opts s_http_server_opts;
|
|||||||
static int s_sig_num = 0;
|
static int s_sig_num = 0;
|
||||||
static void *s_db_handle = NULL;
|
static void *s_db_handle = NULL;
|
||||||
static const char *s_db_path = "api_server.db";
|
static const char *s_db_path = "api_server.db";
|
||||||
static const struct mg_str s_get_method = MG_STR("GET");
|
static const struct mg_str s_get_method = MG_MK_STR("GET");
|
||||||
static const struct mg_str s_put_method = MG_STR("PUT");
|
static const struct mg_str s_put_method = MG_MK_STR("PUT");
|
||||||
static const struct mg_str s_delele_method = MG_STR("DELETE");
|
static const struct mg_str s_delele_method = MG_MK_STR("DELETE");
|
||||||
|
|
||||||
static void signal_handler(int sig_num) {
|
static void signal_handler(int sig_num) {
|
||||||
signal(sig_num, signal_handler);
|
signal(sig_num, signal_handler);
|
||||||
@@ -28,7 +28,7 @@ static int is_equal(const struct mg_str *s1, const struct mg_str *s2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||||
static const struct mg_str api_prefix = MG_STR("/api/v1");
|
static const struct mg_str api_prefix = MG_MK_STR("/api/v1");
|
||||||
struct http_message *hm = (struct http_message *) ev_data;
|
struct http_message *hm = (struct http_message *) ev_data;
|
||||||
struct mg_str key;
|
struct mg_str key;
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
PROG = big_upload
|
PROG = big_upload
|
||||||
|
MODULE_CFLAGS = -DMG_ENABLE_HTTP_STREAMING_MULTIPART
|
||||||
include ../examples.mk
|
include ../examples.mk
|
||||||
@@ -13,12 +13,11 @@ static const char *s_http_port = "8000";
|
|||||||
|
|
||||||
struct file_writer_data {
|
struct file_writer_data {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
size_t bytes_left;
|
size_t bytes_written;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_request(struct mg_connection *nc) {
|
static void handle_request(struct mg_connection *nc) {
|
||||||
// This handler gets called only when we don't reset proto_handler in
|
// This handler gets for all endpoints but /upload
|
||||||
// handle_recv, so we just return a page unconditionally.
|
|
||||||
mg_printf(nc, "%s",
|
mg_printf(nc, "%s",
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: text/html\r\n"
|
"Content-Type: text/html\r\n"
|
||||||
@@ -33,41 +32,17 @@ static void handle_request(struct mg_connection *nc) {
|
|||||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_recv(struct mg_connection *nc) {
|
static void handle_upload(struct mg_connection *nc, int ev, void *p) {
|
||||||
struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
|
struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
|
||||||
|
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part*)p;
|
||||||
|
|
||||||
|
switch (ev) {
|
||||||
|
case MG_EV_HTTP_PART_BEGIN: {
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
// This is a new connection, try to parse HTTP request.
|
|
||||||
struct http_message hm;
|
|
||||||
int req_len = mg_parse_http(nc->recv_mbuf.buf, nc->recv_mbuf.len, &hm,
|
|
||||||
1 /* is_req */);
|
|
||||||
|
|
||||||
if (req_len < 0 ||
|
|
||||||
(req_len == 0 && nc->recv_mbuf.len >= MG_MAX_HTTP_REQUEST_SIZE)) {
|
|
||||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
|
||||||
} else if (req_len == 0) {
|
|
||||||
// Request is not complete yet, do nothing.
|
|
||||||
} else if (mg_vcasecmp(&hm.method, "POST") == 0 &&
|
|
||||||
mg_vcmp(&hm.uri, "/upload") == 0) {
|
|
||||||
// This is the request that we don't want to buffer in memory.
|
|
||||||
|
|
||||||
if (hm.body.len == (size_t) ~0 || hm.body.len == 0) {
|
|
||||||
mg_printf(nc, "%s",
|
|
||||||
"HTTP/1.1 411 Content-Length required\r\n"
|
|
||||||
"Content-Length: 0\r\n\r\n");
|
|
||||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset proto_handler so Mongoose's http_handler() won't get confused
|
|
||||||
// once we start removing data from the buffer.
|
|
||||||
nc->proto_handler = NULL;
|
|
||||||
|
|
||||||
// Headers will be inaccessible later, so put everything we need into
|
|
||||||
// user_data.
|
|
||||||
data = calloc(1, sizeof(struct file_writer_data));
|
data = calloc(1, sizeof(struct file_writer_data));
|
||||||
data->bytes_left = hm.body.len;
|
|
||||||
data->fp = tmpfile();
|
data->fp = tmpfile();
|
||||||
|
data->bytes_written = 0;
|
||||||
|
|
||||||
if (data->fp == NULL) {
|
if (data->fp == NULL) {
|
||||||
mg_printf(nc, "%s",
|
mg_printf(nc, "%s",
|
||||||
"HTTP/1.1 500 Failed to open a file\r\n"
|
"HTTP/1.1 500 Failed to open a file\r\n"
|
||||||
@@ -76,23 +51,21 @@ static void handle_recv(struct mg_connection *nc) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nc->user_data = (void *) data;
|
nc->user_data = (void *) data;
|
||||||
|
|
||||||
// Remove the headers from the buffer.
|
|
||||||
mbuf_remove(&nc->recv_mbuf, hm.body.p - nc->recv_mbuf.buf);
|
|
||||||
|
|
||||||
// Invoke itself again to write the piece of the body that is already in
|
|
||||||
// the buffer.
|
|
||||||
handle_recv(nc);
|
|
||||||
}
|
}
|
||||||
} else { // data != NULL
|
break;
|
||||||
size_t to_write = data->bytes_left, written = 0;
|
}
|
||||||
if (nc->recv_mbuf.len < to_write) to_write = nc->recv_mbuf.len;
|
case MG_EV_HTTP_PART_DATA: {
|
||||||
written = fwrite(nc->recv_mbuf.buf, 1, to_write, data->fp);
|
if (fwrite(mp->data.p, 1, mp->data.len, data->fp) != mp->data.len) {
|
||||||
mbuf_remove(&nc->recv_mbuf, written);
|
mg_printf(nc, "%s",
|
||||||
data->bytes_left -= written;
|
"HTTP/1.1 500 Failed to write to a file\r\n"
|
||||||
if (data->bytes_left <= 0) {
|
"Content-Length: 0\r\n\r\n");
|
||||||
// Request is complete, do something meaningful here.
|
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data->bytes_written += mp->data.len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MG_EV_HTTP_PART_END: {
|
||||||
mg_printf(nc,
|
mg_printf(nc,
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: text/plain\r\n"
|
"Content-Type: text/plain\r\n"
|
||||||
@@ -100,19 +73,11 @@ static void handle_recv(struct mg_connection *nc) {
|
|||||||
"Written %ld of POST data to a temp file\n\n",
|
"Written %ld of POST data to a temp file\n\n",
|
||||||
(long) ftell(data->fp));
|
(long) ftell(data->fp));
|
||||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
// handle_close will free the resources.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we free all allocated resources
|
|
||||||
static void handle_close(struct mg_connection *nc) {
|
|
||||||
struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
|
|
||||||
|
|
||||||
if (data != NULL) {
|
|
||||||
fclose(data->fp);
|
fclose(data->fp);
|
||||||
free(data);
|
free(data);
|
||||||
nc->user_data = NULL;
|
nc->user_data = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,13 +88,6 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
// Invoked when the full HTTP request is in the buffer (including body).
|
// Invoked when the full HTTP request is in the buffer (including body).
|
||||||
handle_request(nc);
|
handle_request(nc);
|
||||||
break;
|
break;
|
||||||
case MG_EV_RECV:
|
|
||||||
// Invoked every time new data arrives.
|
|
||||||
handle_recv(nc);
|
|
||||||
break;
|
|
||||||
case MG_EV_CLOSE:
|
|
||||||
handle_close(nc);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +98,7 @@ int main(void) {
|
|||||||
mg_mgr_init(&mgr, NULL);
|
mg_mgr_init(&mgr, NULL);
|
||||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||||
|
|
||||||
|
mg_register_http_endpoint(nc, "/upload", handle_upload);
|
||||||
// Set up HTTP server parameters
|
// Set up HTTP server parameters
|
||||||
mg_set_protocol_http_websocket(nc);
|
mg_set_protocol_http_websocket(nc);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
SOURCES = $(PROG).c ../../mongoose.c
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
CFLAGS = -W -Wall -I../.. -Wno-unused-function $(CFLAGS_EXTRA) $(MODULE_CFLAGS)
|
CFLAGS = -g -W -Wall -I../.. -Wno-unused-function $(CFLAGS_EXTRA) $(MODULE_CFLAGS)
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
/* RESTful server host and request URI */
|
/* RESTful server host and request URI */
|
||||||
static const char *s_target_address = "ajax.googleapis.com:80";
|
static const char *s_url =
|
||||||
static const char *s_request = "/ajax/services/search/web?v=1.0&q=cesanta";
|
"http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=cesanta";
|
||||||
|
|
||||||
static int s_exit_flag = 0;
|
static int s_exit_flag = 0;
|
||||||
|
|
||||||
@@ -18,13 +18,8 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
switch (ev) {
|
switch (ev) {
|
||||||
case MG_EV_CONNECT:
|
case MG_EV_CONNECT:
|
||||||
connect_status = *(int *) ev_data;
|
connect_status = *(int *) ev_data;
|
||||||
if (connect_status == 0) {
|
if (connect_status != 0) {
|
||||||
printf("Connected to %s, sending request...\n", s_target_address);
|
printf("Error connecting to %s: %s\n", s_url, strerror(connect_status));
|
||||||
mg_printf(nc, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n",
|
|
||||||
s_request, s_target_address);
|
|
||||||
} else {
|
|
||||||
printf("Error connecting to %s: %s\n",
|
|
||||||
s_target_address, strerror(connect_status));
|
|
||||||
s_exit_flag = 1;
|
s_exit_flag = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -43,10 +38,10 @@ int main(void) {
|
|||||||
struct mg_connection *nc;
|
struct mg_connection *nc;
|
||||||
|
|
||||||
mg_mgr_init(&mgr, NULL);
|
mg_mgr_init(&mgr, NULL);
|
||||||
nc = mg_connect(&mgr, s_target_address, ev_handler);
|
nc = mg_connect_http(&mgr, ev_handler, s_url, NULL, NULL);
|
||||||
mg_set_protocol_http_websocket(nc);
|
mg_set_protocol_http_websocket(nc);
|
||||||
|
|
||||||
printf("Starting RESTful client against %s\n", s_target_address);
|
printf("Starting RESTful client against %s\n", s_url);
|
||||||
while (s_exit_flag == 0) {
|
while (s_exit_flag == 0) {
|
||||||
mg_mgr_poll(&mgr, 1000);
|
mg_mgr_poll(&mgr, 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -1,6 +1,7 @@
|
|||||||
PROG = simplest_web_server
|
PROG = simplest_web_server
|
||||||
SOURCES = $(PROG).c ../../mongoose.c
|
SOURCES = $(PROG).c ../../mongoose.c
|
||||||
CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA) -DMG_DISABLE_DAV_AUTH
|
CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA) -DMG_DISABLE_DAV_AUTH \
|
||||||
|
-DMG_ENABLE_FAKE_DAVLOCK
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|
||||||
|
|||||||
+1703
-659
File diff suppressed because it is too large.
Load diff
+658
-153
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user