0

I just spun up a new vps with ubuntu 16.04, nginx 1.10.3 and php 7.0 and copied my working site to it. The old site was on php5.6 and worked flawlessly.

The issue is that something is converting my encoded plus signs into spaces. I can prove it is the real request is encoding the + as %2B by using document inspector but straight up curl test also fails:

Test 1:
curl "my_https_url" --data "details=asdf+%2B+asdf" --compressed
array(1) { ["details"]=> string(11) "asdf   asdf" } <-- 3 spaces

Test 2:
curl "my_https_url" --data-urlencoded "details=asdf+%2B+asdf" --compressed
array(1) { ["details"]=> string(11) "asdf + asdf" } <-- perfect

Test 3:
$.post("my_https_url",{details:"asdf + asdf"})
Document Inspector Encoded Form Data: details=asdf+%2B+asdf
array(1) { ["details"]=> string(11) "asdf   asdf" } <-- 3 spaces

Test 4:
$.post("my_https_url",{details:"asdf %2B asdf"})
Document Inspector Encoded Form Data: details=asdf+%252B+asdf
array(1) { ["details"]=> string(11) "asdf + asdf" } <-- perfect

Test 5:
$.post("my_https_url",{details:"asdf+%2B+asdf"})
Document Inspector Encoded Form Data: details=asdf%2B%252B%2Basdf
array(1) { ["details"]=> string(11) "asdf + asdf" } <-- perfect

Test 6:
$.post("my_https_url",{details:encodeURI("asdf + asdf")})
Document Inspector Encoded Form Data: details=asdf%2520%2B%2520asdf
array(1) { ["details"]=> string(11) "asdf   asdf" } <-- 3 spaces

Test 7:
$.post("my_https_url",{details:encodeURIComponent("asdf + asdf")})
Document Inspector Encoded Form Data: details=details=asdf%2520%252B%2520asdf
array(1) { ["details"]=> string(11) "asdf + asdf" } <-- perfect

Test 8:
$.post("my_https_url",$('<form><input name="details" value="asdf + asdf"></form>').serialize())
Document Inspector Encoded Form Data: details=details=details=asdf+%2B+asdf
array(1) { ["details"]=> string(11) "asdf   asdf" } <-- 3 spaces

Test 9:
$.post("my_https_url",encodeURIComponent($('<form><input name="details" value="asdf + asdf"></form>').serialize()))
Document Inspector Encoded Form Data: details%3Dasdf%2520%252B%2520asdf
array(0) {} <-- not working

<?php
var_dump($_POST);
// I am expecting "asdf + asdf"

Is there a php extension that is causing this or is it nginx? I included the configs of both.

phpinfo: https://ibb.co/jZCxeQ

nginx config:

server {
    listen 80;

#   access_log /var/log/nginx/website.access_log;
    error_log /var/log/nginx/website.error_log;
    set $oldhost $host;
    root PHP_FILES_LOCATION;
    location ~* \.(?:ico|css|js|gif|jpg|png|html|htm)$ {
        try_files $uri $uri/ /index.php;
        expires 3d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    location / {
        index index.php index.htm index.html;
        try_files $uri $uri/ /index.php;
    }

    location ~ json.php$ {
        try_files $uri $uri/ /index.php;
    #   location ~ \..*/.*\.php$ {return 404;}
        #    expires 3d; add_header Pragma public; add_header 
        #    Cache-Control "public";
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        #    fastcgi_index index.php;
        client_max_body_size 80m;
        fastcgi_intercept_errors on;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    location ~ .php$ {
        #location ~ \..*/.*\.php$ {return 404;}
        try_files $uri $uri/ /404.php?$args;
        #expires 1d;
        add_header Pragma public;
        client_max_body_size 80m;
        add_header Cache-Control "public";
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_intercept_errors on;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
Nick Schild
  • 129
  • 10
  • 3
    It's not clear if you _are_ aware of the meaning of `+` in encoded URLs? See https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20 if you are not. – alexis Sep 19 '17 at 18:02
  • Yes, a plus sign in a url can stand for a space. That is why I sent the url encoded version of a plus sign %2B, which should never be treated as a space. – Nick Schild Sep 19 '17 at 18:07
  • Have you tried `--data-urlencode "details=asdf asdf"` ? – John Baker Sep 19 '17 at 18:15
  • @johnBaker thank you for replying, but my curl example was just an example, stripped of any other factors that would cause it to not work correctly. I am really trying to push data from an ajax request. I am trying to get PHP to see the plus sign or %2B – Nick Schild Sep 19 '17 at 20:11
  • @johnBaker John, I took your advice (altered to match my question more) and used `--data-urlencode "details=asdf%2Basdf"` and it worked! The question now is how do I do this with ajax? I will update my question. – Nick Schild Sep 19 '17 at 20:19
  • Wrap your ajax request data in `encodeURI()`. Try `encodeURI('asdf + asdf')` – John Baker Sep 19 '17 at 20:33

2 Answers2

0

You need to encode special characters in your values before you submit the data. Wrap your values in encodeURIComponent.

$.post("my_https_url",{details:encodeURIComponent("asdf + asdf")})

John Baker
  • 425
  • 4
  • 22
  • @NickSchild I edited the post. It should be `encodeURIComponent` instead of `encodeURI` – John Baker Sep 19 '17 at 23:08
  • Code-only answers are discouraged because they do not explain how they resolve the issue in the question. Consider updating your answer to explain what this does and how it addresses the problem. Please review [How do I write a good answer](https://stackoverflow.com/help/how-to-answer) – FluffyKitten Sep 20 '17 at 00:07
  • @JohnBaker I think we are getting closer. You solved that specific issue. I updated my post with a new variation, closest to the actual code I am having an issue with. Check out tests 8 and 9. jQuery's serialize is suppose to encode the data, which it does according to Document Inspector. Which is why I still believe it is a nginx/php config issue. – Nick Schild Sep 20 '17 at 01:17
  • @JohnBaker please see tests 8 and 9 – Nick Schild Sep 20 '17 at 02:06
  • Is your test server publicly accessible? Can you upload an html file with the jquery post and php file with `var_dump($_POST)` in it? – John Baker Sep 20 '17 at 02:30
0

SOLVED: I forgot that I had a proxy server on the main domain. I created a subdomain for @johnBaker that bypassed the proxy server and it worked as it should. A simple fix to the proxy config and it works! Thank you everyone for participating in my wild goose chase.

Nick Schild
  • 129
  • 10