How to check the responses of an HTTP request? - php

I had completed a small Android project(MAP and Location based) 4 months before. Now I am planning to improve the App by upgrading the map API and some code tweaking. As a part of this, I would like to ask that how can I check the response for an HTTP request from the web-server efficiently. My current strategy is:
App will upload the data to PHP server by using HTTP GET method.
The response from server will be in the form of XML tagged format.
I must have to check the corresponding tag for the response from server(use xmlParser example seen in Stack Overflow xml parser).
I think this is little bit annoying for me. Is there any easy method to achieve this process?
Example:
If the user tries to log-in, the credential will be checked in SERVER and successful authentication will be replied as some code: 1 else: 0.
All the HTTP requests are handled as asynctask.

public String login(String login_url,List<NameValuePair> login_parameters_list) throws ClientProtocolException, IOException
{
int response_code = -1;
HttpPost httppost = new HttpPost(post_url);
httppost.setEntity(new UrlEncodedFormEntity(post_parameters_list));
HttpResponse response = httpclient.execute(httppost);
// coockie management
httpclient.getCookieStore().getCookies().get(0).getName();
response_code = response.getStatusLine().getStatusCode();
if(response_code == 999 || response_code == HttpStatus.SC_INTERNAL_SERVER_ERROR)
{
Log.e("HttpResponse", "Internal Server");
}
else if(response_code == -1 )
{
Log.e("HttpResponse", "Socket connection timeout");
}
if (response_code == HttpStatus.SC_UNAUTHORIZED)
{
// credential check failed
Log.e("HTTP status", "unauthorised");
}
else if (response_code == HttpStatus.SC_FORBIDDEN)
{
// forbidden
Log.e("HTTP status", "Forbidden");
}
return response_code == HttpStatus.SC_OK ? EntityUtils.toString(response.getEntity()) : null;
}

Related

Cannot retrieve error message using Symfony HttpClient if the response is not "ok"

I use Symfony HttpClient to call an external API. When the status code is 200 I can use getContent() method to retrieve the API response. If the API response is 400, a ClientException is thrown, and I cannot get the external API message.
$httpClient = HttpClient::create();
$response = $httpClient->request($method, $url);
if (200 !== $response->getStatusCode()) {
$apiResponse['statusCode'] = $response->getStatusCode();
$httpInfo = $response->getInfo();
$content = $response->getContent(); //this throws ClientException
}
You can use
$response->getContent(false)
to get the response and not an error thrown.
Explanation from Code:
public function getContent(bool $throw = true): string
Note that you lose a bit of the very meaningful wrapping functionality HttpClient provides you here.

HTTP JSON API request responds "-1"

I'm trying to make a REST API that an Arduino with an ESP8266 module can GET, but when I try to send a request to my server the HTTP Code that I get is -1, which I have not been able to find any documentation on anywhere (it's not in the list of HTTP status codes here).
My test-API that I get the -1 response from is here, while a this API works fine. My API is simple:
PHP API:
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
$array = array(
"status" => true
);
echo json_encode($array);
The Arduino code is just one of the ESP8266 examples, and looks like this:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
const char* ssid = "Next-Guest";
const char* password = "";
void setup () {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print("Connecting..");
}
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
//http.begin("http://jsonplaceholder.typicode.com/users/1"); <- this works
http.begin("https://makerspace.albe.pw/api/getDoorStatus.php"); // <- this doesn't
int httpCode = http.GET();
Serial.println(httpCode);
if (httpCode > 0) {
String payload = http.getString();
Serial.println(payload);
}
http.end();
}
delay(30000);
}
I can do a GET request locally from any computer to my API using jQuery AJAX, so it must be somewhat open?
Is my host the problem, or are my files missing some headers?
When accessing a domain protected with a SSL certificate (https), you need to specify the SSL thumbprint as a second parameter in the http.begin function:
String thumbprint = "the_thumbprint";
http.begin("https://api.site/api/get_details.json", thumbprint);

Android / Loopj - How can i POST a complex JSON object to a server?

