Giter Site home page Giter Site logo

allinurl / gwsocket Goto Github PK

View Code? Open in Web Editor NEW
731.0 31.0 65.0 251 KB

fast, standalone, language-agnostic WebSocket server RFC6455 compliant

Home Page: http://gwsocket.io

License: MIT License

Makefile 0.66% M4 1.76% C 89.86% Roff 7.73%
websocket-server rfc-6455 c standalone websockets

gwsocket's People

Contributors

allinurl avatar angelskieglazki avatar cgzones avatar dertuxmalwieder avatar heavygale avatar itsanov avatar mtorromeo avatar rsmarples avatar xen0l 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

gwsocket's Issues

Release 0.2

Please release new version, it’s quite long time and many commits since the last release.

I see that you’ve literally copied gwsocket sources to the goaccess project (very bad practice, it’d be better to use at least git subtree) and it doesn’t look like they are in-sync…?

BTW, thanks for this great utility!

gwsocket as a library

Love the way gwserver currently but wonder if anyone would have time to perhaps create a library (libgwserver.so) which does not include gwserver.c so the core code can be embedded inside another process and I do not have to run the gwserver separately.

" unrecognized option `--ssl-cert' "

sys: macOS Catalina[10.15.6]

openssl version: LibreSSL 2.8.3

follow =>

$ wget http://tar.gwsocket.io/gwsocket-0.3.tar.gz
$ tar -xzvf gwsocket-0.3.tar.gz
$ cd gwsocket-0.3/
$ ./configure --with-openssl=/usr/bin/openssl/
$ make
# make install

command
' gwsocket --ssl-cert=/path/to/my/ssl/cert --ssl-key=/path/to/my/ssl/key '
or
' gwsocket --ssl-cert /path/to/my/ssl/cert --ssl-key /path/to/my/ssl/key '

then failed with
" unrecognized option `--ssl-cert' "

any thing wrong?

PS: here is my config.log
config.log

Feature request - client version of gwsocket (same style as gwsocket, but client, not server)

I found gwsocket today (27 August 2020) after some days of struggle to apply websockets with libwebsocket.

In about 1 hour, I downloaded gwsocket, compiled, installed, and configured examples just as described. Even successful with a small modification to gwsocket source code (demonstrate sending a fixed message in response to echo, rather than echo text, so I could be confident I could work with gwsocket source code.)

I am very pleased with gwsocket - it is very friendly system for inexperienced user! Thank you Gerardo Orellana!

I wish to request a client version of gwsocket - idea is it would be counterpart to gwsocket (server), with same concept of fifo/pipe local I/O, etc., and same basic design concepts (simple, clear implementation).

Having simple client of same style as gwsocket (simple, with pipe I/O) would provide benefit by enabling end-to-end websocket connectivity option for traditionally not-networked applications (in my case, industrial telemetry), where traditional IP sockets are no longer possible due to network constraints, and websockets are only solution.

