Giter Club home page Giter Club logo

rymfony's People

Contributors

antiseptikk avatar cydonia7 avatar kayneth avatar kevinpapst avatar macintoshplus avatar pierstoval avatar shine-neko 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

rymfony's Issues

[Ubuntu WSL 1] rymfony server:start cannot unwrap unexisting fpm-conf.ini

Hello!

First, thank you for your work!
I wanted to try it out on a WSL 1 Ubuntu. Everything worked perfectly with new:symfony and php:list. Here is the result for a PHP installation done with ASDF-VM

 | Binary path                           |
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
 | /home/dballandras/.asdf/shims/php     |
 | /home/dballandras/.asdf/shims/php-fpm |

But for server:start, i've got an error. I cannot write to ~/.rymfony/fpm-conf.ini. Here is the backtrace:

INFO - Starting PHP...
INFO - Using php-fpm
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/php/server_fpm.rs:90:20
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:486
  11: rust_begin_unwind
             at src/libstd/panicking.rs:388
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:101
  13: core::option::expect_none_failed
             at src/libcore/option.rs:1272
  14: rymfony::php::server_fpm::start
  15: rymfony::php::php_server::start
  16: rymfony::commands::serve::serve
  17: rymfony::main
  18: std::rt::lang_start::{{closure}}
  19: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
  20: std::panicking::try::do_call
             at src/libstd/panicking.rs:297
  21: std::panicking::try
             at src/libstd/panicking.rs:274
  22: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  23: std::rt::lang_start_internal
             at src/libstd/rt.rs:51
  24: main
  25: __libc_start_main
  26: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

I even touch the file and restarted the command but it did the same.

I will try to rebuild manually the project and search for the issue and report the result here! πŸ˜„

PHP does not receive all Cookies sent in HTTP query

How to reproduce:

  1. Put <?php phpinfo(); into index.php file
  2. Start rymfony serve to serve this file
  3. Call it in the browser
  4. Set one cookie with Javascript dev console document.cookie="test2=1"
  5. refresh the page, see the cookie in 'Variables' section
  6. Set two cookie with Javascript dev console document.cookie="test3=2"
  7. refresh the page, see the cookie in 'Variables' section. ONLY one cookies is present!

image

Detect Systemd presence for php-fpm on *nix systems

When running on Docker or some specific distros, we can have such output when starting the server:

web_1  |  2021-01-25T22:16:13.772Z  INFO > Starting PHP...
web_1  |  2021-01-25T22:16:13.814Z  INFO > Using php-fpm
web_1  |  2021-01-25T22:16:13.815Z  INFO > Running php-fpm with PID 10
web_1  | [25-Jan-2021 22:16:13] ERROR: [/root/.rymfony/fpm-conf.ini:12] unknown entry 'systemd_interval'
web_1  | [25-Jan-2021 22:16:13] ERROR: failed to load configuration file '/root/.rymfony/fpm-conf.ini'
web_1  | [25-Jan-2021 22:16:13] ERROR: FPM initialization failed
web_1  | thread 'main' panicked at 'PHP server exited with exit code: 78', src/php/php_server.rs:50:29
web_1  | note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The systemd_interval value should be dropped when running a system that isn't started with systemd.

Across some quick research, it seems that this command might help:

ps --no-headers -o comm 1

It either returns init or systemd, and might help detecting this.

There are other ways, such as running systemctl to see if it's available or not, or check if file /sbin/init shows a symbolic link or an executable.

I'm not sure which one should be used by Rymfony, but what I'm sure is that this should be a one-time system check, cached somewhere in Rymfony's global configuration.

Fix public directory proxy

For now, when you make an HTTP request to a directory like http://127.0.0.1:8000/admin/ and the directory actually exists in the server, Rymfony's proxy_server will try to render it, instead of passing it to FastCGI.

This kind of directory pass shouldn't happen, and instead the whole path should be forwared to the FastCGI process.

Either the get_render_static_path() function should be changed in proxy_server.rs, or the let render_static ... that's created just after. Feel free to check πŸ˜„

Distribution over system level package managers

First of all, thank you for all the effort so far. Some features in this project are much needed improvements over the actual symfony cli binary. I know my request is pretty big, yet i wanna propose to distribute the binaries over system level package managers. In detail:

  • MacOS = Homebrew
  • Windows = Chocolatey
  • Ubuntu = Apt

