What is wrong with this HTTPclient request that is always returning HTTP response = 400 (bad request)? - httpclient

I have done some projects with Arduino but is my first with HTTP post request, so forgive me if this is a very basic issue. I have been reading a lot of stuff on the forum/internet but haven't find anything to put me on the right path and therefore any help will be greatly appreciated.
When running the code below, on a AI-Thinker ESP32-CAM board (my end goal is to upload a picture to the service provider), I get always the "400 bad request" error.
Any ideas of what am I doing wrong? Also a suggestion as how to read the response body could be helpful in order to identify/fix the issue
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "SigloXX";
const char* password = "";
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
WiFiClient client;
HTTPClient http;
// set the server
http.begin(client, "mydomain.org/auth/login");
// set the headers
http.addHeader("accept", "application/json");
http.addHeader("Content-Type", "application/json");
// JSON data to send with HTTP POST
String httpRequestData = "{\"password\": \"myPassword\",\"login\": \"myLogin\"}";
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
// Free resources
http.end();
}
Many thanks in advance

Related

vertx Router no response

I wrote a dispatcher which routing a request to backend server, and response from backend is encrypted. When I decrypt the response body and write to RoutingContext response. Client can't receive response.
code like below
Router router;
router.routeWithRegex(patter).failureHandler(this::onFailure).handler(this::onRequest);
private void onRequest(Routing context){
...
HttpClient client = vertx.createHttpClient(new HttpClientOptions());
HttpClientRequest requestToBackend =
client.request(method, port, backendHost, uri, backendRsp -> onBackendResponse(context, backendRsp));
context.request().handler(body -> handleReq(requestToBackend));
context.request().endHandler((v) -> requestToBackend.end());
}
private void onBackendResponse(RoutingContext context, io.vertx.core.http.HttpClientResponse backendRsp) {
....
backendRsp.handler(data -> {
byte[] decrypt = decrypt(data);
context.request().response().write(data); // this works fine
// context.request().response().write(Buffer.buffer(decrypt)); // change to this, client can't receive response then
});
backendRsp.endHandler((v) -> context.request().response().end());
}
finally worked out, I changed the response body (shorter than origin), but not modify the header "content-length". so client keep waiting..

How to get Public IP in Flutter?

In my case, i need public IP Address. But, after research almost all documentary related to Local IP like: Get_IP, I want something like 202.xxx not 192.168.xxx. Can someone give some advice?
As far as I'm aware, there's no way to get the public IP of a device from within that device. This is because the vast majority of the time, the device doesn't know it's own public IP. The public IP is assigned to the device from the ISP, and your device is usually separated from the ISP through any number of modems, routers, switches, etc.
You need to query some external resource or API (such as ipify.org) that will then tell you what your public IP is. You can do this with a simple HTTP request.
import 'package:http/http.dart';
Future<String> getPublicIP() async {
try {
const url = 'https://api.ipify.org';
var response = await http.get(url);
if (response.statusCode == 200) {
// The response body is the IP in plain text, so just
// return it as-is.
return response.body;
} else {
// The request failed with a non-200 code
// The ipify.org API has a lot of guaranteed uptime
// promises, so this shouldn't ever actually happen.
print(response.statusCode);
print(response.body);
return null;
}
} catch (e) {
// Request failed due to an error, most likely because
// the phone isn't connected to the internet.
print(e);
return null;
}
}
EDIT: There is now a Dart package for getting public IP information from the IPify service. You can use this package in place of the above manual solution:
import 'package:dart_ipify/dart_ipify.dart';
void main() async {
final ipv4 = await Ipify.ipv4();
print(ipv4); // 98.207.254.136
final ipv6 = await Ipify.ipv64();
print(ipv6); // 98.207.254.136 or 2a00:1450:400f:80d::200e
final ipv4json = await Ipify.ipv64(format: Format.JSON);
print(ipv4json); //{"ip":"98.207.254.136"} or {"ip":"2a00:1450:400f:80d::200e"}
// The response type can be text, json or jsonp
}
I recently came across this package dart_ipify that can do this work.
https://pub.dev/packages/dart_ipify
Here is an example:
import 'package:dart_ipify/dart_ipify.dart';
void main() async {
final ipv6 = await Ipify.ipv64();
print(ipv6); // 98.207.254.136 or 2a00:1450:400f:80d::200e
}
I came across this topic recently.
After investigating the issue, I found a solution using an external API.
I am using ipstack, it has a generous free tier.
Request a free access key
Make the following POST call
http://api.ipstack.com/check?access_key=YOUR_ACCESS_KEY
You can extract the ip parameter from the response

How do you include a port number when using Embarcadero C++ TRESTRequest

