php tcp socket listener data parse - php

I have gps tracker which is sending data to my server over tcp and my server has been coded in PHP. the device is sending data in every 5 seconds. The issue is that the first response comes fine as soon as socket established connection with the client but then subsequent responses comes in weird characters and no idea of how to interpret them.
Server.php code
SocketServer.class.php
<?php
require_once("SocketServer.class.php");
$server = new SocketServer("172.xx.xx.xxx",8000);
$server->max_clients = 10;
$server->hook("CONNECT","handle_connect"); // Run handle_connect every time someone connects
$server->hook("INPUT","handle_input");
$server->infinite_loop();
function handle_connect(&$server,&$client,$input) {
SocketServer::socket_write_smart($client->socket,"String? ","");
}
function handle_input(&$server,&$client,$input) {
$trim = trim($input);
if(strtolower($trim) == "quit")
{
SocketServer::socket_write_smart($client->socket,"Oh... Goodbye...");
$server->disconnect($client->server_clients_index); // Disconnect this client.
return;
}
$output = strrev($trim);
SocketServer::socket_write_smart($client->socket,$output);
SocketServer::socket_write_smart($client->socket,"String? ","");
}
Output:
Triggering Hook 'handle_connect' for 'CONNECT'
*HQ,9176952312,V6,115939,V,3127.2665,N,07307.6974,E,0.00,126.00,100822,FFF7FBFF,410,1,325,14688,8992300001243970980F,#
Triggering Hook 'handle_input' for 'INPUT'
0#119.160.59.240 --> $?v?#uY"1'&e0v?
&????ʧ?E9`,
Triggering Hook 'handle_input' for 'INPUT'
0#119.160.59.240 --> $?v?#uY"1'&e0v?
&????ʧ?E9`,
hex dump if data comes correctly
<Buffer 2a 48 51 2c 39 31 37 36 39 35 32 33 37 35 2c 56 36 2c 31 35 35 37 32 32 2c 56 2c 33 31 32 37 2e 33 30 33 34 2c 4e 2c 37 33 30 37 2e 36 36 33 36 2c 45 ... 65 more bytes>
Hex dump incorrect response
24 91 76 95 23 75 15 57 24 10 08 22 31 27 30 34 04 07 30 76 63 0c 00 00 00 ff f7 fb ff 00 01 c7 f0 00 00 00 00 01 9a 01 01 45 7f 2d 00

Related

AWS S3 Bucket Presigned URL