I have a vague idea of the work needed to implement my proposal, so feel free to discard my thoughts, if this is impossible to do with your available time.

"rymfony php:list" does not display a list of all PHP versions available (Ubuntu 18.04)

Tested with rymfony.ubuntu-latest and also a compiled version with cargo build --release

rymfony php:list command does not display a list
of all PHP versions available on the computer :

rymfony.ubuntu-latest php:list
       # β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       # | Binary path     |
       # β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
       # | /usr/bin/php7.4 |
       # β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

List of all PHP versions available on the computer :

sudo update-alternatives --config php
       # Il existe 4 choix pour l'alternative php (qui fournit /usr/bin/php).
       # 
       #   SΓ©lection   Chemin           PrioritΓ©  Γ‰tat
       # ------------------------------------------------------------
       #   0            /usr/bin/php7.4   74        mode automatique
       # * 1            /usr/bin/php7.0   70        mode manuel
       #   2            /usr/bin/php7.2   72        mode manuel
       #   3            /usr/bin/php7.3   73        mode manuel
       #   4            /usr/bin/php7.4   74        mode manuel


whereis php
       #   php: /usr/bin/php7.4 /usr/bin/php7.2 /usr/bin/php /usr/bin/php7.0 /usr/bin/php7.3 /usr/lib/php /etc/php /usr/share/php7.2-xml /usr/share/php7.2-zip /usr/share/php7.3-opcache /usr/share/php7.0-mcrypt /usr/share/php7.3-common /usr/share/php7.2-opcache /usr/share/php7.0-mbstring /usr/share/php7.0-opcache /usr/share/php /usr/share/php7.4-intl /usr/share/php7.2-json /usr/share/php7.0-curl /usr/share/php7.4-readline /usr/share/php7.3-readline /usr/share/php7.0-xml /usr/share/php7.4-mbstring /usr/share/php7.3-xml /usr/share/php7.0-readline /usr/share/php7.0-json /usr/share/php7.4-opcache /usr/share/php7.4-common /usr/share/php7.3-mbstring /usr/share/php7.4-curl /usr/share/php7.0-intl /usr/share/php7.0-common /usr/share/php7.3-json /usr/share/php7.2-common /usr/share/php7.3-sqlite3 /usr/share/php7.2-readline /usr/share/php7.2-mbstring /usr/share/php7.4-json /usr/share/php7.4-xml /usr/share/php7.2-curl /usr/share/php7.3-curl /usr/share/man/man1/php.1.gz

additional information :

rymfony --version
       # rymfony 0.1

php -v
        # PHP 7.4.8 (cli)

composer --version
       # Composer 1.6.3 2018-01-31 16:28:17

cat /etc/os-release 
       # NAME="Ubuntu"
       # VERSION="18.04.4 LTS (Bionic Beaver)"

cargo --version
       # cargo 1.45.1 

[PHP] Allow overriding PHP's binary based on a local `.php-version` file

The file should only contain a version flag.

This version flag must be used to select a PHP version that is visible in the rymfony php:list command.

The list of PHP binaries is also available in the $HOME/.rymfony/php-versions.json file (if the php:list command was called at least once).

Also, a version flag like 7.2 should match the latest 7.2 version available in all binaries. If you for instance have 7.2.1 and 7.2.5, the latest should be selected.

[PHP] Deserialize `php-versions.json` and reuse it at runtime

For now, running rymfony php:list will save the resulting binaries paths into php-versions.json, using the great serde crate.

When running rymfony serve, the crate::php::binaries::current() function should deserialize this JSON file if it exists.

If it doesn't, it should run crate::php::binaries::all() to fetch them all, and print a warning to tell the user to run the rymfony php:list command to improve performances.

The reason why I want this warning is to allow users to never write anything on the disk, in case they have a read-only filesystem.

This doesn't happen a lot, but a single call to rymfony php:list doesn't cost much, and can be automated if necessary.

Why not focusing only on prod experience?

Hi @Pierstoval very nice project!

I had the same idea few months ago πŸ˜‰.As we're currently building a project on which we were deploying on AWS ECS, I didn't want building & deploying heavy containers. I can share you our experience because maybe it can orient some choices about your project, depending on your true goals behind it.