(small note --- gwsocket is <100K bytes; websocket echo binary using libwebsockets and project's echo "simple example" (basically same function as gwsocket --echo mode) is ~2.5M bytes.)

Thank you again for gwsocket!

Help with FIFO Error. Bad address

I built v 0.4.0 on Buster (Raspberry Pi 4 Model B Rev 1.1)

But I get this error when trying to pipein fifo. Any help would be appreciated

$ gwsocket -p 8080 --pipein=/tmp/websocket/wspipein.fifo
 
Fatal error has occurred
Error occured at: src/websocket.c - ws_setfifo - 2292
Unable to set fifo: Bad address.

websocket.c - Line 2279+


/* Create named pipe (FIFO) with the given pipe name.
 *
 * On error, 1 is returned.
 * On success, 0 is returned. */
int
ws_setfifo (const char *pipename) {
  struct stat fistat;
  const char *f = pipename;

  if (access (f, F_OK) == 0)
    return 0;

  if (mkfifo (f, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0)
    FATAL ("Unable to set fifo: %s.", strerror (errno));
  if (stat (f, &fistat) < 0)
    FATAL ("Unable to stat fifo: %s.", strerror (errno));
  if (!S_ISFIFO (fistat.st_mode))
    FATAL ("pipe is not a fifo: %s.", strerror (errno));

  return 0;
}

Getting HTTP ERROR 400

Whenever I try to access gwsocket web UI, I receive HTTP ERROR 400. I am using gwsocket-0.3.

Below is the message that appears on the browser.

This page isn’t working If the problem continues, contact the site owner.
HTTP ERROR 400

No output on browser.

Hello there, I bookmarked this project a while ago and it turns out I need it as a temporary solution. Very neat indeed.

I followed the install instructions:

  548  wget http://tar.gwsocket.io/gwsocket-0.2.tar.gz
  549  tar -xvzf gwsocket-0.2.tar.gz 
  550  cd gwsocket-0.2/
  551  ./configure
  552  make
  553  make install

It appears to be using the pipes in /tmp/wspipein.fifo as I can cat /tmp/wspipein.fifo on Ubuntu 16.04, yet, nothing shows up in my browser.

I can confirm, gwsocket does get the requests and the pipe is working(I am just redirecting my syslog output to /tmp/wspipein.fifo):

$ cat /tmp/wspipein.fifo 
Nov 19 17:03:01 IdeaPad-Y500 CRON[11067]: (root) CMD (/usr/local/bin/sanoid --cron)
Nov 19 17:03:01 IdeaPad-Y500 CRON[11064]: (CRON) info (No MTA installed, discarding output)
Nov 19 17:03:29 IdeaPad-Y500 systemd[1]: Starting Cleanup of Temporary Directories...
Nov 19 17:03:29 IdeaPad-Y500 systemd-tmpfiles[11190]: [/usr/lib/tmpfiles.d/var.conf:14] Duplicate line for path "/var/log", ignoring.
Nov 19 17:03:29 IdeaPad-Y500 systemd[1]: Started Cleanup of Temporary Directories.
Nov 19 17:04:01 IdeaPad-Y500 CRON[11335]: (root) CMD (/usr/local/bin/sanoid --cron)
Nov 19 17:04:02 IdeaPad-Y500 CRON[11332]: (CRON) info (No MTA installed, discarding output)
Nov 19 17:05:01 IdeaPad-Y500 CRON[11586]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Nov 19 17:05:01 IdeaPad-Y500 CRON[11587]: (root) CMD (/usr/local/bin/sanoid --cron)
Nov 19 17:05:01 IdeaPad-Y500 CRON[11585]: (CRON) info (No MTA installed, discarding output)

$ cat /tmp/access.log 
127.0.0.1 - - [19/Nov/2016:16:49:17 -0800] "GET / HTTP/1.1" 400 406 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:17 -0800] "GET / HTTP/1.1" 200 406 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:18 -0800] "GET /favicon.ico HTTP/1.1" 400 349 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:18 -0800] "GET /favicon.ico HTTP/1.1" 200 349 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:19 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:19 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:19 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:19 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:39 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:39 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:39 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:39 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:40 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:40 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:40 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:40 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:44 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:44 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:44 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:44 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:50 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:51 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:49:51 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:50:04 -0800] "GET / HTTP/1.1" 400 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:50:04 -0800] "GET / HTTP/1.1" 200 432 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:50:04 -0800] "GET /favicon.ico HTTP/1.1" 400 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:50:04 -0800] "GET /favicon.ico HTTP/1.1" 200 392 "http://127.0.0.1:7890/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36" 0
127.0.0.1 - - [19/Nov/2016:16:50:58 -0800] "GET / HTTP/1.1" 400 375 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:50:58 -0800] "GET / HTTP/1.1" 200 375 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:50:58 -0800] "GET /favicon.ico HTTP/1.1" 400 356 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:50:58 -0800] "GET /favicon.ico HTTP/1.1" 200 356 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:51:09 -0800] "GET / HTTP/1.1" 400 375 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:51:09 -0800] "GET / HTTP/1.1" 200 375 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:51:11 -0800] "(null) - (null)" 400 170 "-" "-" 0
127.0.0.1 - - [19/Nov/2016:16:51:11 -0800] "(null) - (null)" 200 170 "-" "-" 0
127.0.0.1 - - [19/Nov/2016:16:54:18 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:18 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:19 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:19 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:20 -0800] "GET / HTTP/1.1" 400 375 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:20 -0800] "GET / HTTP/1.1" 200 375 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:21 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:54:21 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:25 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:25 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:26 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:26 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:26 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:26 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:32 -0800] "GET / HTTP/1.1" 400 418 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:32 -0800] "GET / HTTP/1.1" 200 418 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:35 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:35 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:36 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:36 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:36 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:36 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:37 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:37 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:37 -0800] "GET / HTTP/1.1" 400 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0
127.0.0.1 - - [19/Nov/2016:16:55:37 -0800] "GET / HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0" 0