I am trying to create Presigned URLs for users to access content from an S3 bucket.
The below code was working fine and all of a sudden I am getting the below error when opening any pre-signed URL that is created.
public function getPresignedUri($p)
{
$s3 = new S3Client([
'region' => getenv('S3_REGION'),
'version' => 'latest',
]);
$cmd = $s3->getCommand('GetObject', [
'Bucket' => getenv('S3_BUCKET'),
'Key' => 'casts/'. $p['file']
]);
$request = $s3->createPresignedRequest($cmd, '+1 hour');
return (string) $request->getUri();
}
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>ASIA3DM6Y5GJC4FYJAFC</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256
20180821T072223Z
20180821/ap-southeast-2/s3/aws4_request
fc4f1139d3b146ae027bd0bfc0b3d6dacda81d711b062e0d93a65d04a61aa268</StringToSign><SignatureProvided>5f5d3ae9ef3d9cdfc0d039c39302c584dcfc93f5a94a0f1770bf6781d6958198</SignatureProvided><StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 31 38 30 38 32 31 54 30 37 32 32 32 33 5a 0a 32 30 31 38 30 38 32 31 2f 61 70 2d 73 6f 75 74 68 65 61 73 74 2d 32 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 66 63 34 66 31 31 33 39 64 33 62 31 34 36 61 65 30 32 37 62 64 30 62 66 63 30 62 33 64 36 64 61 63 64 61 38 31 64 37 31 31 62 30 36 32 65 30 64 39 33 61 36 35 64 30 34 61 36 31 61 61 32 36 38</StringToSignBytes><CanonicalRequest>GET
/casts/5B735D22BCB17.mp4
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=ASIA3DM6Y5GJC4FYJAFC%2F20180821%2Fap-southeast-2%2Fs3%2Faws4_request&X-Amz-Date=20180821T072223Z&X-Amz-Expires=3600&X-Amz-Security-Token=FQoGZXIvYXdzEPn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDEMaw7h8OwK6f6QN0SLBA4%2B9LzXs7OMNjW7HDqr1jhuK%2FshbOMDBoF00GHqTWUuJWXQuL4ptYpvWRjwpris0USWPMTx0O3WeKacvtw6oN2M1KRoUe3IcNOpFwaixKw8%2Fo5FKXK%2BSCo%2F7U%2B76V4aEFuuWEZkC5qhm9R7ChB7vDNTlmYXx2GOzL2uZYV8dZrAnrUfU5qWpyI4IQb8DvPnpDWB0OgA2SRvuGzkwkVLEtMmHS2SMU32gwX2Oy6YnMswWZeqVQ%2FovfWbxd5AA4O%2BFNQfcNM5l4jsuR2zV8FiKZ3jQRLgfQx5uvydv6FFzb90SDbvUjZd0aAsR1Mre%2FnoQodezAm0xoA5618%2FWd%2BIh3jouN2RflRM3II8UXCWzFFq2NL%2FxweJu2mYXfKNpTkqOEls5dFMo2OWQa3IGXJqT3EZEZKXcQ3z%2F2aOP%2Fyw%2F2GtPdQrdJziwN4lTXyl6%2FGZYd968yjlU6pIk6vB0NVq9q3wKjBiwlsfGTlaJnFJH7DD%2FIY4U6fYOmvAcGnoozAbIcqDZpDPNrvZX75tzSatHHLyQoF56STZPhWK7cCWEo2JWAzg6NE4xBmypFG%2Bkxtv0QtrcUNYD35FvFGbjheUhMnyOKOTz7tsF&X-Amz-SignedHeaders=host
host:app-assets-dev-ap-southeast-2-cmpny.s3.ap-southeast-2.amazonaws.com
host
UNSIGNED-PAYLOAD</CanonicalRequest>
AWS SDK verison aws/aws-sdk-php (3.65.0)
One small difference I can see in the URL is that when it was working it had
X-Amz-SignedHeaders=host
and now it has
X-Amz-SignedHeaders=host%3Bx-amz-security-token
Although not sure what could be causing that extra string??
EDIT 1:
I identified that this issue was due to the SDK version 3.65 ... when I rolled back to 3.31 there was no issue.
However I am not marking this as resolved as I would like to know why a small version change like this made such a big difference and error?
I can see there is major differences in the src/Signature/SignatureS4.php file specifically:
$parsed['query']['X-Amz-SignedHeaders'] = 'host'; (V3.31)
and
$parsed['query']['X-Amz-SignedHeaders'] = implode(';', $this->getPresignHeaders($parsed['headers'])); (V3.65)
however that line alone didn't fix - replacing the whole file did fix the error.
I logged this issue on Github - https://github.com/aws/aws-sdk-php/issues/1609
And it was tested, confirmed and resolved very quickly - https://github.com/aws/aws-sdk-php/pull/1610
This is resolved.

PHP shell_exec inserts CR character in CURL command, leading to server error 500

