Trying to get data from IOT using PHP - php

I'm trying to get JSON from my IOT application. I can post data to my IOT application so my connection is ok but cant get a response. I only get a not allowed error.
I use this code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$endpoint_url);
$result = curl_exec($ch);
if ($result === FALSE) {
printf("cUrl error (#%d): %s<br>\n", curl_errno($ch),
htmlspecialchars(curl_error($ch)));
}
curl_close($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
But all I get back is the following:
Verbose information:
* Hostname integrations.thethingsnetwork.org was found in DNS cache
* Trying 13.69.184.129...
* Connected to integrations.thethingsnetwork.org (13.69.184.129) port 443
(#0)
* ALPN, offering http/1.1
* Cipher selection:
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=integrations.thethingsnetwork.org
* start date: Jan 31 12:04:08 2019 GMT
* expire date: May 1 12:04:08 2019 GMT
* subjectAltName: integrations.thethingsnetwork.org matched
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> GET /ttn-eu/api/v2/down/secret/test?key=secret HTTP/1.1
Host: integrations.thethingsnetwork.org
Accept: */*
< HTTP/1.1 405 Method Not Allowed
< Server: nginx/1.13.7
< Date: Wed, 20 Mar 2019 15:33:10 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 0
< Connection: keep-alive
<
* Connection #0 to host integrations.thethingsnetwork.org left intact
How can I get the data?

You are not specifying the Request type in your curl request which automatically defaults it to a GET one. Add the following to your code.
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

Related

PHP_curl loose content-length on redirect

I'm trying to make a request to payment processing page. This requires authorization, which takes place through a set of redirects. In the second step, I get "411 Length Required" error, which means that content-length was lost along the way. Indeed, I cannot see it in the log. What can be done here? Change tool (programming language)?
CURLOPT_VERBOSE:
* Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.dev.example.com
* start date: Apr 27 00:00:00 2019 GMT
* expire date: Apr 26 23:59:59 2021 GMT
* subjectAltName: host "api.dev.example.com" matched cert's "*.dev.example.com"
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
* SSL certificate verify ok.
> POST /p2p/v2/payer HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Content-Length: 224
* upload completely sent off: 224 out of 224 bytes
< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 213
< Connection: keep-alive
< Keep-Alive: timeout=20
< Cache-Control: private
< Location: /api/payer/auth?sessionToken=e744a95992fa405ba10662bbc6908d6bedd48a73cc0d45d589f4ef2f7d7a0b88
< Set-Cookie: returnUrl=http://example.com/returnurl.php; path=/
<
* Ignoring the response-body
* Connection #0 to host api.dev.walletone.com left intact
* Issue another request to this URL: 'https://api.dev.example.com/auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88'
* Switch from POST to GET
* Found bundle for host api.dev.example.com: 0x5649fd243480 [can pipeline]
* Re-using existing connection! (#0) with host api.dev.example.com
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
> POST /auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88 HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
< HTTP/1.1 411 Length Required
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=us-ascii
< Content-Length: 344
< Connection: keep-alive
< Keep-Alive: timeout=20
<
* Connection #0 to host api.dev.example.com left intact
My code is:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $path);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
"Content-Type: application/x-www-form-urlencoded",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method);
curl_setopt($ch, CURLOPT_POSTFIELDS, $order_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$response = curl_exec($ch);
curl_close($ch);
Set the content-length in the header, which would be set to the string length strlen() of $order_data
curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
"Content-Type: application/x-www-form-urlencoded",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Content-Length: ". strlen($order_data)
));
you can also debug this by checking out curl_setopt($ch, CURLINFO_HEADER_OUT, true); which makes curl_getinfo() include the request's headers in its output.
The problem was in using curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method). Curl tryed to swithc to GET, like mostly browsers do, but cannot. Use curl_setopt($ch, CURLOPT_POST, 1); indeed.

How to decode binary response from PHP curl

curl -vvvv -k -s -X POST --header 'Content-type: text/xml;charset="utf-8"' --header 'SOAPAction: vend' -u 'USER':'PIN' -d "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header/><soapenv:Body><vend xmlns=\"http://host.vim.services.co.uk/xsd\"><sequence>6922343</sequence><origMsisdn>xxxxxxxxxxxxx </origMsisdn><destMsisdn>xxxxxxxxxxxxx</destMsisdn><amount>1000</amount><tariffTypeId>1</tariffTypeId></vend></soapenv:Body></soapenv:Envelope>" https://xxx.xxx.x.xxx:443/modlue/services/TargetOne ; echo;
The curl request above gets me this response below (in terminal)
* Trying xxx.xxx.x.xxx...
* TCP_NODELAY set
* Connected to xxx.xxx.x.xxx (xxx.xxx.x.xxx) port 443 (#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.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=*.xxx.xxxxxxe.com
* start date: Sep 10 00:00:00 2018 GMT
* expire date: Nov 28 12:00:00 2020 GMT
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=RapidSSL RSA CA 2018
* SSL certificate verify ok.
* Server auth using Basic with user 'username'
> POST /axis2/services/HostIFService HTTP/1.1
> Host: xxx.xxx.x.xxx
> Authorization: Basic V4mp00vKL2wb3LL6Z2hZZSIzI2RzCL2kbNPlQjExMQ==
> User-Agent: curl/7.58.0
> Accept: */*
> Content-type: text/xml;charset="utf-8"
> SOAPAction: vend
> Content-Length: 409
>
* upload completely sent off: 409 out of 409 bytes
< HTTP/1.1 200
< Content-Type: text/xml;charset=UTF-8
< Content-Length: 568
< Date: Wed, 15 Jan 2020 14:24:53 GMT
< Vary: Accept-Encoding
<
* Connection #0 to host xxx.xxx.x.xxx left intact
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><xsd:vendResponse xmlns:xsd="http://xxxxxx.xxx.xxxxx.xx.xx/xxx"><xsd:sequence>0000000001</xsd:sequence><xsd:statusId>301</xsd:statusId><xsd:txRefId>2020011515245375604706230</xsd:txRefId><xsd:origBalance>0.00</xsd:origBalance><xsd:origMsisdn>12345678910112 </xsd:origMsisdn><xsd:destMsisdn>12345678910112</xsd:destMsisdn><xsd:responseCode>0</xsd:responseCode><xsd:responseMessage>Insufficient Airtime</xsd:responseMessage></xsd:vendResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
But with PHP curl it outputs only
string(792) "00000000031060.002347064058107 23480320303031Sequence Number Check Failed2020012312555188502475422FAILED8076922343" with header informtion `"HTTP/1.1 200 Content-Type: text/xml;charset=UTF-8 Content-Length: 656 Date: Thu, 23 Jan 2020 12:20:02 GMT Vary: Accept-Encoding"`
How can I get the remaining contents and read the corresponding values from the xml response?
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><xsd:vendResponse xmlns:xsd="http://xxxxxx.xxx.xxxxx.xx.xx/xxx"><xsd:sequence>0000000001</xsd:sequence><xsd:statusId>301</xsd:statusId><xsd:txRefId>2020011515245375604706230</xsd:txRefId><xsd:origBalance>0.00</xsd:origBalance><xsd:origMsisdn>12345678910112 </xsd:origMsisdn><xsd:destMsisdn>12345678910112</xsd:destMsisdn><xsd:responseCode>0</xsd:responseCode><xsd:responseMessage>Insufficient Airtime</xsd:responseMessage></xsd:vendResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
EDIT
This is my php code I use to send the request. But i want to be able to get the response as XML and then extract the contents of the XML like txrefid and response and message.
$request = "<xml>Request</xml>";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://xxx.xxx.xxx.xxx:443/request");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: text/xml',
'charset: utf-8',
'action: action',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_ENCODING,'');
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
$server_output = curl_exec($ch);
$error = curl_error($ch);
$errno = curl_errno($ch);
if (0 !== $errno) {
throw new \RuntimeException($error, $errno);
}
else{
var_dump($server_output);
}
curl_close ($ch);
Try sending the same headers used in curl from the terminal:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: text/xml;charset="utf-8"',
'SOAPAction: vend'
));