As Symfony cli wasn't recommanded for production, we where using it anyway to deploy on our staging/preproduction environments because this was pretty handy: we didn't have to take time on this infra part, on this bootstraping project we wanted to focus on user features.. This was working pretty well... except few drawbacks:

  1. Symfony cli detection systems is great but only for development environments. I don't want it on production this is useless overhead.
  2. I wasn't able to make my infrastructure fully immutable (read only containers), mainly because it generates fpm configuration at runtime. I prefer from far writing my own configuration and package it by myself into the container image.
  3. Some crashes and closed source: after some time the main process was not able to communicate with fpm and it was neither frankly crashing neither restoring a functional state by itself. Also I'm not sure if in Symfony cli fpm runs as a child process of this main process or not and which respawn strategy is in place.

Past week, I've migrated our ECS infra to AWS Lambda so I don't nee anymore such http to fast-cgi proxy at the moment. But... since a lot of people run php in containers and have no other official alternative than running php as an apache module on production (if they use official php images, otherwise they can always try nginx/php-fpm couple but needs to share or copy same filesystem, not very sexy nor simple & elegant setup).

I'm pretty sure there's a big interest for a robust, performant, secure & lightweight http server solution on top of php-fpm that fits well for php production deployments in docker containers. this is why I wanted to share you my mindset on this subject.

[Windows] Unable to build

  1. I have installed the latest version of Rust lang (x64) on Windows 10
  2. I have run cargo build on Rymfony folder

This is the result:

X:\>cargo build
   Compiling autocfg v1.0.1
   Compiling unicode-xid v0.2.1
   Compiling cfg-if v0.1.10
   Compiling lazy_static v1.4.0
LLVM ERROR: IO failure on output stream: bad file descriptor
error: could not compile `cfg-if`

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
LLVM ERROR: IO failure on output stream: bad file descriptor
LLVM ERROR: IO failure on output stream: bad file descriptor
LLVM ERROR: IO failure on output stream: bad file descriptor
error: build failed

[MacOS] FPM crashes with: unknown entry 'systemd_interval'

Starting for the first time without changing anything manually:

~/Downloads/rymfony.macOS-latest server:start
INFO - Starting PHP...
INFO - Using php-fpm
INFO - Running php-fpm with PID 62448
[25-Aug-2020 18:53:50] ERROR: [/Users/kevin/.rymfony/fpm-conf.ini:12] unknown entry 'systemd_interval'
[25-Aug-2020 18:53:50] ERROR: failed to load configuration file '/Users/kevin/.rymfony/fpm-conf.ini'
[25-Aug-2020 18:53:50] ERROR: FPM initialization failed
thread 'main' panicked at 'PHP server exited with exit code: 78', src/php/php_server.rs:56:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

cat /Users/kevin/.rymfony/fpm-conf.ini

[global]
log_level = notice

; Output to stderr
error_log = /dev/fd/2

; This should be managed by Rymfony.
; This gives the advantage of keeping control over the process,
; and possibly retrieve logs too (since logs can be piped with fpm's stderr with current config)
daemonize = no
systemd_interval = 0

[www]
; Only works if launched as a root user
; TODO: check if this can be usable anyway
;user = 502
;group = 20

listen = 127.0.0.1:65535
listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.status_path = /_fpm-status

; Output to stderr
php_admin_value[error_log] = /dev/fd/2
php_admin_flag[log_errors] = on

; Redirect stdout and stderr to main error log instead of /dev/null (default config for fastcgi)
catch_workers_output = yes

; This allows injecting custom env vars like with "APP_ENV=dev rymfony serve"
clear_env = no

And:

~/Downloads/rymfony.macOS-latest php:list
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
| Binary path             |
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
| /usr/local/bin/php      |
| /usr/local/sbin/php-fpm |
| /usr/local/bin/php      |
| /usr/bin/php            |
| /usr/sbin/php-fpm       |
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

As https://www.php.net/manual/en/install.fpm.configuration.php says:

When FPM is build with systemd integration, specify the interval, in second, between health report notification to systemd. Set to 0 to disable. Default value: 10.

So it seems my FPM is not compiled with support for systemd. The config line is not simply ignored but FPM crashes.
Also mentioned here.

Unfortunately I cannot change the auto generated fpm config, because it will be overwritten upon the next start.
When changing the config and removing write permissions rymfony crashes, as it can't write the config.

My complete Dev setup is installed via Brew, so I assume this error will happen to most users with a current PHP 7.4.8 setup on macOS Catalina 10.15.6 (19G2021).

Anything I can do to help debugging/fixing this issue?
All I could find to check for systemd support is the compile flag --with-fpm-systemd that activates it.
Therefor php -i|grep with-fpm-systemd shows nothing here.

Server starts correctly, but errors appear when I try to consult server URL

Server starts correctly, but errors appear when I try to consult server URL.

target/release/rymfony server:start --port 8989 
       # INFO - Starting PHP...
       # INFO - Running native PHP server with PID 15360
       # [Sun Aug  2 13:27:05 2020] PHP 7.4.8 Development Server (http://127.0.0.1:65535) started
       # INFO - PHP server is ready
       # INFO - PHP started with module CLI
       # INFO - Starting HTTP server...
       # INFO - Configured document root: /home/fabrice/Bureau/test_rymfony/rymfony
       # INFO - PHP entrypoint file: /home/fabrice/Bureau/test_rymfony/rymfony/index.php
       # INFO - Server listening to http://127.0.0.1:8989

Error with CURL

curl -v http://127.0.0.1:8989
       # * Rebuilt URL to: http://127.0.0.1:8989/
       # *   Trying 127.0.0.1...
       # * TCP_NODELAY set
       # * Connected to 127.0.0.1 (127.0.0.1) port 8989 (#0)
       # > GET / HTTP/1.1
       # > Host: 127.0.0.1:8989
       # > User-Agent: curl/7.58.0
       # > Accept: */*
       # > 
       # * Empty reply from server
       # * Connection #0 to host 127.0.0.1 left intact
       # curl: (52) Empty reply from server

Rymfony log

INFO - HTTP/1.1 GET /
[Sun Aug  2 13:29:34 2020] 127.0.0.1:36746 Accepted
[Sun Aug  2 13:29:34 2020] 127.0.0.1:36746 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:29:34 2020] 127.0.0.1:36746 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Error with Chormium