I use the following test program to retrieve a website's content:
<?php
function getData( $url, $output ) {
// set the path for CURL
if (file_exists( '/var/lib'))
$curl = 'curl';
else
$curl = 'curl.exe';
$curl .= ' --trace trace.txt --header "User-Agent: Some-Agent/1.0" ';
echo "\nreading $url...\n";
$buffer = shell_exec( "$curl -i \"$url\"" );
// if this is a 301 redirection URL, follow it one step
if ((preg_match( '~^HTTP.+? 301 ~', $buffer )) and preg_match( '~Location: (.+)~', $buffer, $location )) {
$cmd = "$curl -i \"$location[1]\"";
echo "$cmd\n";
$buffer = shell_exec( $cmd );
}
file_put_contents( $output, $buffer );
}
// test with a URL that will be redirected:
getData( "http://www.onvista.de/aktien/fundamental/EISEN-UND-HUETTENWERKE-AG-Aktie-DE0006055007", "DE0006055007-AG.html" );
On my windows machine, this code runs fine. On a linux machine it returns a 500 internal server error.
This is the start of the trace file trace.txt:
== Info: About to connect() to www.onvista.de port 80 (#0)<br>
== Info: Trying 217.11.205.10... == Info: connected<br>
== Info: Connected to www.onvista.de (217.11.205.10) port 80 (#0)<br>
=> Send header, 130 bytes (0x82)<br>
0000: 47 45 54 20 2f 61 6b 74 69 65 6e 2f 66 75 6e 64 GET /aktien/fund<br>
0010: 61 6d 65 6e 74 61 6c 2f 31 53 54 2d 52 45 44 2d amental/1ST-RED-<br>
0020: 41 47 2d 41 6b 74 69 65 2d 44 45 30 30 30 36 30 AG-Aktie-DE00060<br>
0030: 35 35 30 30 37 0d 20 48 54 54 50 2f 31 2e 31 0d 55007. HTTP/1.1.<br>
0040: 0a 48 6f 73 74 3a 20 77 77 77 2e 6f 6e 76 69 73 .Host: www.onvis<br>
0050: 74 61 2e 64 65 0d 0a 41 63 63 65 70 74 3a 20 2a ta.de..Accept: *<br>
0060: 2f 2a 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 /*..User-Agent: <br>
0070: 53 6f 6d 65 2d 41 67 65 6e 74 2f 31 2e 30 0d 0a Some-Agent/1.0..<br>
0080: 0d 0a ..<br>
<= Recv header, 36 bytes (0x24)<br>
0000: 48 54 54 50 2f 31 2e 31 20 35 30 30 20 49 6e 74 HTTP/1.1 500 Int<br>
0010: 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 ernal Server Err<br>
0020: 6f 72 0d 0a <br>
The only difference between the windows trace and this one is a CR character after the filename (ending in DE0006055007. How did get there and how can I suppress it? (And no, I don't want to use the PHP cURL module which leads to other problems.)
The http headers you get end with \r\n, as should. It seems curl on linux converts them to \n if it detects the output is tty, but try to redirect to a file and you'll see the \rs in there.
. in preg_match matches also \r character, so it becomes part of $location[1]. Simple solution is to trim it.
This doesn't happen on windows only because you can execute curl -i "http://google.com. The quotation is ended by the shell automaticaly after newline.
And you should really use escapeshellarg.

Return hexidecimal differences in binary files with PHP

I've read and tried every answer here, yet they seem to only apply to strings in non-binary formats. I'm trying to compare differences in binary files and return those in format such as this:
[file1]
-0001010: ac 0f 00 00 01 00 00 00 48 65 6c 6c 6f 2c 20 77 ........Hello, w
[file2]
+0001010: ac 0f 00 00 01 00 00 00 48 75 6c 6c 6f 2c 20 77 ........Hullo, w
xdiff works fine for creating bdiff patches and patching file - I'm looking too illustrate the differences.
$one = 'one'; // original file
$two = 'two'; // updated file
$pat = 'dif'; // bdiff patch
$new = 'new'; // new destfile
xdiff_file_diff_binary($one, $two, $pat);
xdiff_file_patch_binary($one, $pat, $new);
$diff = xdiff_file_diff($one, $two, 1);
if (is_file($diff)) {
echo "Differences:\n"; // result = 1
echo $diff;
}
Maybe xdiff isn't the right extension to be using for this? I'm not sure.
Sound like a big pain in the butt to do in PHP, might I suggest the following bash one-liner?
diff <(hexdump -C file1) <(hexdump -C file2)
Output:
10c10
< 00000090 35 35 61 34 32 62 62 31 30 33 31 62 38 38 39 34 |55a42bb1031b8894|
---
> 00000090 35 35 61 34 32 62 62 31 30 33 31 61 38 38 39 34 |55a42bb1031a8894|
And you can always mess with the options for diff and hexdump.

file_get_contents($url) returning extra data with some servers

I made a simple script to isolate my problem :
<?php
$url = "http://www.sitlor.fr/photos/754/754000273_4.jpg";
file_put_contents("test.jpg", file_get_contents($url));
?>
In this case and with this file in particular, file_get_contents() add extra bytes in the beggining of the file.
When $url is an url to an other image, it does work normally.
Some $url causing trouble :
$url = "http://www.sitlor.fr/photos/754/754000273_4.jpg";
$url = "http://www.sitlor.fr/photos/754/754005986_4.jpg";
$url = "http://www.sitlor.fr/photos/754/754002719_4.jpg";
If I use a curl script, it works well :
function curly($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
file_put_contents("test.jpg", curly("http://www.sitlor.fr/photos/754/754000273_4.jpg"));
But I can't : I need getimagesize() too and it returns false when I use it on the problematics files.
I also noticed that the problem occurs only on my remote server. When I try theses scripts locally, it works fine.
Edit:
I added the IIS tag because I can see they are using a IIS Server from the response HTTP header :
Server :"Microsoft-IIS/6.0"
X-Powered-By :"ASP.NET"
X-AspNet-Version :"4.0.30319"
Edit 2:
Here is the binary difference (vbindiff output) of the files.
It seems that the extra parts is 33 32 34 0D 0A (I have no idea what it means) :
/tmp/original.jpg
0000 0000: FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 01 2C ......JF IF.....,
0000 0010: 01 2C 00 00 FF E1 03 BA 45 78 69 66 00 00 49 49 .,...... Exif..II
0000 0020: 2A 00 08 00 00 00 0B 00 0E 01 02 00 3B 00 00 00 *....... ....;...
/tmp/extra-bytes.jpg
0000 0000: 33 32 34 0D 0A FF D8 FF E0 00 10 4A 46 49 46 00 324..... ...JFIF.
0000 0010: 01 01 01 01 2C 01 2C 00 00 FF E1 03 BA 45 78 69 ....,.,. .....Exi
0000 0020: 66 00 00 49 49 2A 00 08 00 00 00 0B 00 0E 01 02 f..II*.. ........

windows 7, php 5.3, when fetching binary data with sqlsrv from mssql the data is doubled

ok, so I have images on a MSSQL 2005 (express) server which I want to write to files.
with the same piece of code, on linux it works fine, on windows it writes the data twice in the file
file_put_contents($file, $val);
$val = basename($file);
I know it is not a file_put_contents() problem because I also tried with fwrite
the output file in windows has double the size it has in linux
-rw-rw-r-- 1 dimitris dimitris 891768 2011-11-22 16:13 eshop_products__2201.jpg
-rw-rw-r-- 1 dimitris dimitris 445884 2011-11-21 19:15 eshop_products__2201_linux.jpg
I am using the freetds driver for linux and php_pdo_sqlsrv_53_nts_vc9 in windows
any ideas on something I could do to get the correct data in windows? maybe some configuration I missed?
topmost bytes of each file:
windows file:
ASCII (php substr):
FFD8FFE000104A46494600010100000100010000FFDB0043000302020302020303030304030304050805050404050A070706080C0...etc...
hex:
00000000: 46 46 44 38 46 46 45 30 30 30 31 30 34 41 34 36 FFD8FFE000104A46
00000010: 34 39 34 36 30 30 30 31 30 31 30 30 30 30 30 31 4946000101000001
00000020: 30 30 30 31 30 30 30 30 46 46 44 42 30 30 34 33 00010000FFDB0043
00000030: 30 30 30 33 30 32 30 32 30 33 30 32 30 32 30 33 0003020203020203
00000040: 30 33 30 33 30 33 30 34 30 33 30 33 30 34 30 35 0303030403030405
00000050: 30 38 30 35 30 35 30 34 30 34 30 35 30 41 30 37 0805050404050A07
00000060: 30 37 30 36 30 38 30 43 30 41 30 43 30 43 30 42 0706080C0A0C0C0B
linux file:
ASCII (php substr):
����JFIF��C
hex:
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03 .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07 ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d ................
00000040: 0e 11 0e 0b 0b 10 16 10 11 13 14 15 15 15 0c 0f ................
00000050: 17 18 16 14 18 12 14 15 14 ff db 00 43 01 03 04 ............C...
00000060: 04 05 04 05 09 05 05 09 14 0d 0b 0d 14 14 14 14 ................
00000070: 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 ................
The code extracting the file from the database is base on the yii framework, using yii's commands feature (php cli)
Connection strings:
linux
'connectionString' => 'dblib:host=192.168.56.101;port=1433;dbname=mssqldb',
windows
'connectionString' => 'sqlsrv:Server=192.168.56.101;Database=mssqldb',
Code:
$rows = $this->db->createCommand("SELECT * FROM $viewName WHERE 1=1")->queryAll();
/*
* Convert charset and extract photos from view
*/
foreach ($rows as $row) {
// convert charset / export photos
foreach ($row as $key => &$val) {
// charset conversion, on fields that do not contain photos
// $viewCfg is an array I maintain to know which field does what
if (empty($viewCfg['photos']) || !in_array($key, $viewCfg['photos'])) {
$val = #iconv("Windows-1253", "UTF-8", $val);
// grab image in file
} else {
$id = '';
foreach ($viewCfg['keys'] as $fieldName) {
$id .= '_' . $row[$fieldName];
}
$file = Yii::app()->params['pathPhotos'] . '/' . $viewName . '_' . $id . '.jpg';
if ($val) {
if (file_exists($file) && (file_get_contents($file)!=$val))
unlink($file);
file_put_contents($file, $val);
$val = basename($file);
}
}
}
// ... do the rest
Good to hear you found some solution, if not a nice one : /
I had that situation while testing Mssql on a PHP app but never got any further. Another hint you may check is the PHP doc on PDO Large Objects (like varbinary and image SQL Datatypes): http://de2.php.net/manual/en/pdo.lobs.php
Maybe the result is consistent when you read the image as a stream?

Categories