Curl is working however error with php CURL

We want to communicate to the 3rd party API for which we are using curl from linux terminal. The curl is -
curl -X POST \
\
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json'
When we fire this curl then we are getting expected response.
However, when we try to do this from PHP script then we are getting error as -
HTTP ERROR 500
PHP Code snippet is -
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, <URL>);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
//curl_setopt($ch, CURLOPT_POSTFIELDS,'');
curl_setopt($ch, CURLOPT_VERBOSE,true);
$headers = array();
$headers[] = 'Authorization: Bearer <token>';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
echo $result;
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
?>
When verbose mode is on then response received is -
* Trying <IP>...
* Connected to <URL> (<IP>) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: OU=Domain Control Validated; CN=* <domain>
* start date: Dec 17 10:41:01 2017 GMT
* expire date: Dec 17 10:41:01 2020 GMT
* subjectAltName: <URL> matched
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify ok.
> POST /app/auth HTTP/1.1
Host: <URL>
Accept: */*
Authorization: Bearer <Token>
Content-Type: application/json
Expect: 100-continue
< HTTP/1.1 500 Request failed.
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Type: text/html;charset=iso-8859-1
< Date: Wed, 08 Jan 2020 04:39:23 GMT
< Content-Length: 252
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
* Closing connection 0
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 500 Request failed.</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /app/auth. Reason:
<pre> Request failed.</pre></p>
</body>
</html>
Please note that Ihave replaced actual URL,IP and token while posting the question here.
To make sure that there are no issues with the PHP curl we used curl-to-PHP code generator utility to generate code ( http://incarnate.github.io/curl-to-php/).
Can someone please help me and let me know what might be going wrong.
To avoid «500 error» (for example) be sure to:
set proper "Referer: " header if needed, with
curl_setopt(CURLOPT_REFERER, 'ref page');
set proper "User-Agent: " header, with
curl_setopt(CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');

Invalid client error with curl POST request

I'm having troubles trying to get an access token from an oauth endpoint.
I'm making a curl POST request in the following way
$username = 'Joe';
$password = 'Doe##!'
$auth = 'Basic Y245Y3BleGF4aTp2ZWludGZxMmVwbGd5anU1Y2N6aGZtNmZ3OXdlNmJ=';
$headers = [
'Authorization' => $auth,
'Content-Type' => 'application/x-www-form-urlencoded',
];
$form_params = [
'username' => $username,
'password' => $password,
'grant_type' => 'password',
'scope' => 'auto'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://oauth.wildapricot.org/auth/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($form_params));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
but I keep getting a invalid client error (the $auth variable consists in the client and secret encoded with base 64).
I've tried encoding the postfields but didn't help. I've hardcoded the $auth variable just in case the base64_encode function was messing it up (I generated it with that function before), but it didn't change anything.
I've checked that the endpoint was actually working with Postman and it actually is.
Any ideas on what could be the issue?
Edit: I've just added some debugging lines into the code and this is what I got (if that's of any help)
* Trying 34.226.77.200:443...
* TCP_NODELAY set
* Connected to oauth.wildapricot.org (34.226.77.200) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/local/etc/openssl/cert.pem
CApath: /usr/local/etc/openssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; postalCode=M5J 2L7; ST=Ontario; L=Toronto; street=144 Front Street West; O=Wild Apricot Inc.; OU=PremiumSSL Wildcard; CN=*.wildapricot.org
* start date: Sep 20 00:00:00 2018 GMT
* expire date: Nov 17 23:59:59 2020 GMT
* subjectAltName: host "oauth.wildapricot.org" matched cert's "*.wildapricot.org"
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Organization Validation Secure Server CA
* SSL certificate verify ok.
> POST /auth/token HTTP/1.1
Host: oauth.wildapricot.org
Accept: */*
Content-Length: 76
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 76 out of 76 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Length: 68
< Content-Type: application/json; charset=utf-8
< Expires: -1
< WWW-Authenticate: Basic realm="authentication required"
< X-Powered-By: ASP.NET
< Access-Control-Allow-Origin: *
< Date: Fri, 15 Nov 2019 12:29:30 GMT
< Connection: close
< X-Backend-Server: lap1wue1b-62e2
< X-LB-Server: llblue1b-5471
<
* Closing connection 0
This line tells us there's a problem with your authentication:
WWW-Authenticate: Basic realm="authentication required"
Curl provides a simpler method for HTTP Basic auth. Try removing the Authorization header and setting the CURLOPT_USERPWD option instead:
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);