SΓ©lection_001

Rymfony log

INFO - HTTP/1.1 GET /
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38894 Accepted
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38894 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38894 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38896 Accepted
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38896 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38896 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38900 Accepted
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38900 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:45:12 2020] 127.0.0.1:38900 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18

Error with Firefox

SΓ©lection_002

Rymfony log

INFO - HTTP/1.1 GET /
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41150 Accepted
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41150 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41150 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41154 Accepted
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41154 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41154 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41158 Accepted
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41158 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41158 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41162 Accepted
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41162 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:49:27 2020] 127.0.0.1:41162 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41530 Accepted
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41530 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41530 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41532 Accepted
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41532 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41532 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18
INFO - HTTP/1.1 GET /
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41536 Accepted
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41536 Invalid request (Malformed HTTP request)
[Sun Aug  2 13:50:12 2020] 127.0.0.1:41536 Closing
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', src/http/fastcgi_handler.rs:82:18

additional information :

rymfony --version
       # rymfony 0.1

php -v
        # PHP 7.4.8 (cli)

composer --version
       # Composer 1.6.3 2018-01-31 16:28:17

cat /etc/os-release 
       # NAME="Ubuntu"
       # VERSION="18.04.4 LTS (Bionic Beaver)"

cargo --version
       # cargo 1.45.1 

[HTTP server] Detach the PID file and use a global system

For now, the running server's details are available through its PID, and the PID is available in the .pid file that is at the project's root.

This system must change for something better and global.

Roadmap of this issue:

  • Create a hash of every project (like a sha1 of the full path or something, or an "urlized" version of it)
  • For every project, create a directory in $HOME/.rymfony/
  • Store the PID and php-fpm.ini config in this global directory.
  • Refactor the stop command to use the global path to find the PID.

This will in the end allow users to customize the php-fpm configuration for each project if they like (which is a good thing in the end), instead of relying on a single configuration.

This will also lead the path to a server:list command in the future.

php:list on MacOS throws error

Hello,

The rymfony php:list command throws a "panic" message on MacOS Big Sur.

❯ rymfony php:list
thread 'main' panicked at 'Version "WARNING: PHP is not recommended
PHP is included in macOS for compatibility with legacy software.
Future versions of macOS will not include PHP.
PHP 7.3.24-(to be removed in future macOS) (cli) (built: May  8 2021 09:40:37) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.24, Copyright (c) 1998-2018 Zend Technologies
" for PHP binary "/usr/bin/php" is invalid.', src/php/binaries.rs:260:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
❯ php -v
PHP 7.4.16 (cli) (built: Mar  4 2021 20:49:25) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.16, Copyright (c), by Zend Technologies

I would like to help, but I don't know rust :)