In one of my application, in which I use the Loopj library, I need to send a complex object to a web-service (running on PHP). I decided to send a JSON object via HTTP POST request using Loppj example.
JSONObject params = new JSONObject();
try
{
params.put("params1", "value1");
params.put("params2", "value2");
params.put("params3", "value3");
}
catch(JSONException e)
{
// ...
}
StringEntity entity = new StringEntity(params.toString(), HTTP.UTF_8);
ArrayList<Header> array = new ArrayList<>();
array.add(new BasicHeader("Content-type", "application/json"));
array.add(new BasicHeader("Accept", "application/json"));
Header[] headers = new Header[headers.size()];
headers = headers.toArray(array);
AsyncHttpClient client = new AsyncHttpClient();
client.post(context, url, headers, entity, "application/json", new JsonHttpResponseHandler()
{
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response)
{
//...
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject errorResponse)
{
// ...
}
});
Unfortunately, $_POST / $_REQUEST are always empty. I've searched different tips but none of them is working. I haven't restriction on routes in my web-service, just a simple function to dump posted parameters.
EDIT 1
To check posted parameters, I coded a simple PHP page to log them. Thanks to #Steve, I was abble to find them in php://input.
file_put_contents(__DIR__ . '/post_data.log', json_encode($_POST));
file_put_contents(__DIR__ . '/input_data.log', file_get_contents('php://input'));
The fact is that I'm not the owner of the final web-services, so I can't change access to data. They must be accessible through $_POST. So, sending application/json isn't the solution ? How AJAX can send complex objects to a server and find them in $_POST, and not Android ?
EDIT 2
I tried to do the same with PostMan and $_POST is always empty. So, I analyzed the request sent by jQuery.ajax(...) (which allow you to send JSON object) and it generate proper key/value from JSON object.
For example, the JSON object :
{
"users":[
{
"name":"jean",
"age":"25",
"city":"paris"
}
]
}
It is converted in 3 pairs key/value :
users[0][name] : jean
users[0][age] : 25
users[0][city] : paris.
So, I guess I need a function which convert my JSONObject into RequestParams object and send it "normally" through "x-www-form-urlencoded". I don't know if there's any native function which can do this but I found the Javascript equivalent (Query-string encoding of a Javascript Object).
serialize = function(obj, prefix) {
  var str = [], p;
  for(p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.push((v !== null && typeof v === "object") ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
}
As I said previously, I wrote a helper class which convert JSONObject to RequestParams which can "normally" be sent over POST HTTP method.
I copy/paste it and wrote a quick README file. If you have any suggestions or even pull-requests, please share.
Hope it helps.
https://github.com/schnapse/json-to-requestparams

Performing requests to ETSY store allowing access automatically PHP OAUTH

I am using a library to connect to my ETSY store and pull data from receipts to bring them into my personal website (database).
After making the request using OAuth, I get to the ETSY site to "Allow Access"
https://www.etsy.com/images/apps/documentation/oauth_authorize.png
Then, I need to manually click on Allow Access and my request will be completed and will display the data requested.
I would like to avoid the process of manually clicking on "Allow Access", since I want my personal site to automatically display information pulled from ETSY orders.
Here is my current code for page etsyRequest.php:
$credentials = new Credentials(
$servicesCredentials['etsy']['key'],
$servicesCredentials['etsy']['secret'],
$currentUri->getAbsoluteUri()
);
// Instantiate the Etsy service using the credentials, http client and storage mechanism for the token
/** #var $etsyService Etsy */
$etsyService = $serviceFactory->createService('Etsy', $credentials, $storage);
if (!empty($_GET['oauth_token'])) {
$token = $storage->retrieveAccessToken('Etsy');
// This was a callback request from Etsy, get the token
$etsyService->requestAccessToken(
$_GET['oauth_token'],
$_GET['oauth_verifier'],
$token->getRequestTokenSecret()
);
// Send a request now that we have access token
$result2 = json_decode($etsyService->request('/receipts/111111'));
//echo 'result: <pre>' . print_r($result, true) . '</pre>';
echo $result2->results[0]->seller_user_id;
How could I automate the Allow Access part and get the returned value for my request by just running this page?
You can resolved this problem by simply save the returned "access token" and "token secret".
Steps to do it:
After making the request using OAuth, you get to the ETSY site to
"Allow Access". after allowing it will show a oauth_verifier pin.
After you enter this pin in your code it will set "access token" and
"token secret" to your request.you just need to save them in
variables or database.
next time when to create any request to etsy you just have to set
these access token" and "token secret" with your oauth_consumer_key
and oauth_consumer_secret. you don't need oauth_verifier pin at that time.
it will work util you revoke permission from your etsy account.
I did this in my java code because i mm facing same problem and its working.(sorry i m not good enough in php) here is my sample code may this helps-
public void accessEtsyAccount(String consumer_key, String consumer_secret, String requestToken, String tokenSecret, String shopName) throws Throwable{
OAuthConsumer consumer = new DefaultOAuthConsumer(
consumer_key, consumer_secret
);
if(StringUtils.isBlank(requestToken) || StringUtils.isBlank(tokenSecret) ){
OAuthProvider provider = new DefaultOAuthProvider(
"https://openapi.etsy.com/v2/oauth/request_token",
"https://openapi.etsy.com/v2/oauth/access_token",
"https://www.etsy.com/oauth/signin");
System.out.println("Fetching request token from Etsy...");
// we do not support callbacks, thus pass OOB
String authUrl = provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND);
System.out.println("Request token: " + consumer.getToken());
System.out.println("Token secret: " + consumer.getTokenSecret());
System.out.println("Now visit:\n" + authUrl
+ "\n... and grant this app authorization");
if(Desktop.isDesktopSupported()){
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(new URI(authUrl));
} catch (IOException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("xdg-open " + authUrl);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Enter the PIN code and hit ENTER when you're done:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String pin = br.readLine();
System.out.println("Fetching access token from Etsy...");
provider.retrieveAccessToken(consumer, pin);
} else {
consumer.setTokenWithSecret(requestToken, tokenSecret);
}
System.out.println("Access token: " + consumer.getToken());
System.out.println("Token secret: " + consumer.getTokenSecret());
URL url = new URL("https://openapi.etsy.com/v2/private/shops/"+shopName+"/transactions");
HttpURLConnection request = (HttpURLConnection) url.openConnection();
consumer.sign(request);
System.out.println("Sending request to Etsy...");
request.connect();
System.out.println("Response: " + request.getResponseCode() + " "
+ request.getResponseMessage());
System.out.println("Payload:");
InputStream stream = request.getInputStream();
String stringbuff = "";
byte[] buffer = new byte[4096];
while (stream.read(buffer) > 0) {
for (byte b: buffer) {
stringbuff += (char)b;
}
}
System.out.print(stringbuff);
You need to save the access token when you have requested the Etsy store for the first time and then the same access token can be used for later calls. This would prevent you from clicking ALLOW ACCESS again and again when requesting Etsy store through API.

Handling different php responses after a javascript http post request

I am developing an android application that uses the PHP/MySQL to send data from app to server in order to register/login users. I already wrote the Javascript and PHP files to send and receive JSON data an insert it into MySQL database. The problem I have is how to handle different responses from PHP.
Exemple:
<?php
//decode json object
$json = file_get_contents('php://input');
$obj = json_decode($json);
//variables
$user_firstname = $obj->{'user_firstname'};
$user_lastname = $obj->{'user_lastname'};
$user_email = $obj->{'user_email'};
$user_password = $obj->{'user_password'};
if([variables] != null){
//check for an existing email in db
mysql_query("Check if email exists");
if(email exist){
//pass a response to java file
return user_exists;
die();
}else{
//success
return success;
}
}
?>
All I want is to handle those different return values in order to interact with the user inside the android app.
I think you should user HTTP response codes for this. For example, your php script will return HTTP 200 - OK when user successfully created and HTTP 409 Conflict when user already exists. This is how RESTfull APIs usually works this. On Android you'll have to check the status code and decide what to do.
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpget = new HttpPost("http://www.google.com/");
HttpResponse response = httpclient.execute(httpget);
int statusCode = response.getStatusLine().getStatusCode();
You can craft a json response by creating an associative array and passing it to json_encode() which will return a string that you can echo to the java client. Don't forget to set the appropriate Content-Type header using the header() function. It's also a good idea to set the HTTP response code appropriately. I'm picturing something like this:
$responseArray = array('response' => 'success'); // or 'user_exists'
$responseJson = json_encode($responseArray);
header('HTTP/1.1 200 OK'); // or 4xx FAIL_TEXT on failure
header('Content-Type: application/json');
echo $responseJson;
You'll then have to parse this response on the java client.

Categories