Unable to post query string via CURL

URL Working fine in Browser after accepting the exception , but not working in curl.
My code is as follows :::
PHP CODE :
<?php
$str1 = "https://50.60.70.80/servlet/API";
$url = $str1."?".$_SERVER['QUERY_STRING'];
echo $url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST, true);
$data = curl_exec($ch);
echo curl_errno($ch);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
}
else {
echo 'Success: '.$data;
}
curl_close($ch);
?>
URL : https://50.60.70.80/servlet/API?userName=Test&password=pwd&message=My_Message&mobile=5555558888
Error getting while using through command line with "-k" and "-v":
***** About to connect() to 50.60.70.80 port 443 (#0)
* Trying 50.60.70.80... connected
* Connected to 50.60.70.80 (50.60.70.80) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* warning: ignoring value of ssl.verifyhost
* skipping SSL peer certificate verification
* SSL connection using TLS_DHM_RSA_W1TH_AES_128_CBC_SEA
* Server certificate:
* subject: E=abcd#mnmn.com,OU=lelna,O=teledna
* start date: Mar 01 09:51:25 2013 GMT
* expire date: Mar 01 09:51:25 2014 GMT
* common name: (nil)
* issuer: E=abcd#mnmn.com,OU=lelna,O=teledna
> GET /servlet/API?UserName=Test HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 50.60.70.80
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Pragma: no-cache
< Cache-Control: no-store
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Transfer-Encoding: chunked
< Date: Thu, 08 Aug 2013 16:38:57 GMT
<
status=FAILED,transid=4526698561,reasoncode=201
* Connection #0 to host 50.60.70.80 left intact
* Closing connection #0****
Can anybody help ?
I am using following versions ::
PHP Version -- 5.3.3
CURL Version -- 7.19.7
Using Apache
You need to add this
EDITED :
curl_setopt( $ch ,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

Categories