Why I got laravel NotFoundHttpException? - php

I have successfully cloned a laravel from a git repo into a new folder, and I have successfully run database migrations& seeds.
I also deleted vendor folder, and run: $composer install --dev
Although my routes.php is simple:
<?php
Route::get('/', 'BlogController#getIndex');
I try to visit my page as:
http://localhost:8080/widgets-repository-contribution%20/public/
I get this error:
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException
I also tried to restart the server, but no luck ..
Any idea?
for full trace:
Server/Request Data
REDIRECT_OPENSSL_CONF C:\Bitnami\wampstack-5.4.37-0/apache2/conf/openssl.cnf
REDIRECT_PATH C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\jZip;C:\HaxeToolkit\haxe\;C:\HaxeToolkit\neko;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Bitnami\wampstack-5.4.37-0\php;C:\ProgramData\ComposerSetup\bin;;C:\Bitnami\wampstack-5.4.37-0/apache2/bin;
REDIRECT_STATUS 200
OPENSSL_CONF C:\Bitnami\wampstack-5.4.37-0/apache2/conf/openssl.cnf
PATH C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\jZip;C:\HaxeToolkit\haxe\;C:\HaxeToolkit\neko;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Bitnami\wampstack-5.4.37-0\php;C:\ProgramData\ComposerSetup\bin;;C:\Bitnami\wampstack-5.4.37-0/apache2/bin;
HTTP_HOST localhost:8080
HTTP_CONNECTION keep-alive
HTTP_CACHE_CONTROL max-age=0
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
HTTP_USER_AGENT Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
HTTP_ACCEPT_ENCODING gzip, deflate, sdch
HTTP_ACCEPT_LANGUAGE ar,en-US;q=0.8,en;q=0.6
HTTP_COOKIE laravel_session=eyJpdiI6Inp0ZnZOZDhIcFFKS2FBejZNeEthNlE9PSIsInZhbHVlIjoiVHlKUzI2bkFrZGhkS0lFRXdqMEMrUUNXRWNcL2JORnY5OVVmOHF1d0NrbXE4K21zMkVabFpNMXFyN0Vhb2U1ZXVMVmlDUUpHZUMzV0hYUzExUnVlVGVBPT0iLCJtYWMiOiI2YjMzZTlkMTNmNjhhNmVmNjY3NDYxYTEwZjYzNWNmNjY2N2RjYjE5NWEwODgzMzY1NTMzZjZjMjZkNzRmMTg5In0%3D
SystemRoot C:\Windows
COMSPEC C:\Windows\system32\cmd.exe
PATHEXT .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
WINDIR C:\Windows
SERVER_SIGNATURE
SERVER_SOFTWARE Apache
SERVER_NAME localhost
SERVER_ADDR ::1
SERVER_PORT 8080
REMOTE_ADDR ::1
DOCUMENT_ROOT C:/Bitnami/wampstack-5.4.37-0/apache2/htdocs
REQUEST_SCHEME http
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT C:/Bitnami/wampstack-5.4.37-0/apache2/htdocs
SERVER_ADMIN admin#example.com
SCRIPT_FILENAME C:/Bitnami/wampstack-5.4.37-0/apache2/htdocs/widgets-repository-contribution/public/index.php
REMOTE_PORT 57801
REDIRECT_URL /widgets-repository-contribution /public/
GATEWAY_INTERFACE CGI/1.1
SERVER_PROTOCOL HTTP/1.1
REQUEST_METHOD GET
QUERY_STRING
REQUEST_URI /widgets-repository-contribution%20/public/
SCRIPT_NAME /widgets-repository-contribution/public/index.php
PHP_SELF /widgets-repository-contribution/public/index.php
REQUEST_TIME_FLOAT 1427016178.277
REQUEST_TIME 1427016178

"public" is not part of the url and space (%20) in url is also strange. You must access http://localhost:8080/widgets-repository-contribution
php artisan route:list will show you all routes that have been correctly defined for doublechecking.

Related

How do I get PHP-FPM to work with nginx-proxy with FastCGI?

