Code Monkey home page Code Monkey logo

facil.io's Introduction

Hi there 👋

My name is Boaz Segev and I'm:

  • A human being.
  • A musician (composer, producer and songwriter)
  • A full-stack software engineer.
  • An artist.

Development Projects I Enjoy ⚡

  • Software and API design
  • Barebones Front-end development using CSS and JavaScript
  • Backend development using Ruby, Node and C.
  • Ruby MRI C extensions.

Contact

I'm available by:

My Mission Statement

My intention is to leave this world in a more compassionate, loving and free state than it was when I entered it.

Bo's github stats

profile for Myst at Stack Overflow, Q&A for professional and enthusiast programmers

facil.io's People

Contributors

0xflotus avatar 64 avatar area55git avatar benjcal avatar boazsegev avatar fbrausse avatar gnaneshkunal avatar joeyhoek avatar kradih avatar low-power avatar neshkeev avatar owendelahoy avatar raminfp avatar svenefftinge avatar timgates42 avatar wishdev avatar zweimach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

facil.io's Issues

Build issue

I can't build via make /usr/bin/ld: cannot find /usr/lib64/libasan.so.0.0.0

SSL / TLS library

I know one of the main concerns for SSL/TLS is that it doesn't gonk the license. Most SSL/TLS is sadly CPL cancer which is a problem for keeping facil.io MIT. After a bit of Googling I came upon BearSSL which is MIT and appears to meat the needs of simple, client and server side implementations. Without much overhead in its own right.

https://bearssl.org/index.html

You could either pull it in as a compiled dependency or pull in the bits and pieces of code that you want to salvage without causing license problems. Seems like it might work...

Can we get a more complete explanation for the C11 requirement?

This library is pretty sweet. Thanks for making it!

I'm evaluating the portability of this library. The README made it sound like there are only a few C11 features being used. If it's not too much work it would be great to have support for C99. There are way more compliant compilers for that standard. If that's not going to be an easy task, can the reasons behind that be elaborated more in the README or some other relevant part of the repo?

Thanks :)

Read content from file descriptor

When request body more then 1024 - it stored data in some tmp file?
May you please explain where i may find this file and how to read data from it
Thank you

bash issues under Linux

it works like this under Ubuntu:

bash <(curl -s https://raw.githubusercontent.com/boazsegev/facil.io/master/scripts/new/app) testapp
* Creating testapp
https://api.github.com/repos/boazsegev/facil.io/tarball/v.0.6.0.beta
rm: cannot remove 'src': No such file or directory

next

~/testapp$ make
/bin/sh: 1: Syntax error: Bad fd number
/bin/sh: 1: Syntax error: Bad fd number
/bin/sh: 1: Syntax error: Bad fd number
/bin/sh: 1: Syntax error: Bad fd number

maybe because of >& instead of &> ? Not sure. Just tried once and the output looks a bit weird

how to use http_connect with keep-alive

I sent http request body with the first time on_response, and process the returned second time on_response body.

so, how can I keep a http client connection alive to reuse the http socket connection to some server? Can I do that? @boazsegev

Thanks

Logo Proposal for Facil.io

Hi @boazsegev, I'm a graphic designer and I like to collaborate with open source projects. Do you know that the graphic image of a project is very important? thinking about it I would like to design a logo for your Project Facil.io.

I will be pleased to collaborate with you.
Att
Francisco

High-level description of how this framework works

Hi there!

I found this framework interesting and promising due to its handy API syntax. However, the documentation somewhat confuses me. Well, this is unsurprising because I'm not an expert in Web development anyway. Actually, I have received little formal education in CS, but I know the very basics of TCP thanks to Beej's Guide to Network Programming. In addition, I have previously worked with kcgi, Flask, and Django.

Anyway, from my perspective, both the comments in the header files and the HTML document are enumerating functions without sufficiently stating how they interact with each other as a whole. For example, the HTML document begins with introducing fio_protocol_s which has a lot of on_* callbacks. This part inevitably contains several forward references to stuff like FIO_PR_LOCK_TASK. When working through it I'm totally lost for a while, because I have no idea how the connections and locks are handled by the framework (without reading the rest of the document, which is kinda long and dry).

Personally, I would like to see a high-level description at the very beginning of this documentation, preferably presented with a diagram like the following one. Plain text descriptions like "On startup, we allocate a fio_protocol_s object with malloc and set its callback functions by writing a compound literal. Next, we get a UUID from somewhere. Then we can conveniently attach it to a connection with fio_attach and set up some kind of lock. ..." are also nice to have.

diagram

Question about facil.listen() argument

Hi there,
I'm writing a simple websocket server based on a sample from the site.
I needed to change some rows of code to compile, 'cause they have a different prototipes.
In particular
facil_listen(
.port = "7681",
.on_open = create_protocol,
Now create_protocol() is
static inline void create_protocol(intptr_t uuid, void * arg) {
returns nothing and then I'm wondering how to return the pointer to protocol_s structure.
In this way the connection is not possible.
Thanks!

Possible bug in start/stop routines

Played with "echo" demo, as found on "Getting started" page (using stable branch with debug symbols).

All runs smoothly, however when I run this demo under valgrind and ^C it, the following errors are reported:

==7444== Memcheck, a memory error detector
==7444== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7444== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==7444== Command: ./a.out
==7444==
* Listening on port 3000
Server is running 1 worker X 1 thread, press ^C to stop
* 7444 is running.
^C==7444== Invalid read of size 4
==7444==    at 0x12115D: defer_perform_in_fork (defer.c:394)
==7444==    by 0x112DD6: facil_run (facil.c:1069)
==7444==    by 0x1105A8: main (e2.c:53)
==7444==  Address 0x5404cc0 is 0 bytes after a block of size 0 alloc'd
==7444==    at 0x4C2DBC5: calloc (vg_replace_malloc.c:711)
==7444==    by 0x121022: defer_perform_in_fork (defer.c:363)
==7444==    by 0x112DD6: facil_run (facil.c:1069)
==7444==    by 0x1105A8: main (e2.c:53)
==7444==
==7444== Invalid read of size 4
==7444==    at 0x121196: defer_perform_in_fork (defer.c:397)
==7444==    by 0x112DD6: facil_run (facil.c:1069)
==7444==    by 0x1105A8: main (e2.c:53)
==7444==  Address 0x5404cc0 is 0 bytes after a block of size 0 alloc'd
==7444==    at 0x4C2DBC5: calloc (vg_replace_malloc.c:711)
==7444==    by 0x121022: defer_perform_in_fork (defer.c:363)
==7444==    by 0x112DD6: facil_run (facil.c:1069)
==7444==    by 0x1105A8: main (e2.c:53)
==7444==
* 7444 cleanning up.
* (7444) Stopped listening on port 3000

   ---  Completed Shutdown  ---

Probably there is an error there and you should have a look.

`strtod` might be unsafe on some systems

facil.io protects the JSON parser and Strings from overflowing during a call to strtod... however, it still appears that strtod calls strlen internally on some systems.

One might have assumed the issue was fixed... however, using my profiler showed distinct calls make from strtod to strlen on some systems (and I hope it was some sort of mistake).

This isn't really safe if the string isn't NUL terminated.

It also wastes CPU cycles when the floating point number is in the middle (rather than the end) of a string.

Rolling an strtod alternative (or copying the buffer to a NUL terminated buffer before parsing the data), should be considered.

It is currently recommended that developers test the strtod implementations and consider overriding the function using safe implementations (when discovering an issue).

unclear how to add openssl support

Hi, i was able to use facil.io as websocket client, now i need tls support and tried to add openssl...

I cloned openssl, compiled it and added the headers to the include search path - but if i include <fio_tls.h> and call fio_tls_s * tls = fio_tls_new("www.example.com", NULL, NULL, NULL); then i get the output:
FATAL: No supported SSL/TLS library available.

i also tried setting some defines i found in the source:

#define HAVE_OPENSSL
#define FIO_TLS_FOUND

#include <http.h>
#include <fio.h>
#include <fio_tls.h>

this did not change anything, unfortunately

Attempting to free stack allocated channel_s object

Version 0.7.0.beta8

When building a release with gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 I see the following:

In function ‘fio_channel_free.part.26’,
    inlined from ‘fio_ch_set__insert_or_overwrite_.constprop’,
    inlined from ‘fio_filter_dup_lock_internal’ at lib/facil/fio.h:6127:10,
    inlined from ‘fio_filter_dup_lock’ at lib/facil/fio.c:5383:10,
    inlined from ‘fio_subscribe’ at lib/facil/fio.c:5455:8:
lib/facil/fio.c:5151:3: warning: attempt to free a non-heap object ‘ch’ [-Wfree-nonheap-object]
   free(ch);
   ^~~~~~~~
In function ‘fio_channel_free.part.26’,
    inlined from ‘fio_ch_set__insert_or_overwrite_.constprop’,
    inlined from ‘fio_filter_dup_lock_internal’ at lib/facil/fio.h:6127:10,
    inlined from ‘fio_channel_match_dup_lock.isra.67’ at lib/facil/fio.c:5416:14,
    inlined from ‘fio_subscribe’ at lib/facil/fio.c:5457:8:
lib/facil/fio.c:5151:3: warning: attempt to free a non-heap object ‘ch’ [-Wfree-nonheap-object]
   free(ch);
   ^~~~~~~~
In function ‘fio_channel_free.part.26’,
    inlined from ‘fio_ch_set__insert_or_overwrite_.constprop’,
    inlined from ‘fio_filter_dup_lock_internal’ at lib/facil/fio.h:6127:10,
    inlined from ‘fio_channel_dup_lock.isra.68’ at lib/facil/fio.c:5396:14,
    inlined from ‘fio_subscribe’ at lib/facil/fio.c:5459:8:
lib/facil/fio.c:5151:3: warning: attempt to free a non-heap object ‘ch’ [-Wfree-nonheap-object]
   free(ch);

How to send data image base64 in socket in http?

Hi,

Thanks for repo,

I have a question, How to you convert a image (.png) that is a large character to base64 from clinet side and send data in the socket to server and convert base64 image (.png) of server side in C in facil ? how to handle to buffer large character?

Thanks,

Timers still running after main()

Hi,

I'm having trouble with object lifetimes. My (dumbed down) application looks something like this:

#include <fio.h>

struct my_context { /* ... */ };
void on_timer(void *) { /* ... */ }
void on_finish(void *udata)
{
  struct my_context *ctx = udata;
  do_some_last_thing_with(ctx);
}

int main()
{
  struct my_context ctx;
  init(&ctx);
  fio_run_every(5000, 1, on_timer, &ctx, on_finish);
  fio_start(.threads=1);
  fini(&my_context);
}

I should add, that I link it dynamically to libfacil.so.

When the application is interrupted by e.g. SIGINT, my understanding is that facil.io's custom signal handler will cause fio_start() to return to main. After main the atexit(3) handlers run, including those that call _dl_fini which calls:

static void __attribute__((destructor)) fio_lib_destroy(void) {

Now, there is still the on_timer active and will be shutdown by calling on_finish here:
fio_timer_clear_all();
after main already called fini() on ctx, leading to an access violation in on_finish.

Is this the intended behaviour and, if so, how am I using facil.io in the wrong way? My expectation was that on_finish (and actually the entire shutdown procedures from fio_lib_destroy) would be called before fio_start() returns and not when unloading libfacil.so.

I realize this is relatively easy to fix either by dynamic allocation of ctx and something like reference-counting, or by manually dlopen/dlclose, but I am wondering whether there was a way to avoid both of these. Maybe by exposing some kind of fio_init() and fio_fini(), which I could call around fio_start()?

Please forgive me if this issue is already covered by the documentation, I couldn't find any hint regarding timers or interaction of the .on_unsubscribe callbacks with fio_start() or the shutdown procedure of facil.io.

What Features do you want to see in fail.io?

I'm in the processes of rewriting many part of the library, including major updates to the HTTP and Pub/Sub design and API, with the intention of making everything as easy to use as can be.

You can have a look at the reHTTP branch to see the work so far.

But now is your chance to vote or suggest any new features you want to see in facil.io.

What features would you prefer (HTTP client? how big should the total HTTP headers length size should be? etc')

What default behaviors would you prefer? (Do you want forked processes to re spawn automatically after a crash or do you prefer a cild process crashing to bring down the while process cluster node?)

Leave comments below.

Processing of big test frames.

Hi,
i am just testing your websocket library and noticed that when sending big text Frames like this here, the parsing Fails with "ERROR Websockets: unmasked frame, disconnecting."

Is it just for me, or can you also reproduce this on your side?

Thanks for any hints.

there are some proplems with fio_str_tmp function

this is my source code

typedef struct table_data{
    char **fields;
    char **value;
}table_data;
char *fields[] = {"id","name","age"};
    char *value[] = {"1","jack","100"};
    insert("users",(table_data){.fields=fields,.value=value}); 
int insert(char *table,table_data data)
{
    int i=0;
    FIOBJ fields = fiobj_str_tmp();
    FIOBJ val = fiobj_str_tmp();
    if (table){
        while (data.fields[i]){
            fiobj_str_write(fields,"`",1);
            fiobj_str_write(fields,data.fields[i],strlen(data.fields[i]));
            fiobj_str_write(fields,"`",1);
            fiobj_str_write(fields,",",1);

            fiobj_str_write(val,"'",1);
            fiobj_str_write(val,data.value[i],strlen(data.value[i]));
            fiobj_str_write(val,"'",1);
            fiobj_str_write(val,",",1);
            i++;
        }
        printf("fields=%s\n",fiobj_obj2cstr(fields).data);
        printf("value=%s\n",fiobj_obj2cstr(val).data);

    }
}

run it shows

fields=`id`,'1',`name`,'jack',`age`,'100',
value=`id`,'1',`name`,'jack',`age`,'100',

How to compile facil.io

Hi,

i'm not sure, how to compile facil.io,because on your docs any point about this,

[root@raminfp facil.io]# ls
CHANGELOG.md  CMakeLists.txt  dev  docs  Doxyfile  examples  lib  LICENSE  makefile  NOTICE  README.md  scripts  tests
[root@raminfp facil.io]# 
[root@raminfp facil.io]# make
Assembler messages:
Fatal error: can't create tmp/./lib/core/defer.o: No such file or directory
makefile:114: recipe for target 'tmp/./lib/core/defer.o' failed
make: *** [tmp/./lib/core/defer.o] Error 1

please help for it,

Thanks,
Ramin

Outdated demo on website

Just wanted to tell you, that you have a bug in demo on your website.

It is under "Simple API (Echo example)" section on "Getting started" page.

This is the compilation log:

a.c: In function ‘create_echo_protocol’:
a.c:45:19: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
.on_close = destroy_echo_protocol,
^~~~~~~~~~~~~~~~~~~~~
a.c:45:19: note: (near initialization for ‘(anonymous).on_close’)

And it really crashes when one tries to close connection to the server.

Adding a void *udata field to fio_protocol_s

I think it would be nice to have some data private to each connection, just like Flask's request context. The most obvious way to do this is by adding a void *udata field to fio_protocol_s.

A typical use case is attaching a database instance db to each connection, so that during a request, references to db will always refer to the same object. Also, this db instance will be closed automatically at the end of the request with the help of on_close.

Consistent Coding Style

I realize this may seem like grasping at straws but spending tons of time programing these things become quite an annoyance. Both Google and Github searches show clearly that ARR instead of ARY is the preferred abbreviation for array. While this would not be a big concern in a vacuum, in combining several libraries remembering that Facil says ARY while all other libs say ARR is frustrating. For these reasons I'm suggesting that for the next major version we should standardize this abbreviation for everyone and grep all ARY/ary replacing with ARR/arr. I am willing to take on this task if we decide to do it...

The biggest concern is that this will impact backwards compatibility. So it needs to be planned instead of just sending a pull request in a vacuum.

document 0.7 version fio_connect function description is error

/* *****************************************************************************
The connection protocol (use the facil.io API to make a socket and attach it)
***************************************************************************** */

typedef struct {
fio_protocol_s pr;
intptr_t uuid;
void *udata;
void *tls;
void (*on_connect)(intptr_t uuid, void *udata);
void (*on_fail)(intptr_t uuid, void *udata);
} fio_connect_protocol_s;
document description is
image

on_fail callback not found on this web page doc

Option to not set signal handlers

Since facil is a library, it is unfortunate for it to unconditionally overwrite signal handlers with it's own. The functionality implemented through them seems non-essential and could just as well be triggered through the integrating program (e.g. fio_stop).

It should in any case chain signals to the signal handlers it overwrote, which isn't currently done.

From Project 3: MIT -> ISC

https://github.com/boazsegev/facil.io/projects/3

These are equivalent licenses but ISC has more modern language. For most commercial projects BSD, MIT and ISC licenses are thought of as identical since they each can be included in commercial products ad nauseum.

  • MIT probably has more "brand recognition" than ISC. It is the current favorite of most web frameworks and technologies - so better understood by your target audience.
  • ISC is considered easier to read with more modern legalese.

I'm not sure if you gain anything by switching and may scare off some people in the web world less familiar with the ISC (since it's newer). I try to keep things simple in my projects with either, MIT, LGPL or GPL. These are the household names. BSD gets confusing because they can't decided whether it's 2, 3 or 4 clauses.

Bottomline: I won't waste time on this.

You'll lose more people than you gain on the switch and it doesn't change anything legally other than MIT having more case law because it's an older license...

I can use facil lib in http protocol response?

Hi @boazsegev ,

I have question! how to i use facil lib in http protocol response for get status response ex: (OK) 200,(forbidden) 404,...,
i saw your http lib but sill i'm not sure, please help,

my means : this is a an example of CURLlib, CURLE_OK == 200 if it's status == 200 in response, you will see printf("OK\n"),

#include <stdio.h>
#include <curl/curl.h>
 
int main(void)
{
  CURL *curl;
  CURLcode res;
 
  curl = curl_easy_init();
  if(curl) {
  
    curl_easy_setopt(curl, CURLOPT_URL, "http://google.com");
    res = curl_easy_perform(curl);
    if(res == CURLE_OK) {
        printf("OK!\n ");
        long response_code;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
    }
    curl_easy_cleanup(curl);
  }
  return 0;
}

Thanks,

Some strange libs dependencies.

Brief about me. Newbie lnx usr. trying to write C server with blackjack and... saw you lib and it is quite lite.
But i have fail from the start due to dependencies... and i ask you for advise.

from the start, i tried download with script + newapp and typical way.
e.g.

$ wget https://github.com/boazsegev/facil.io/archive/master.zip
$ unzip master.zip
$ cd facil.io-master/
$ ls
CHANGELOG.md    CONTRIBUTING.md  docs      examples  LICENSE   NOTICE     scripts
CMakeLists.txt  dev              Doxyfile  lib       makefile  README.md  tests
# for case
$ make clean
rm: cannot remove 'tmp/demo': No such file or directory
makefile:167: recipe for target 'clean' failed
make: [clean] Error 1 (ignored)
rm: cannot remove 'tmp': No such file or directory
makefile:167: recipe for target 'clean' failed
make: [clean] Error 1 (ignored)

# lets make it from the box. ...i said...
$ make
lib/facil/core/defer.c:56:3: error: unknown type name ‘uint8_t’
   uint8_t state;
   ^
makefile:158: recipe for target 'tmp/./lib/facil/core/defer.o' failed
make: *** [tmp/./lib/facil/core/defer.o] Error 1

#nope said compiler... ver is
$ gcc -v
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)

# i assumed fail of #include <sys/types.h>
$ echo "#include <sys/types.h>" | gcc -E -x c - | grep /types.h
1 "/usr/include/x86_64-linux-gnu/sys/types.h" 1 3 4

root@ubuntu-512mb-ams2-01: / vim /usr/include/x86_64-linux-gnu/sys/types.h

# hm... they are without needed types... i guess... strange

$ vim lib/facil/core/defer.c
include <inttypes.h> //add //for test
include <sys/types.h>

$ make

# this should not have happened...
lib/facil/core/types/fiobj/fiobj_str.c: In function ‘fiobj_str_readfile’:
lib/facil/core/types/fiobj/fiobj_str.c:222:45: error: ‘PATH_MAX’ undeclared (first use in this function)
   if (file_path_len == 0 || file_path_len > PATH_MAX)
                                             ^
lib/facil/core/types/fiobj/fiobj_str.c:222:45: note: each undeclared identifier is reported only once for each function it appears in
lib/facil/core/types/fiobj/fiobj_str.c:249:7: warning: implicit declaration of function ‘pread’ [-Wimplicit-function-declaration]
   if (pread(file, obj2str(str)->str, limit, start_at) != (ssize_t)limit) {
       ^
lib/facil/core/types/fiobj/fiobj_str.c:225:8: warning: unused variable ‘real_public_path’ [-Wunused-variable]
   char real_public_path[PATH_MAX + 1];
        ^
makefile:158: recipe for target 'tmp/./lib/facil/core/types/fiobj/fiobj_str.o' failed
make: *** [tmp/./lib/facil/core/types/fiobj/fiobj_str.o] Error 1

# first guess it could be limits...
$ echo "#include <limits.h>" | gcc -E -x c - | grep /limits.h
1 "/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h" 1 3 4
1 "/usr/include/limits.h" 1 3 4
1 "/usr/include/linux/limits.h" 1 3 4

# but they present... what is happening... something going wrong...

I don't know why something is wrong with libs and dependencies... or they are different... so i ask you for advise how should i solve this? Do i need do download some extra libs files? Is this something wrong with distro?

Unexpected Numeral and String representation issue when parsing a query

int main(int argc, char const *argv[]) {

    http_listen("80", NULL,
                .on_request = on_http_request,
                .on_upgrade = on_http_upgrade,
                .max_clients=10240,
                .log = 1,
                .public_folder="../web"
    );
    fio_start(.threads = 1, .workers = 1);
    return 0;
} 
static void on_http_request(http_s *h) {
   if (fiobj_type_is(h->params,FIOBJ_T_HASH)){
        if (fiobj_hash_haskey(h->params,fiobj_str_new("name",4))){
            printf("ok=%s\n",fiobj_obj2cstr(fiobj_hash_get(h->params,fiobj_str_new("name",4))).data);
            printf("ok1=%s\n",fiobj_obj2cstr(h->query).data);
        }
    }
}

use postman send a request:
http://ip:port/?name=xbbb&age=100
图片

print result :
图片

图片
图片

1、when name=b or name=x will display 0
2、when name value is 'b' and 'x' will display number value
3、when name value=0b001,value=0100 value=0x11 will display number value

Function prefixes

First, congratulations for the work!

I was seeing the example usage:

// Listen to HTTP requests and start facil.io
int main(int argc, char const **argv) {
  // allocating values we use often
  HTTP_X_DATA = fiobj_str_new("X-Data", 6);
  // listen on port 3000 and any available network binding (NULL == 0.0.0.0)
  http_listen("3000", NULL, .on_request = on_request, .log = 1);
  // start the server
  facil_run(.threads = 1);
  // deallocating the common values
  fiobj_free(HTTP_X_DATA);
}

And, at least for me, using 3 different prefixes (http, fiobj, facil) appear a bit unintuitive.

What about all prefixes being just http_?

In this way we don't need to remember each functions should use this or that prefix. The learning curve is smaller, and hence the adoption can be bigger.

Just an idea.

Another thing is this line:

FIOBJ HTTP_X_DATA;

Generally in C we use uppercase letters for constants, but this is a variable.

The typedef is also in uppercase. A bit unusual for me.

But this can be less important.

Cheers,

Websocket: heavy `on_open` could cause a client's first message to drop

As discovered by @madsheep and @nilclass, detailed in issue iodine#10 here, a client's first message might be lost due to a long on_open.

The issue seems to have been caused by the previous locking scheme, probably by the HTTP layer collecting the data instead of the Websocket.

At this point, the root of the cause is only guesswork. The issue prompted me to fragment the upgrade process (so now the on_open action is deferred), something that was on my internal TODO list for a while.

Along the way, the issue disappeared. I wish I know what was wrong with the previous upgrade locking scheme, so I would be sure the issue is solved and not masked... but it is what it is.

Credit to @madsheep and @nilclass, who did amazing work exposing the issue and tracking it down to the on_open callback.

bad output in sha1

Hi @boazsegev ,

#18 i use example of README and compiled but i get bad output of program:

[root@raminfp ramin]# make
gcc -Iinclude  src/sha1.c src/sha2.c src/hex.c src/jalali.c src/misc.c src/random.c src/siphash.c src/main.c -o main
[root@raminfp ramin]# 
[root@raminfp ramin]# ./main 
sha1 : /���z-(�턞��v�9����

Strange with keep-alive

Hi, Boaz!
It's again i)
At first off all, i create database prototype based on your library: https://github.com/recoilme/okdb

But some strange things found with flag keep alive(
Then i test with keep-alive - all looks good:
ab -n 1000 -c 200 -k http://127.0.0.1:8888/
Requests per second: 86452

But if i disable keep-alive:
ab -n 1000 -c 200 http://127.0.0.1:8888/
Requests per second: 33.85

I test in on mac and debian with same results.

May be i do something wrong with headers? https://github.com/recoilme/okdb/blob/master/okdb.c (sophia not used for this request)

And i dont may reproduce right now - but i see one time, then i send long value (around 1024 bytes) without keep-alive from curl it dont work

Example request:

curl -v -H "Connection: keep-alive" -X PUT -d "01234567890123456789012345678901234567890123456789012345678901234567890123456901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456701234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012" http://127.0.0.1:8888/hello
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
> PUT /hello HTTP/1.1
> User-Agent: curl/7.38.0
> Host: 127.0.0.1:8888
> Accept: */*
> Connection: keep-alive
> Content-Length: 1021
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 1021 out of 1021 bytes
< HTTP/1.1 200 OK
< Content-Length: 2
< Connection: keep-alive
< Keep-Alive: 1;timeout=5
<
* Connection #0 to host 127.0.0.1 left intact

And last - then i try to reproduce - looks like server down:

./tmp/okdb

Initialized libsock for 512000 sockets, each one requires 32 bytes.
overall ovearhead: 16384000 bytes.
Initialized packet pool for 1024 elements, each one 16424 bytes.
overall buffer ovearhead: 16818176 bytes.
=== Total: 33202176 bytes ===

* Listenning on port 8888
* Running 19 processes X 1 threads.
* [23163] Running.
* [23164] Running.
* [23161] Running.
* [23162] Running.
* [23165] Running.
* [23166] Running.
* [23167] Running.
* [23168] Running.
* [23169] Running.
* [23175] Running.
* [23177] Running.
* [23179] Running.
* [23181] Running.
* [23183] Running.
* [23185] Running.
* [23187] Running.
* [23154] Running.
* [23189] Running.
* [23191] Running.
Segmentation fault

But then i grep - i see some running procces and server proccesed request.

ps aux|grep okdb
vkuliba+ 23161  0.1  0.0 3591948 33572 pts/0   Sl   14:08   0:15 ./tmp/okdb
vkuliba+ 23164  0.1  0.0 3591948 33572 pts/0   Sl   14:08   0:16 ./tmp/okdb
vkuliba+ 23165  0.1  0.0 3591948 33572 pts/0   Sl   14:08   0:17 ./tmp/okdb
vkuliba+ 23167  0.1  0.0 3591948 33572 pts/0   Sl   14:08   0:15 ./tmp/okdb
vkuliba+ 23168  0.1  0.0 3591948 33572 pts/0   Sl   14:08   0:16 ./tmp/okdb
vkuliba+ 23175  0.1  0.0 3591948 33572 pts/0   Sl   14:08   0:16 ./tmp/okdb
vkuliba+ 24072  0.0  0.0  14644  1612 pts/0    S+   16:43   0:00 grep okdb

Is building on Windows supported?

Hi,

I am currently looking into using this framework on an upcoming project I am trying to finish. I thought that this was a good lighter alternative for a TCP implementation than LibUV.

I am curious about building on Windows. I was able to use cmake with no erroneous output however I also dont see any binaries or headers.

The makefile doesnt seem to support Windows. Am I just way off the beaten path here?

Support CoAP

CoAP is a protocol used in resource-constrained environments like IoT (see http://coap.technology.) libcoap is a popular C implementation of the protocol and includes a trivial server example. Could libcoap be used with facli.io?

Memory leak in example code?

I'm on macOS 10.14 so I cannot use Valgrind to verify my concern, but please take a look here.

// A callback called for new connections
static void echo_on_open(intptr_t uuid, void *udata) {
// Protocol objects MUST be dynamically allocated when multi-threading.
fio_protocol_s *echo_proto = malloc(sizeof(*echo_proto));
*echo_proto = (fio_protocol_s){.on_data = echo_on_data,
.on_shutdown = echo_on_shutdown,
.on_close = echo_on_close,
.ping = echo_ping};
fprintf(stderr, "New Connection %p received from %s\n", (void *)echo_proto,
fio_peer_addr(uuid).data);
fio_attach(uuid, echo_proto);
fio_write2(uuid, .data.buffer = "Echo Service: Welcome\n", .length = 22,
.after.dealloc = FIO_DEALLOC_NOOP);
fio_timeout_set(uuid, 5);
(void)udata; // ignore this
}

On L77, you allocated a chunk of memory for echo_proto, but on the very next line, you point it to a compound literal with automatic storage duration, discarding its previous value. I think this might cause a memory leak because you never called free.

To make thing even more confusing, there appears to be a related compiler bug.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.