Browser:

http://imgur.com/a/N7Ako

Am I missing something?

Strict protocol parsing

Hi,
First and most important: Nice work! Thank you!
I'm trying to connect Arduino with web browser with "gwsocket". Communication is binary.
gwsocket --strict --pipein=/dev/ttyS1 --pipeout=/dev/ttyS1 --max-frame-size=128
Unfortunately, when Arduino is restarted gwsocket strict protocol parser gets out of sync and can't return back.
I have implemented a workaround. Please have a look.
websocket.c:2687

   if (validate_fifo_packet (listener, type, size) == 1) {
 //    close (pi->fd);
 //    clear_fifo_packet (pi);
 //    ws_openfifo_in (pi);
     for(int i = 0; i < HDR_SIZE - 1; i++)
         pi->hdr[i] = pi->hdr[i+1];
     pi->hlen--;
     return;
   }

Current implementation is throwing away the complete header (12 bytes) when header is not OK. My change is to throw away just one byte and to try again.

Cheers

gwsocket 0.3 tag

Hello,

would it be possible to tag version 0.3? It seems that the version in configure.ac has been already bumped to 0.3.

make fails on Ubuntu 20.

When configured with --enable-ssl make spews the following errors:

src/websocket.c: In function ‘shutdown_ssl’:
src/log.h:48:24: warning: this statement may fall through [-Wimplicit-fallthrough=]
   48 | #define LOG(x) do { if (DEBUG_TEST) dbg_printf x; } while (0)
      |                        ^
src/websocket.c:730:5: note: in expansion of macro ‘LOG’
  730 |     LOG (("SSL: SSL_shutdown, probably unrecoverable, forcing close.\n"));
      |     ^~~
src/websocket.c:731:3: note: here
  731 |   case SSL_ERROR_ZERO_RETURN:
      |   ^~~~
src/websocket.c: In function ‘send_ssl_buffer’:
src/websocket.c:862:8: warning: this statement may fall through [-Wimplicit-fallthrough=]
  862 |     if ((bytes < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)))
      |        ^
src/websocket.c:865:3: note: here
  865 |   case SSL_ERROR_ZERO_RETURN:
      |   ^~~~
src/websocket.c: In function ‘accept_ssl’:
src/websocket.c:766:8: warning: this statement may fall through [-Wimplicit-fallthrough=]
  766 |     if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
      |        ^
src/websocket.c:772:3: note: here
  772 |   case SSL_ERROR_ZERO_RETURN:
      |   ^~~~
src/websocket.c: In function ‘read_ssl_socket’:
src/websocket.c:903:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
  903 |       if ((bytes < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)))
      |          ^
src/websocket.c:905:5: note: here
  905 |     case SSL_ERROR_ZERO_RETURN:
      |     ^~~~
