Skip to content
Snippets Groups Projects
Commit 147bb332 authored by clohr's avatar clohr
Browse files

Préparation de la v0.5r2

git-svn-id: https://redmine.imt-atlantique.fr/svn/xaal/code/C/trunk@1590 b32b6428-25c9-4566-ad07-03861ab6144f
parent d0b73727
Branches
No related tags found
No related merge requests found
......@@ -99,12 +99,19 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
pss->post_uri = NULL;
pss->post_msg = NULL;
pss->post_len = 0;
pss->complete = true;
if (len < 1) {
lws_return_http_status(wsi, HTTP_STATUS_BAD_REQUEST, NULL);
return -1;
}
/* if a legal POST URL, let it continue and accept data */
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
pss->post_uri = strdup(in);
break;
}
/* Our pseudo-REST API */
{
pss->janswer = NULL;
......@@ -153,16 +160,10 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
if (pss->janswer) {
lws_callback_on_writable(wsi);
return 0;
break;
}
}
/* if a legal POST URL, let it continue and accept data */
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
pss->post_uri = strdup(in);
return 0;
}
/* send a file the easy way */
strcpy(buf, resource_path);
......@@ -186,18 +187,18 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi)))
return -1; /* error or can't reuse connection: close the socket */
return 0;
break;
case LWS_CALLBACK_HTTP_BODY:
pss->post_msg = realloc(pss->post_msg, pss->post_len+=len);
memcpy(pss->post_msg, in, pss->post_len);
return 0;
break;
case LWS_CALLBACK_HTTP_BODY_COMPLETION:
if (!pss->post_uri || !pss->post_msg) {
free(pss->post_uri);
free(pss->post_msg);
return 1;
goto try_to_reuse;
}
if ( strcmp(pss->post_uri, REST_PREFIX "send") == 0 )
......@@ -210,22 +211,36 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
pss->post_uri = NULL;
pss->post_msg = NULL;
pss->post_len = 0;
pss->complete = true;
if (pss->janswer) {
lws_callback_on_writable(wsi);
return 0;
break;
} else {
lws_return_http_status(wsi, HTTP_STATUS_BAD_REQUEST, NULL);
return -1;
}
case LWS_CALLBACK_HTTP_WRITEABLE:
if (!pss->janswer && !pss->complete) {
if ( hdr_http_stream(wsi) ) {
//lws_client_http_body_pending(wsi, 1);
break;
} else {
lwsl_err("Bad REST\n");
lws_return_http_status(wsi, HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL);
return -1;
}
}
if (pss->janswer) {
if (pss->complete) {
if ( serve_http_json(wsi, pss->janswer) ) {
json_object_put(pss->janswer);
//lws_client_http_body_pending(wsi, 0);
pss->janswer = NULL;
return 1;
//lws_client_http_body_pending(wsi, 0);
goto try_to_reuse;
} else {
lwsl_err("Bad REST\n");
lws_return_http_status(wsi, HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL);
......@@ -233,51 +248,63 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
pss->janswer = NULL;
return -1;
}
} else {
if ( serve_http_stream(wsi, pss->janswer) ) {
json_object_put(pss->janswer);
pss->janswer = NULL;
//lws_client_http_body_pending(wsi, 1);
break;
} else {
lwsl_err("Bad REST\n");
lws_return_http_status(wsi, HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL);
return -1;
}
return 0;
}
}
break;
case LWS_CALLBACK_ADD_POLL_FD:
if (count_pollfds >= max_poll_elements) {
lwsl_err("LWS_CALLBACK_ADD_POLL_FD: too many sockets to track\n");
return 1;
goto try_to_reuse;
}
fd_lookup[pa->fd] = count_pollfds;
pollfds[count_pollfds].fd = pa->fd;
pollfds[count_pollfds].events = pa->events;
pollfds[count_pollfds++].revents = 0;
return 0;
break;
case LWS_CALLBACK_DEL_POLL_FD:
if (!--count_pollfds)
return 0;
break;
m = fd_lookup[pa->fd];
/* have the last guy take up the vacant slot */
pollfds[m] = pollfds[count_pollfds];
fd_lookup[pollfds[count_pollfds].fd] = m;
return 0;
break;
case LWS_CALLBACK_CHANGE_MODE_POLL_FD:
pollfds[fd_lookup[pa->fd]].events = pa->events;
return 0;
break;
default:
return 0;
break;
}
}
return 0;
bool serve_http_json(struct lws *wsi, struct json_object *jobj) {
bool r;
r = serve_http_json_str(wsi, json_object_to_json_string_ext(jobj,
JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOZERO));
json_object_put(jobj);
return r;
/* if we're on HTTP1.1 or 2.0, will keep the idle connection alive */
try_to_reuse:
if (lws_http_transaction_completed(wsi))
return -1;
return 0;
}
bool serve_http_json_str(struct lws *wsi, const char *json) {
bool serve_http_json(struct lws *wsi, struct json_object *jobj) {
const char *json = json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOZERO);
unsigned char buffer[4096 + LWS_PRE];
unsigned char *p, *end, *start;
ssize_t sz = strlen(json);
......@@ -317,3 +344,52 @@ bool serve_http_json_str(struct lws *wsi, const char *json) {
return true;
}
#define STREAM_PREFIX "data: "
#define STREAM_SUFFIX "\r\n\r\n"
bool serve_http_stream(struct lws *wsi, struct json_object *jobj) {
const char *json = json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOZERO);
char buf[ strlen(STREAM_PREFIX) + strlen(json) + strlen(STREAM_SUFFIX) + 1];
sprintf(buf, STREAM_PREFIX "%s" STREAM_SUFFIX, json);
return ( lws_write(wsi, (unsigned char *)buf, strlen(buf), LWS_WRITE_HTTP) >= 0 );
}
bool hdr_http_stream(struct lws *wsi) {
unsigned char buffer[4096 + LWS_PRE];
unsigned char *p, *end, *start;
p = buffer + LWS_PRE;
start = p;
end = p + sizeof(buffer) - LWS_PRE;
if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
return false;
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *)"text/event-stream",
strlen("text/event-stream"), &p, end))
return false;
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CACHE_CONTROL,
(unsigned char *)"no-cache",
strlen("no-cache"), &p, end))
return false;
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_CONNECTION,
(unsigned char *)"keep-alive",
strlen("keep-alive"), &p, end))
return false;
if (lws_finalize_http_header(wsi, &p, end))
return false;
return ( lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS) >= 0 );
}
......@@ -20,6 +20,7 @@
#define _PROTOHTTP_
#include <stdbool.h>
#include <libwebsockets.h>
#include <json-c/json.h>
......@@ -29,6 +30,7 @@
struct per_session_data__http {
struct json_object *janswer;
bool complete;
char *post_msg;
char *post_uri;
size_t post_len;
......@@ -39,6 +41,9 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
bool serve_http_json(struct lws *wsi, struct json_object *jobj);
bool serve_http_json_str(struct lws *wsi, const char *json);
bool hdr_http_stream(struct lws *wsi);
bool serve_http_stream(struct lws *wsi, struct json_object *jobj);
#endif
......@@ -67,6 +67,13 @@ static struct lws_protocols protocols[] = {
};
static const struct lws_extension exts[] = {
{ "permessage-deflate", lws_extension_callback_pm_deflate, "permessage-deflate" },
{ "deflate-frame", lws_extension_callback_pm_deflate, "deflate_frame" },
{ NULL, NULL, NULL }
};
void sighandler(int sig) {
force_exit = 1;
lws_cancel_service(context);
......@@ -150,9 +157,10 @@ int main(int argc, char **argv) {
info.protocols = protocols;
info.gid = options.gid;
info.uid = options.uid;
info.max_http_header_pool = 16;
info.max_http_header_pool = 32;
info.options = LWS_SERVER_OPTION_VALIDATE_UTF8;
info.timeout_secs = 5;
info.extensions = exts;
info.timeout_secs = 15;
context = lws_create_context(&info);
if (context == NULL) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment