Page 1 of 1

Error on HTTP POST with RPI0 (Python) + PC (PHP)

Posted: Wed May 05, 2021 9:58 am
by treeTrunksPi
Hi!

I am using Raspberry Pi 0 and I want to pass data to the local PC/Server.
I want to use HTTP so that I would not show database name and password per rpi.
It is both for security and ease of use since if I have changes in database I only need to change the php code.

This is my php code:

Code: Select all

.config
<?php

  define("DB_SERVER", "localhost");
  define("DB_USERNAME", "root");
  define("DB_PASSWORD", "root");
  define("DB_DATABASE", "idiy");
  define("DB_CHARSET", "utf8mb4");
  define("DSN", "mysql:host=". DB_SERVER. ";dbname=". DB_DATABASE. ";charset=". DB_CHARSET);
	
  $opt = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
    //PDO::ATTR_PERSISTENT => true
  ];
	
  $PDO = new PDO(DSN, DB_USERNAME, DB_PASSWORD, $opt);

?>

temp.php
<?php
require("../.config");

echo $_POST["serial"];

if (isset($_POST["temperature"])) {
    $serial = $_POST["serial"];
    $temperature = $_POST["temperature"];
    
    $result = $PDO->prepare("UPDATE devices SET temperature=:xt WHERE serial='".$serial."'");
    $result->execute(["xt" => $temperature]);
    echo "success";   

    $result = NULL;
    $PDO = NULL;
    exit();
}
exit();

?>
This is my rpi code:

Code: Select all

import requests

url = 'http://192.168.1.4:80/temp_test/temp.php'
myobj = {'serial': 'wgse5fa', 'temperature': '25.0'}

r = requests.post(url, data = myobj)

print (r.text)
This is the error I get:

Code: Select all

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 159, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw)
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 80, in create_connection
    raise err
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 70, in create_connection
    sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 354, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.7/http/client.py", line 1260, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.7/http/client.py", line 1306, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.7/http/client.py", line 1255, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.7/http/client.py", line 1030, in _send_output
    self.send(msg)
  File "/usr/lib/python3.7/http/client.py", line 970, in send
    self.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 181, in connect
    conn = self._new_conn()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 168, in _new_conn
    self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0xb5fdeb30>: Failed to establish a new connection: [Errno 110] Connection timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 398, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.1.4', port=80): Max retries exceeded with url: /temp_test/temp.php (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb5fdeb30>: Failed to establish a new connection: [Errno 110] Connection timed out'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "temprh.py", line 6, in <module>
    r = requests.post(url, data = myobj)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 116, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.1.4', port=80): Max retries exceeded with url: /temp_test/temp.php (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb5fdeb30>: Failed to establish a new connection: [Errno 110] Connection timed out'))

I want to use POST because I want to hide the serial.
I have tried GET. The python does not work but if I type the url directly it works. (eg. http://192.168.1.4/temp_test/temp.php?s ... ature=20.0

Re: Error on HTTP POST with RPI0 (Python) + PC (PHP)

Posted: Wed May 05, 2021 1:23 pm
by neilgl
If I have this temp.php in temp_test on a pi running apache2 server, then run the python script fpost.py from another pi, it works. (no database in this test). Try it on your rig?

Code: Select all

<?php
if (isset($_POST["temperature"])) {
    echo "POST received ";
    $serial = $_POST["serial"];
    $temperature = $_POST["temperature"];
    echo "temp = "; echo $temperature;
    echo " ";
    echo "serial="; echo $serial;
    echo " now update database";
}
?>
The python script (same as yours with my ip address) fpost.py is:

Code: Select all

import requests
url = 'http://192.168.1.144:80/temp_test/temp.php'
myobj = {'serial': 'wgse5fa', 'temperature': '25.0'}
r = requests.post(url, data = myobj)
print (r.text)
Result is:

Code: Select all

pi@picam:~/scripts $ python3 fpost.py
POST received temp = 25.0 serial=wgse5fa now update database

Re: Error on HTTP POST with RPI0 (Python) + PC (PHP)

Posted: Thu May 06, 2021 1:55 am
by treeTrunksPi
Thank you so much for that!
You are right, it works on other pi RPI0(Python) + RPI4(PHP)

Code: Select all

pi@raspberrypi:~ $ sudo python3 reqtest.py
POST received temp = 25.0 serial=wgse5fa now update database
I just need to know why because I need to use a PC for the server for larger data storage.

Do you think this is because the PC uses Apache2.4? I searched and haven't found anything useful yet.
I'm also looking if the urllib3 is the problem but still no lead yet.

Re: Error on HTTP POST with RPI0 (Python) + PC (PHP)

Posted: Thu May 06, 2021 9:35 pm
by neilgl
Probably something to do with the Windows server. What server is it (WS2016, WS2012, Windows 10, WS2003 etc.) ?

Re: Error on HTTP POST with RPI0 (Python) + PC (PHP)

Posted: Wed May 12, 2021 2:59 am
by treeTrunksPi
Hi, sorry for the late reply.

I'm using Windows 10 MySQL Workbench 8.0 CE

Re: Error on HTTP POST with RPI0 (Python) + PC (PHP)

Posted: Wed May 12, 2021 10:58 am
by drtechno
I think in the required statement ; path separator should be \ instead of / on a Windows php server.
Also , the dB table character encoding is different (uft8mb4 vs utf8) from the default encoding from php as it supports only utf8 character set. I still don't see anywhere if uft8mb4 is officially support by php. Change your table character set to utf8 in mysql.
As well as php inputs should be filtered and with character encoding set check:

Code: Select all

$recieved=htmlentities($_POST ['serial'],ENT_XML1,"UTF-8");
Also, I would think the server response should be coded as json_encode instead of an http page that the python would have to parse.