depbase=`echo src/xmalloc.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -DHAVE_CONFIG_H -I. -I./src    -O2 -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare -Wredundant-decls -Wbad-function-cast -Winline -Wcast-align -Wextra -Wdeclaration-after-statement -Wno-missing-field-initializers  -MT src/xmalloc.o -MD -MP -MF $depbase.Tpo -c -o src/xmalloc.o src/xmalloc.c &&\
mv -f $depbase.Tpo $depbase.Po
gcc -O2 -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare -Wredundant-decls -Wbad-function-cast -Winline -Wcast-align -Wextra -Wdeclaration-after-statement -Wno-missing-field-initializers  -rdynamic -rdynamic  -o gwsocket src/base64.o src/gslist.o src/gwsocket.o src/log.o src/sha1.o src/websocket.o src/xmalloc.o  -lssl
/usr/bin/ld: src/websocket.o: undefined reference to symbol 'ERR_get_error@@OPENSSL_1_1_0'
/usr/bin/ld: /lib/x86_64-linux-gnu/libcrypto.so.1.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [Makefile:472: gwsocket] Error 1

OpenSSL 1.1.0 is not available to Ubuntu 20

$ openssl version -a
OpenSSL 1.1.1f  31 Mar 2020
built on: Mon Apr 20 11:53:50 2020 UTC
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(int) blowfish(ptr)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -fdebug-prefix-map=/build/openssl-P_ODHM/openssl-1.1.1f=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
OPENSSLDIR: "/usr/lib/ssl"
ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-1.1"
Seeding source: os-specific

gwsocket+apache: status 200 instead of 101

Ubuntu14.04 + Apache 2.4.7 + gwsocket 0.3 with SSL

I have found that if i serve both http and https traffic, and i have gwsocket service running like this:
/usr/local/bin/gwsocket_ssl --port=8080 --ssl-cert=/etc/apache2/ssl/apache_ss.crt --ssl-key=/etc/apache2/ssl/apache_ss.key --access-log=/tmp/gw_access.log

and access the site via http, this results in:

127.0.0.1 - - [09/Dec/2019:12:20:01 +0100] "(null) - (null)" 400 0 "-" "-" 0
127.0.0.1 - - [09/Dec/2019:12:20:01 +0100] "(null) - (null)" 200 0 "-" "-" 0

while accessing via https results in:

127.0.0.1 - - [09/Dec/2019:12:38:14 +0100] "GET / HTTP/1.1" 200 703 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 0
127.0.0.1 - - [09/Dec/2019:12:38:15 +0100] "GET / HTTP/1.1" 101 703 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 0

apache configs:

<VirtualHost *:80>
    ServerName servername
    ServerAdmin webmaster@localhost

    ProxyPass "/ws"  "ws://127.0.0.1:8080/"
    ProxyPassReverse "/ws"  "ws://127.0.0.1:8080/"
    ProxyRequests Off

    DocumentRoot /var/www/html
    <Directory /var/www/html>
        Options -Indexes +FollowSymLinks -SymLinksIfOwnerMatch +MultiViews
        AllowOverride None
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/se_error.log
    CustomLog ${APACHE_LOG_DIR}/se_access.log combined

</VirtualHost>
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        ServerName servername
        ServerAlias servername
        ServerAdmin webmaster@localhost

        SSLProxyEngine on
	ProxyPass "/wss"  "wss://127.0.0.1:8080/"
        ProxyPassReverse "/wss"  "wss://127.0.0.1:8080/"
        ProxyRequests Off

	DocumentRoot /var/www/html
        <Directory /var/www/html>
            Options -Indexes +FollowSymLinks -SymLinksIfOwnerMatch +MultiViews
            AllowOverride None
            Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/se_error.log
        CustomLog ${APACHE_LOG_DIR}/se_access.log combined

        SSLEngine on
        SSLCertificateFile      /etc/apache2/ssl/apache_ss.crt
        SSLCertificateKeyFile   /etc/apache2/ssl/apache_ss.key

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>

        BrowserMatch "MSIE [2-6]" \
        nokeepalive ssl-unclean-shutdown \
        downgrade-1.0 force-response-1.0
        # MSIE 7 and newer should be able to use keepalive
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

    </VirtualHost>
</IfModule>

if i change proxypass directive in http site definition to watch port 8081, and run another instance of gwsocket like this, then i can access both:
`/usr/local/bin/gwsocket_ssl --port=8081``

    ProxyPass "/ws"  "ws://127.0.0.1:8081/"
    ProxyPassReverse "/ws"  "ws://127.0.0.1:8081/"