Here's the compulsory code snippet:
UnicodeString SeizonshaRest::doStuff(UnicodeString strEmail, UnicodeString strPassword)
{
restclient->BaseURL = "http://localhost";
restrequest->Resource = ":60800/home/login";
restrequest->Params->AddItem("email", strEmail);
restrequest->Params->AddItem("password", strPassword);
UnicodeString strId;
restrequest->Execute();
strId = respMain->Content;
return strId;
}
I know this is the wrong way to do it.
What's the correct way to add a port number please?
The port number is attached to the server hostname that the client connects to, not to the resource that the client requests once connected.
Try this:
restclient->BaseURL = "http://localhost:60800";
restrequest->Resource = "home/login";
If you read the documentation, it says:
TCustomRESTClient.BaseURL
Specifies the base URL for all API calls.
All resources and parameters of your requests will be appended to this URL. Please, be aware that a trailing forward slash ("/") is added to the value of the BaseURL property.
TCustomRESTRequest.Resource
This property is added to the base URL to establish a complete URL for the HTTP request.
Important: The Resource value should meet the following limitations:
Does not include the scheme or domain mame.
Does not include the leading slash.
So, your original code would have produced the request URL as http://localhost/:60800/home/login, but the correct URL is http://localhost:60800/home/login instead.
I really wanted to post my code as I can find NO examples of this ANYWHERE
contact.h:
#ifndef contactH
#define contactH
#include <System.Classes.hpp>
#include <IPPeerClient.hpp>
#include <REST.Client.hpp>
//---------------------------------------------------------------------------
class contact;
class contact
{
public:
contact();
~contact() {};
String connect(String query);
TRESTClient *clientContact;
TRESTRequest *reqContact;
TRESTResponse *respContact;
private:
};
contact.cpp:
String contact::connect(String query)
{
clientContact = new TRESTClient(NULL);
reqContact = new TRESTRequest(NULL);
respContact = new TRESTResponse(NULL);
reqContact->Client = clientContact;
reqContact->Response = respContact;
UnicodeString strUrl = "http://myawesomeurl:5150";
reqContact.Resource = query;
clientContact->BaseURL = strUrl;
UnicodeString strInspect;
reqContact->Execute();
strInspect = respContact->Content;
return strInspect;
}
I hope this helps someone as stuck for examples as I was.

Restful URL custom authentication failing in java

This code is for getting the text from some URL which is having custom authentication as specified below.Tried with even ajax and Jquery as dataType:"jsonp" but it is also showing 401 error.
URL u;
HttpURLConnection con;
InputStream is = null;
DataInputStream dis;
String s;
try {
// u = new URL("http://q.addthis.com/feeds/1.0/trending.json?pubid=atblog");
u = new URL("http://m2mportal.connectm.com/EMS/rest/device");
is = u.openStream();
con=(HttpURLConnection) u.openConnection();
con.connect();
con.setDoOutput(true);
con.setRequestMethod("GET");
con.setRequestProperty("Accept","application/json");
con.setRequestProperty("Authorization","authenticate\":{\"userName\":\"admin01\",\"password\":\"admin01$\",\"appId\":\"123\"}");
con.setRequestProperty("userName","admin01");
con.setRequestProperty("password","admin01$");
con.setRequestProperty("appId","123");
dis = new DataInputStream(new BufferedInputStream(is));
while ((s = dis.readLine()) != null)
{
System.out.println(s);
}
}
catch (MalformedURLException mue)
{
System.out.println("Ouch - a MalformedURLException happened.");
mue.printStackTrace();
System.exit(1);
}
catch (IOException ioe)
{
System.out.println("Oops- an IOException happened.");
ioe.printStackTrace();
System.exit(1);
}
catch(IllegalStateException ise)
{
System.out.println("In IllegalState Exception........");
ise.printStackTrace();
}
When tried to authenticate against a url which is having some custom authentication as shown in the code it is returning 401 error
Oops- an IOException happened.
java.io.IOException: Server returned HTTP response code: 401 for URL: some url
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at java.net.URL.openStream(URL.java:1037)
at com.techm.JavaGetUrl.main(JavaGetUrl.java:16)
Java Result: 1
Actually problem here is Authorization property that you passed is not encoded.
You need to pass it to Base64 encoder so that http Authorization mechanism will use it.
Base64 encoding is commonly used when there is a need to encode / decode binary data stored and transferred over network.
Add encoding to your code . change your code to :
you need to use
Base64.encodeToString()
to perform encoding.
Following link will help you more:
http://www.javatips.net/blog/2011/08/how-to-encode-and-decode-in-base64-using-java

How to fetch data of remote server in GWT development mode?

I'm a GWT beginner. I debug my program in GWT development mode. The url is http://127.0.0.1:8888/Replayer.html?gwt.codesvr=127.0.0.1:9997.
I want to get data from existing server which provided data in json format. My code is:
String url = "http://i.abc.com?sid=" + mSessionId + "&action=info";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP
// violation, etc.)
Window.alert("Get fudao info error");
mPrepare = false;
}
#Override
public void onResponseReceived(Request request, Response response) {
GWT.log("statuscodeļ¼š"+response.getStatusCode());
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
Window.alert(response.getText());
mPrepare = true;
} else {
// Handle the error. Can get the status text from
// response.getStatusText()
Window.alert("Get fudao info wrong");
mPrepare = false;
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
When run the application, the request failed and its status was "canceled". Is it the reason that I cannot request remote server address from localhost for SOP restrictions?
How to fetch data of remote server in GWT development mode?
Normally can't fetch data from another server form GWT client code. But your local server can serve as proxy, e.g. you sending request to your local server, it will send request to remote server, than it will get response from remote server and give it to the GWT client code. This is basically the easiest solution.