I am attempting to get nginx-proxy to work with the php-fpm variant of the official php image via fastcgi. Unfortunately, I seem to be unable to do so. I'm sure the problem is just something simple that I don't know about.
I have followed the instructions for nginx-proxy to the best of my ability and have boiled it down to a very simple way to re-create the issue. Here's my docker-compose.yml file:
version: "3"
services:
proxy:
image: jwilder/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- DEFAULT_HOST=test.local
fpm:
image: php:fpm
environment:
- VIRTUAL_HOST=test.local
- VIRTUAL_PROTO=fastcgi
I then drop in a simple index.php file by running:
docker container exec -it web_fpm_1 /bin/bash -c 'echo "<?php phpinfo(); ?>" > /var/www/html/index.php'
(It puts web_ in front because this project is in a directory named web/.)
I also modify my hosts file to point test.local to 127.0.0.1, so I can test it.
However, every attempt to browse to test.local results in a blank white page.
The logs for the web_proxy_1 container don't indicate anything out of the ordinary, as far as I know:
❯ docker container logs web_proxy_1
WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one
is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded.
forego | starting dockergen.1 on port 5000
forego | starting nginx.1 on port 5100
dockergen.1 | 2020/07/20 19:24:54 Generated '/etc/nginx/conf.d/default.conf' from 2 containers
dockergen.1 | 2020/07/20 19:24:54 Watching docker events
dockergen.1 | 2020/07/20 19:24:54 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload'
nginx.1 | test.local 172.18.0.1 - - [20/Jul/2020:19:25:12 +0000] "GET / HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
nginx.1 | test.local 172.18.0.1 - - [20/Jul/2020:19:25:13 +0000] "GET /favicon.ico HTTP/1.1" 200 5 "http://test.local/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
The logs for the web_fpm_1 container show that nothing gets sent except a 200 response:
❯ docker container logs web_fpm_1
[20-Jul-2020 19:24:54] NOTICE: fpm is running, pid 1
[20-Jul-2020 19:24:54] NOTICE: ready to handle connections
172.18.0.3 - 20/Jul/2020:19:25:12 +0000 "- " 200
172.18.0.3 - 20/Jul/2020:19:25:13 +0000 "- " 200
What am I doing wrong?
Incidentally, I have asked this question on the nginx-proxy repo, the nginx-proxy Google Group, and the php repo. I either get no response or they pass the buck.
The default generated config of nginx-proxy is not fully working.
I think something is messed up with VIRTUAL_ROOT environment variable, because the root of the problem is PHP getting a wrong path via SCRIPT_FILENAME (that's why you see no PHP output) and there is no try_files with =404 symbol (that's why you get 200 with everything).
I have a prepared working setup using docker-compose in GitHub to demonstrate that it would work with an existing SCRIPT_FILENAME in the nginx config.
I have changed test.local to test.localhost.
I think to get it working as it should, you would have to use an nginx template for nginx-proxy, so the generated default.conf does work with php fpm and have the missing fastcgi param included.
Another, yet different approach would be to pack PHP and a manually configured webserver (nginx) in a project and having the automated reverse nginx proxy in a standalone project.
This would cost you an additional process running but gives you more control and easier deployment.
Alternatively, you might want to have a look into traefik which does essentially the same as nginx-proxy.
Daniel's answer is definitely on the right track. I use the php-fpm image with nginx as my main stack for php sites. Having said that, I don't use the nginx-proxy docker image. Instead, I use plain nginx on the host machine, and configure ports to point to backend php-fpm docker images.
I'm not using docker-compose either. Since it's just docker containers running single sites, I don't need it. Here's an example docker run command:
docker rm -f www.example.com || true
docker run -itd -p 9001:9000 -P \
--name www.example.com \
--volume /var/www/html/www.example.com:/var/www/html/www.example.com \
--link mariadb:database.example.com \
--restart="always" \
--hostname="example.com" \
--log-opt max-size=2m \
--log-opt max-file=5 \
mck7/php-fpm:7.4.x-wordpress
And here is an example nginx config:
server {
server_name example.com www.example.com;
location ~ /.well-known {
allow all;
}
location ~ /\.ht {
deny all;
}
root /var/www/html/www.example.com/src;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
}
}
A few things about this setup are key. The port re-mapping for the docker container. In this example I map port 9001 to 9000. The other "gotcha" is that the root for the container must be an actual location on the host. I have no idea why this is the case, but for whatever reason the path docker thinks it's using has to actually be the path on the host as well.

Nginx multiple root depending on user agent

I have two applications one for mobile devices and other for other devices.
What I am trying to do is to show both application on the same domain instead of 2 different domain
I have google it but every one it showing url redirection.
Below is the code which, I have trying
server {
listen 80;
set $root /var/www/ng/webApplication;
if ($http_user_agent ~* "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos") {
set $root /var/www/html/mobileApplication;
}
root $root;
}
but nginx stop working if add this condition.
Edit
nginx -t result
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Edit
access.log
180.151.19.20 - - [02/Jul/2019:05:12:10 +0000] "GET / HTTP/1.1" 404 178 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
also in browser it shows 404 Not Found
Assuming both applications can respond independently. You can try to use the reverse proxy option. Here is an example.
proxy_pass http://localhost/webApplication;
if ($http_user_agent ~* "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos") {
proxy_pass http://localhost/mobileApplication;
}