edit

    ProxyPass "/wss"  "wss://127.0.0.1:8080/"
    ProxyPassReverse "/wss"  "wss://127.0.0.1:8080/"

/edit

Is this by design?
is there a way to circumvent this, or should i be using two gwsocket services running on the same machine?

No data when starting to write before first client is connected

I have the problem(?) that when I start piping into /tmp/wspipein.fifo after starting gwsocket, but before a client is connected, I never get data (i.e. not even data that is piped into /tmp/wspipein.fifo after the client has connected). Otherwise (if I first cause a client to connect, and then start piping), everything works.

Is this the expected behavior (if not, it might be something related to my custom CMake based build and related config that I have to look into my side)?

Fails to compile with OpenSSL 1.1.0 or newer

OpenSSL 1.1.0 introduces breaking changes which prevents gwsocket from compiling. This is what I did to get it to compile with OpenSSL 1.1.1 on Debian 10:

  • SSL_library_init needs to be replaced with SSL_SESSION_new.
  • CRYPTO_num_locks is now a macro, so the AC_CHECK_LIB needs to be removed.
  • -lcrypto needs to be added to LDFLAGS. I did ./configure --with-openssl LDFLAGS=-lcrypto.

feedback

> git clone https://github.com/allinurl/gwsocket.git
> cd gwsocket
> autoreconf -fiv
> ./configure
> make
> doas dmesg -w | ./gwsocket --port 4000 --access-log=/dev/stdout
127.0.0.1 - - [27/Jun/2023:23:33:05 +0200] "GET / HTTP/1.1" 400 651 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 0
127.0.0.1 - - [27/Jun/2023:23:33:05 +0200] "GET / HTTP/1.1" 200 651 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 0
127.0.0.1 - - [27/Jun/2023:23:33:13 +0200] "GET / HTTP/1.1" 400 651 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 0
127.0.0.1 - - [27/Jun/2023:23:33:13 +0200] "GET / HTTP/1.1" 200 651 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 0

For each browser connection, the server logs two connections, where the first one is a rejection (400).

This is Fedora Linux 38.

Cannot write to wspipein.fifo

Commands provided on the manual page for sending data doesn't work for me.
E.g.
sudo tail -f /var/log/nginx/access.log > /tmp/wspipein.fifo (NO RESULTS)
also tried python code attached there - same result. Just empty fifo file.
Tried on Mac OS and Ubuntu 18.04.

wspipeout is also empty

What may cause problem? Running under ngrok in pair with nginx, clients - Android

How can I get the same text formatting effect as on the website?

I know this isn't an issue with the project, so sorry in advance. I was wondering how you created the nice multi-color formatting effect on the front page of the gwsocket.io as this would be useful for my own implementation. I would appreciate it if you could share some pointers as to how this could be recreated as I am completely clueless here!

Serving files via sendfile

Would be helpful to include a static web server to deliver the client web app. I was thinking of adding two more CLI options:

--web-root=/path/to/webroot/
--pipeurl=/path/to/websocket

This allows for websites to be fully dynamic while remaining language agnostic using websockets for any dynamic io and the static web servers for the rest.

add Protocol support in gwsocket

Websockets offer the option to specify a protocol at connection, yet currently gwsocket drops it silently.
This is to request the feature of tracking the protocol specified at connection so that in strict mode packets can be isolated depending on protocol.

access from webserver

Hey

all seems to work,
except when i am trying to access from webserver I get empty page

in the video example you are using a /terminal.html page

i also tried to parse your home page to sse how you do it in the frame, but could not figure it out how

in MAN page you have an example of HTML snippet to communicate wit the server, which works, but not sure what command to send

whatever I type in there, is also sent and received as same string