"rymfony news:symfony" works fine

rymfony news:symfony command works fine ! πŸ‘


additional information :

rymfony --version
       # rymfony 0.1

php -v
        # PHP 7.4.8 (cli)

composer --version
       # Composer 1.6.3 2018-01-31 16:28:17

cat /etc/os-release 
       # NAME="Ubuntu"
       # VERSION="18.04.4 LTS (Bionic Beaver)"

cargo --version
       # cargo 1.45.1 

Error on PNG assets access

OS: Linux Ubuntu 20.04.1 LTS
PHP: 7.3.26 FPM
Rymfony: rymfony 0.1.0-ubuntu-829e2b47-nightly

Error when this image is requested:

 2021-01-14T07:46:56.687Z  INFO > GET /var/site/storage/images/_aliases/customer_logo_1/8/8/9/2/2988-3-fre-FR/customers%20logo.png
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: 

No error when I replace the space %20 by an underscore.

[windows] how to provide directory to find PHP

On Windows, I manage many PHP version with this arbo:

sites
    tools
        php72_nts
        php73_nts
        php74_nts
        php80_nts
        bin
            php72.bat
            php73.bat
            php74.bat
            php80.bat

The directory d:\sites\tools\bin is in PATH env variable.

image

How to allow Rymfony to found all php version?

Set-Cookie header lost in response

If the serveur send multiple Set-Cookie response header, only one is received by the browser

image

On left, Rymfony response, on right Symfony Cli response.

Rymfony and SymfonyCli serve the same project.

Error on request

Configuration:

$ rymfony --version
rymfony 0.1.0-ubuntu-6a6e74fc-nightly

$ rymfony php:list
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Version β”‚ PHP CLI         β”‚ PHP FPM              β”‚ PHP CGI β”‚ System β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 7.2.34  β”‚ /usr/bin/php7.2 β”‚                      β”‚         β”‚        β”‚
β”‚ 7.3.24  β”‚ /usr/bin/php7.3 β”‚                      β”‚         β”‚        β”‚
β”‚ 7.4.13  β”‚ /usr/bin/php7.4 β”‚ /usr/sbin/php-fpm7.4 β”‚         β”‚ *      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

$ bin/console --version
Symfony 5.1.8 (env: dev, debug: true)

$ uname -a
Linux xxxxx 5.4.0-54-generic #60-Ubuntu SMP Fri Nov 6 10:37:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Error With Chromium

Rymfony log:

 rymfony serve
 2020-12-02T10:55:47.436Z  INFO > Starting PHP...
 2020-12-02T10:55:47.882Z  INFO > Using php-fpm
 2020-12-02T10:55:47.882Z  INFO > Running php-fpm with PID 90323
[02-Dec-2020 11:55:47] NOTICE: fpm is running, pid 90323
[02-Dec-2020 11:55:47] NOTICE: ready to handle connections
[02-Dec-2020 11:55:47] NOTICE: systemd monitor disabled
 2020-12-02T10:55:48.882Z  INFO > PHP server is ready
 2020-12-02T10:55:48.882Z  INFO > PHP started with module FPM
 2020-12-02T10:55:48.882Z  INFO > Starting HTTP server...
 2020-12-02T10:55:48.882Z  INFO > Configured document root: /home/xxxx/dev/xxxx/xxxx/public/
 2020-12-02T10:55:48.882Z  INFO > PHP entrypoint file: index.php
 2020-12-02T10:55:48.888Z  INFO > TlsServer::run; addr=127.0.0.1:8000
 2020-12-02T10:55:48.888Z  INFO > listening on https://127.0.0.1:8000 
 2020-12-02T10:55:55.766Z ERROR > TLS alert received: Message {
    typ: Alert,
    version: TLSv1_3,
    payload: Alert(
        AlertMessagePayload {
            level: Fatal,
            description: IllegalParameter,
        },
    ),
}
 2020-12-02T10:55:56.824Z ERROR > TLS alert received: Message {
    typ: Alert,
    version: TLSv1_3,
    payload: Alert(
        AlertMessagePayload {
            level: Fatal,
            description: IllegalParameter,
        },
    ),
}
 2020-12-02T10:56:01.850Z ERROR > TLS alert received: Message {
    typ: Alert,
    version: TLSv1_3,
    payload: Alert(
        AlertMessagePayload {
            level: Fatal,
            description: IllegalParameter,
        },
    ),
}

Chrome error:

image

Error With cURL