Can nginx handle duplicate X-Forwarded-For headers?

When user using proxy (Google data saver etc), the browser adds X-Forwarded-For for clients' real ip address to server. Our load balancer passes all headers + the clients' ip address as X-Forwarded-For header to nginx server. The example request headers:
X-Forwarded-For: 1.2.3.4
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Host: *.*.*.*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,tr;q=0.6
Save-Data: on
Scheme: http
Via: 1.1 Chrome-Compression-Proxy
X-Forwarded-For: 1.2.3.5
Connection: Keep-alive
Is there any way to pass both of the X-Forwarded-For headers to php, respectively?
TL;DR
nginx: fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for
php: $_SERVER['HTTP_MERGED_X_FORWARDED_FOR']
Explanation
You can access all http headers with the $http_<header_name> variable. When using this variable, nginx will even do header merging for you so
CustomHeader: foo
CustomHeader: bar
Gets translated to the value:
foo, bar
Thus, all you need to do is pass this variable to php with fastcgi_param
fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for
Proof of concept:
in your nginx server block:
location ~ \.php$ {
fastcgi_pass unix:run/php/php5.6-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for;
include fastcgi_params;
}
test.php
<?php
die($_SERVER['HTTP_MERGED_X_FORWARDED_FOR']);
And finally see what happens with curl:
curl -v -H 'X-Forwarded-For: 127.0.0.1' -H 'X-Forwarded-For: 8.8.8.8' http://localhost/test.php
Gives the following response:
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /test.php HTTP/1.1
> Host: localhost
> User-Agent: curl/7.47.0
> X-Forwarded-For: 127.0.0.1
> X-Forwarded-For: 8.8.8.8
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Wed, 01 Nov 2017 09:07:51 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
127.0.0.1, 8.8.8.8
Boom! There you go, you have access to all X-FORWARDED-FOR headers, as a comma-delimited string in $_SERVER['HTTP_MERGED_X_FORWARDED_FOR']
Of course, you can use whatever name you want and not just HTTP_MERGED_X_FORWARDED_FOR.
You can get the original client address of the connecting ELB in the variable $realip_remote_addr, but be aware that this variable was only added in nginx 1.9.7, so you'll need to be running a very recent version of nginx.
For more info. ngx_http_realip_module variables
For example, with this config:
set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
And an X-Forwarded-For header resulting in:
X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1
By default, nginx will pick up the leftmost IP 123.123.123.123 as the client's IP address apart from trusted proxies.
But $realip_remote_addr keeps the original client address
What you are looking for needs to be handled at web server level. So I created two servers one using apache and one using nginx for this. The test command
curl -H "X: Y" -H "X: Z" http://localhost:8088/router.php | jq
Apache
When executed using apache the output is below
{
"HEADERS": {
"Host": "localhost:8088",
"User-Agent": "curl/7.47.0",
"Accept": "*/*",
"X": "Y, Z"
}
}
As you can see we passed two headers to apache and apache combined them using ,. If we change our first header to already contain , it would still work fine
$ curl -H "X: Y, A" -H "X: Z" http://localhost:8088/router.php | jq
{
"HEADERS": {
"Host": "localhost:8088",
"User-Agent": "curl/7.47.0",
"Accept": "*/*",
"X": "Y, A, Z"
}
}
Nginx
Now same request on nginx yields
{
"HEADERS": {
"X": "Z",
"Accept": "*/*",
"User-Agent": "curl/7.47.0",
"Host": "localhost"
}
}
Now it is not that Nginx is not sending those headers to PHP-FPM, it does send them as it is. PHP-FPM doesn't merge these duplicate headers into one. So in the script you only get the latest header.
Edit-1: Merge using fastcgi_param
Thanks to #AronCederholm for pointing out that merging does work by specifying FASTCGI_PARAM
I originally had tested the same approach but it had resulted in blank headers. I had tried adding
fastcgi_param X-Forwarded-For $http_x_forwarder_for;
Just now after reading his message I realized that I had a typo in my config. It should have been
fastcgi_param X-Forwarded-For $http_x_forwarded_for;
And after this change the header does work fine. It won't come in getallheaders() though. It would be available through $_SERVER[] as shown in below response
$ curl -v -H 'X-Forwarded-For: 127.0.0.1' -H 'X-Forwarded-For: 8.8.8.8' http://localhost/router.php | jq
{
"HEADERS": {
"X-Forwarded-For": "8.8.8.8",
"Accept": "*/*",
"User-Agent": "curl/7.47.0",
"Host": "localhost"
},
"SERVER": {
"USER": "vagrant",
"HOME": "/home/vagrant",
"HTTP_X_FORWARDED_FOR": "8.8.8.8",
"HTTP_ACCEPT": "*/*",
"HTTP_USER_AGENT": "curl/7.47.0",
"HTTP_HOST": "localhost",
"X-Forwarded-For": "127.0.0.1, 8.8.8.8",
Original Answer
Unfortunately I found no settings or plugins for Nginx or PHP-FPM which allows you to merge the duplicate headers into one. And you cannot handle this situation at PHP level, because you will never be able to see the raw headers.
Possible Solutions
Put apache in front of Nginx. Make nginx listen on a unix socket and use apache to reverse proxy the request to nginx
Replace Nginx by Apache
Create a Nginx plugin to merge headers. Below two projects should give you a head start
https://github.com/giom/nginx_accept_language_module
https://github.com/openresty/headers-more-nginx-module
The headers for X-Forwarded-For should be appended to by each proxy inline of your request. You should not be getting two headers. Because the values are appended to by design, anyone can add ip's to that list, so do not use it for security checks. If you need to check an ip for security, set the X-Real-IP header on your web server, overwriting any passed in value.

Can't access php files on local apache server

I have setup a local apache2 server, and it works and display correctly for any html files located at home/user/website, but it gives me an 404 error when i try to access php files.
i.e:
~/website ls
hello.php index.html test2.html test.php
127.0.1.1/index.html and 127.0.1.1/test2.html loads normally but 127.0.1.1/hello.php and 127.0.1.1/test.php gives me a 404
Theres no trace of error on the error.log file though there's a 404 GET on the access.log file:
127.0.0.1 - - [25/Sep/2014:00:35:01 -0300] "GET /hello.php HTTP/1.1" 404 273 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36"
I have this on the apache2.conf, not sure if it's correct:
<Directory /home/user/website>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
I configured apache2 to run with hhvm trough the scripts that comes with hhvm.
My system is ubuntu 14.04
Thanks.
I found this answer on: https://github.com/facebook/hhvm/issues/3472
I had to set hhvm.server.fix_path_info = true in /etc/hhvm/server.ini, now it works.

Basic PHP Web Analytics

I want to capture as much simple information on a web request with just PHP. What variables are available for me to store? Here's what I have so far:
https://gist.github.com/1363218
My wishlist for this function:
Turns language into an associative array ordered by weight
Add full name to language
Break server software into an associative array
Get the exact version of the platform, e.g., 'Windows 7 SP1' instead of just 'Windows'
Classify the request as being from a mobile device, a tablet, or a desktop
Am I missing anything else that could be useful?
Every information available to you are in variables, so an easy way to find the stuff you want is to have a look at $GLOBALS. Create a new PHP file and do print_r($GLOBALS);, and you'll see every information your script has gathered.
This includes everything from http headers (charset, encoding, language) to cookies, browser and operating system.
Take what you need: http://php.net/manual/en/reserved.variables.php
PHP_SELF /blog/article.php
GATEWAY_INTERFACE CGI/1.1
SERVER_ADDR Server IP: 217.112.82.20
SERVER_NAME www.URL.co.uk
SERVER_SOFTWARE Apache/2.2.15 (Win32) JRun/4.0 PHP/5.2.13
SERVER_PROTOCOL HTTP/1.0
REQUEST_METHOD GET / POST / PUT / HEAD
REQUEST_TIME Request start time: 1280149029
QUERY_STRING id=10&user=foo
DOCUMENT_ROOT /path/to/your/server/root/
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9
HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_ACCEPT_ENCODING gzip,deflate
HTTP_ACCEPT_LANGUAGE en-gb,en;q=0.5
HTTP_CONNECTION keep-alive
HTTP_HOST www.URL.co.uk
HTTP_REFFERER http://previous.url.com
HTTP_USER_AGENT Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)
HTTPS 1
REMOTE_ADDR 193.60.128.69
REMOTE_HOST Client server's host name
REMOTE_PORT 5390
SCRIPT_FILENAME /path/to/this/script.php
SERVER_ADMIN webmaster#URL.co.uk
SERVER_PORT 80
SERVER_SIGNATURE Version signature: 5.123
SCRIPT_NAME /blog/article.php
REQUEST_URI /blog/article.php
$_SERVER['HTTP_USER_AGENT'].
This can you about user's operating system, as well as their browser.
For example
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en)

Categories