otherwise I can compile and see the traffic coming to the gwsocket server (gwsocket access log)

could you please post an example of either

  1. http requests directly to the gwsocket server - e.g. http://localhost:7890/someting/
  2. example of HTML page that pulls in the output of remote gwsocket (ws://localhost:7890) in a frame or other means

I can already see the live goaccess feed in a browser coming, should be pretty cool !!!

many thanks

-Duro

Using in multible domains on one port

As @ws-h-ono wrote on allinurl/goaccess issue #444

"Can you somehow try to share web socket ports against multiple sites? (Maybe by using URL path like, wss://ws.domain/site.domain ?)"

I like that Idea, even I have limited ports to spare.

Is it possible to Publish data from REDIS instead of file ?

Hi,

I want to send data from REDIS server to the websocket server and then post to BROWSER.

Is it possible instead of using a file ?

What is the part of the code responsible to read the file and send the data to client ?

Last thing, can i compile it in WINDOWS ?

WSS secured connection supported ?

Thank's in advance.

Support for multiple instances?

Thanks for making gwsocket, it is a very cool and useful project! At the moment I understand we support 1 instance /tmp/wspipein.fifo -> terminal.html, is it possible we can support multiple instances as in we have

/tmp/wspipein-1.fifo -> terminal-1.html
/tmp/wspipein-2.fifo -> terminal-2.html
/tmp/wspipein-3.fifo -> terminal-3.html

with only have 1 gwsocket process running in the background?

Can't make socket connection

Hi,

I've installed gwsocket following these instructions:

$ wget http://tar.gwsocket.io/gwsocket-0.2.tar.gz
$ tar -xzvf gwsocket-0.2.tar.gz
$ cd gwsocket-0.2/
$ ./configure
$ make
$ make install

Then I run the program like this:

$ gwsocket &

Check if the process is started and socket is listening:

$ ps ax | grep gwsocket
 2925 pts/0    S      0:00 gwsocket
 2936 pts/0    S+     0:00 grep gwsocket

$ netstat -atn | grep 7890
tcp        0      0 0.0.0.0:7890                0.0.0.0:*                   LISTEN      

But when using your html example the connection to the socket fails. The html file throws the following error:

WebSocket connection to 'ws://localhost:7890/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

window.onload @ terminal.html:20

The code from line 20 is:

var socket = new WebSocket('ws://localhost:7890');

As far as I know iptables is off and firewall is off too.

$ service iptables status
iptables: Firewall is not running.

$ cat /etc/redhat-release 
CentOS release 6.9 (Final)
$ uname -a
Linux centosdev.localdomain 2.6.32-696.30.1.el6.x86_64 #1 SMP Tue May 22 03:28:18 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

What is missing? Why I can't establish the connection?

Regards,
-Gerardo

Listening on IPv6.

gwsocket won't listen on IPv6.

gwsocket --addr "[::]" --echo-mode
gwsocket --addr :: --echo-mode

No result in ss --ipv6 --tcp --all

OpenBSD 5.9 - 400 Invalid Request

Hi,

I have no problem with the collection, but does not work

# gwsocket &
# vmstat -w 10 > /tmp/wspipein.fifo

lynx response is:

# lynx http://localhost:7890/terminal.html                                
Looking up localhost:7890
Making HTTP connection to localhost:7890
Sending HTTP request.
HTTP request sent; waiting for response.
Alert!: HTTP/1.1 400 Invalid Request
Data transfer complete

lynx: Start file could not be found or is not text/html or text/plain
Exiting...

API to disconnect client in strict mode

  • In the event that a client fails to pass the authorization process, it becomes necessary to disconnect them from the WebSocket connection promptly;
  • Load balancing...

Allow to read from gwsocket’s stdin with (unnamed) pipe

It’d be great to be able to do simply tail -f /var/log/nginx/access.log | gwsocket.

Currently it’s possible to read user input from stdin and/or write to stdout using gwsocket --pipein=/dev/stdin --pipeout=/dev/stdout, but this doesn’t work with |.

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.