Rymfony logs

$ rymfony serve
 2020-12-02T10:57:51.272Z  INFO > Starting PHP...
 2020-12-02T10:57:51.766Z  INFO > Using php-fpm
 2020-12-02T10:57:51.766Z  INFO > Running php-fpm with PID 90637
[02-Dec-2020 11:57:51] NOTICE: fpm is running, pid 90637
[02-Dec-2020 11:57:51] NOTICE: ready to handle connections
[02-Dec-2020 11:57:51] NOTICE: systemd monitor disabled
 2020-12-02T10:57:52.766Z  INFO > PHP server is ready
 2020-12-02T10:57:52.766Z  INFO > PHP started with module FPM
 2020-12-02T10:57:52.766Z  INFO > Starting HTTP server...
 2020-12-02T10:57:52.766Z  INFO > Configured document root: /home/xxxx/dev/xxxx/xxxxx/public/
 2020-12-02T10:57:52.766Z  INFO > PHP entrypoint file: index.php
 2020-12-02T10:57:52.769Z  INFO > TlsServer::run; addr=127.0.0.1:8000
 2020-12-02T10:57:52.769Z  INFO > listening on https://127.0.0.1:8000 
 2020-12-02T10:58:06.482Z  INFO > GET /


Curl access:

curl -kv https://127.0.0.1:8000
*   Trying 127.0.0.1:8000...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=FR; O=Orbitale.io; CN=Orbitale CA (dev)
*  start date: Dec  2 08:14:49 2020 GMT
*  expire date: Dec  2 08:14:49 2021 GMT
*  issuer: C=FR; O=Orbitale.io; CN=Orbitale CA (dev)
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x562fb872bdb0)
> GET / HTTP/2
> Host: 127.0.0.1:8000
> user-agent: curl/7.68.0
> accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
< HTTP/2 503 
< content-type: text/html
< date: Wed, 02 Dec 2020 10:58:06 GMT
< content-length: 871
< 

        <!DOCTYPE html>
        <html>
            <head>
                <meta charset="utf-8" />
                <title>Internal server error</title>
                <style>
                    body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
                    .container { margin: 30px; max-width: 600px; }
                    h1 { color: #dc3545; font-size: 24px; }
                    h2 { font-size: 18px; }
                </style>
            </head>
            <body>
                <div class="container">
                    <h1>Internal server error "503"</h1>
                    <h2>The server returned:</h2>
                    <pre>Connection refused (os error 111)</pre>
                </div>
            </body>
        </html>
* Connection #0 to host 127.0.0.1 left intact

Unable to download binary file from PHP

When the query response is binary, the conversion to UTF8 string not work.

Result for a MP4 download:

 2021-01-15T08:38:10.203Z  INFO rymfony::http::proxy_server    > GET /content/download/71/file/video-2.mp4
 2021-01-15T08:38:10.203Z DEBUG fastcgi_client::client         > [id = 1] Params will be sent: ParamPairs([ParamPair { name_length: Short(11), value_length: Short(3), name_data: "HTTP_ACCEPT", value_data: "*/*" }, ParamPair { name_length: Short(11), value_length: Long(2147483804), name_data: "HTTP_COOKIE", value_data: "coderhapsodie=!analytics=true!recaptcha=true!disqus=true!twitterembed=true!youtube=true; eZSESSID2d916c70663d96fd9785568f5b446851=4fscggud3eamn4flc3n4qd3gaj" }, ParamPair { name_length: Short(14), value_length: Short(0), name_data: "CONTENT_LENGTH", value_data: "" }, ParamPair { name_length: Short(12), value_length: Short(22), name_data: "HTTP_REFERER", value_data: "http://127.0.0.1:8000/" }, ParamPair { name_length: Short(9), value_length: Short(37), name_data: "PATH_INFO", value_data: "/content/download/71/file/video-2.mp4" }, ParamPair { name_length: Short(19), value_length: Short(11), name_data: "HTTP_SEC_FETCH_SITE", value_data: "same-origin" }, ParamPair { name_length: Short(11), value_length: Short(5), name_data: "REMOTE_PORT", value_data: "60000" }, ParamPair { name_length: Short(13), value_length: Short(42), name_data: "DOCUMENT_ROOT", value_data: "/home/me/dev/code-rhapsodie/www/web/" }, ParamPair { name_length: Short(11), value_length: Short(12), name_data: "SCRIPT_NAME", value_data: "/app_dev.php" }, ParamPair { name_length: Short(10), value_length: Short(8), name_data: "HTTP_RANGE", value_data: "bytes=0-" }, ParamPair { name_length: Short(11), value_length: Short(9), name_data: "REMOTE_ADDR", value_data: "127.0.0.1" }, ParamPair { name_length: Short(12), value_length: Short(37), name_data: "DOCUMENT_URI", value_data: "/content/download/71/file/video-2.mp4" }, ParamPair { name_length: Short(20), value_length: Short(35), name_data: "HTTP_ACCEPT_LANGUAGE", value_data: "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7" }, ParamPair { name_length: Short(15), value_length: Short(14), name_data: "SERVER_SOFTWARE", value_data: "Rymfony v0.1.0" }, ParamPair { name_length: Short(12), value_length: Short(0), name_data: "QUERY_STRING", value_data: "" }, ParamPair { name_length: Short(19), value_length: Short(7), name_data: "HTTP_SEC_FETCH_MODE", value_data: "no-cors" }, ParamPair { name_length: Short(15), value_length: Short(105), name_data: "HTTP_USER_AGENT", value_data: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" }, ParamPair { name_length: Short(9), value_length: Short(14), name_data: "HTTP_HOST", value_data: "127.0.0.1:8000" }, ParamPair { name_length: Short(11), value_length: Short(37), name_data: "REQUEST_URI", value_data: "/content/download/71/file/video-2.mp4" }, ParamPair { name_length: Short(15), value_length: Short(10), name_data: "HTTP_CONNECTION", value_data: "keep-alive" }, ParamPair { name_length: Short(14), value_length: Short(3), name_data: "REQUEST_METHOD", value_data: "GET" }, ParamPair { name_length: Short(20), value_length: Short(19), name_data: "HTTP_ACCEPT_ENCODING", value_data: "identity;q=1, *;q=0" }, ParamPair { name_length: Short(19), value_length: Short(5), name_data: "HTTP_SEC_FETCH_DEST", value_data: "video" }, ParamPair { name_length: Short(11), value_length: Short(4), name_data: "SERVER_PORT", value_data: "8000" }, ParamPair { name_length: Short(12), value_length: Short(0), name_data: "CONTENT_TYPE", value_data: "" }, ParamPair { name_length: Short(11), value_length: Short(14), name_data: "SERVER_NAME", value_data: "127.0.0.1:8000" }, ParamPair { name_length: Short(17), value_length: Short(11), name_data: "GATEWAY_INTERFACE", value_data: "FastCGI/1.0" }, ParamPair { name_length: Short(15), value_length: Short(53), name_data: "SCRIPT_FILENAME", value_data: "/home/me/dev/code-rhapsodie/www/web/app_dev.php" }, ParamPair { name_length: Short(15), value_length: Short(8), name_data: "SERVER_PROTOCOL", value_data: "HTTP/1.1" }]).
 2021-01-15T08:38:10.541Z DEBUG rymfony::http::fastcgi_handler > Normalized headers: "Content-Disposition: attachment; filename="video-2.mp4""

The error:

 error: Utf8Error { valid_up_to: 48, error_len: Some(1) } }', src/http/fastcgi_handler.rs:179:49

IMHO, all responses body from PHP needs always binary processing.

Issues with POST requests

I just detected a POST request issue: on Compotes, I can't even login, because making a POST request seems to reset the request somehow πŸ€”

I have investigated just a bit (this is what made me add the Host header in 3a3d3d3), but didn't make it so far.

[PHP] CGI server healthcheck

For now, if the CGI/FPM server crashes, Rymfony usually doesn't care, it'll just display an HTTP error (should be a 503, might need to check that).

If such thing happen, the server should be restarted right away with the exact same config as before.

For now I don't know how to implement this, but I'm thinking about two ways:

  • Hook into the command that's created in server_cgi.rs or server_fpm.rs, and if it stops, restart it (maybe the cleanest, IMO).
  • Use Tokio to create a background task that polls the server and restart it if there's no answer after a few seconds.

Duplicate entries when using `php:list`

Hello,

I've tried rymfony with the latest Ubuntu release.

PHP binary seems to be duplicated in the list:

image

Tested on Ubuntu 18.04

PHP binaries are installed through Brew for Linux.

Rymfony with PHP7.3 cli on Linux

OS: Linux Ubuntu 20.04.1 LTS
Rymfony: rymfony 0.1.0-ubuntu-829e2b47-nightly
PHP:

PHP 7.3.26-1+ubuntu20.04.1+deb.sury.org+1 (cli) (built: Jan 13 2021 08:01:31) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.26, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.26-1+ubuntu20.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with blackfire v1.48.1~linux-x64-non_zts73, https://blackfire.io, by Blackfire

Start Rymfony:

$ rymfony serve

Send request:

$ curl -ki https://127.0.0.1:8000/
HTTP/2 502 
content-type: text/html
date: Thu, 14 Jan 2021 07:33:14 GMT
content-length: 865


        <!DOCTYPE html>
        <html>
            <head>
                <meta charset="utf-8" />
                <title>Internal server error</title>
                <style>
                    body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
                    .container { margin: 30px; max-width: 600px; }
                    h1 { color: #dc3545; font-size: 24px; }
                    h2 { font-size: 18px; }
                </style>
            </head>
            <body>
                <div class="container">
                    <h1>Internal server error "502"</h1>
                    <h2>The server returned:</h2>
                    <pre>failed to fill whole buffer</pre>
                </div>
            </body>
        </html>

Result in Rymfony log :

 2021-01-14T07:29:42.425Z  INFO > GET /
[Thu Jan 14 08:29:42 2021] 127.0.0.1:45178 Invalid request (Malformed HTTP request)
 2021-01-14T07:29:42.426Z ERROR > FastCGI returned an error. It was displayed as a 502 to the end user.

Check if PHP Binary exist before launch

Step to reproduce:

  1. Install PHP FPM and cli
  2. Install Rymfony
  3. perform rymfony php:list --refresh
  4. uninstall PHP-FPM
  5. perform Β» RUST_BACKTRACE=1 RYMFONY_LOG=trace rymfony serve

Result:

Β» RUST_BACKTRACE=1 RYMFONY_LOG=trace rymfony serve --passthru app_dev.php                                                                                                                                    
 2021-01-15T07:58:38.266Z  INFO > Starting PHP...
 2021-01-15T07:58:38.266Z TRACE > File /home/me/.rymfony/php-versions.json found
 2021-01-15T07:58:38.269Z DEBUG > PHP version set to 7.3 from ".php-version" file.
 2021-01-15T07:58:38.269Z TRACE > User selected version 7.3.26
 2021-01-15T07:58:38.269Z  INFO > Using php-fpm
 2021-01-15T07:58:38.269Z DEBUG > Running getuid
 2021-01-15T07:58:38.269Z DEBUG > Running getgid
thread 'main' panicked at 'Could not start php-fpm.', src/php/server_fpm.rs:136:5
stack backtrace:
   0: std::panicking::begin_panic
   1: rymfony::php::php_server::start
   2: rymfony::commands::serve::serve_foreground
   3: rymfony::commands::serve::serve
   4: rymfony::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Suggested resolution:

Check if the PHP binary exist before launch. Exit with information to run the refresh PHP list command.

Handle root user

Hello,

I'm using Rymfony through Docker and I have two errors related to root user.

Sudo

sudo is required for certificate (not really a problem but sudo should not be required for root)

fpm-conf.ini

Server can't start because of fpm config. fpm-conf.ini should be updated on lines 17 and 18

user = www-data
group = www-data

Error:

rymfony server:start
 2021-03-23T16:38:21.937Z  INFO > Starting PHP...
 2021-03-23T16:38:21.986Z  INFO > Using php-fpm
 2021-03-23T16:38:21.987Z  INFO > Running php-fpm with PID 389
[23-Mar-2021 16:38:22] ALERT: [pool www] user has not been defined
[23-Mar-2021 16:38:22] ERROR: failed to post process the configuration
[23-Mar-2021 16:38:22] ERROR: FPM initialization failed
thread 'main' panicked at 'PHP server exited with exit code: 78', src/php/php_server.rs:69:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Forks cannot build with Github actions

With your updated CI setup, it is not possible to use the Github actions on forks due to the missing secrets.

I would propose to either split up CI.yaml into two files:

  • CI.yaml - runs on all branches * (which then can be used by forks / pull requests as well)
  • release.yaml (runs only on main and executes only the release steps)

Or minimum change: reorder steps, so the release steps will fail at the end.
That way contributors could still see the build output in Github action, example: https://github.com/kevinpapst/rymfony/actions/runs/379088085

I can work on a PR if you agree on one of the solutions.

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.