nativescript-community / https

Secure HTTP client with SSL pinning for Nativescript - iOS/Android
https://nativescript-community.github.io/https/
Other
50 stars 42 forks source link

application/x-www-form-urlencoded Handling Issue #70

Closed pradumnk-mahanta closed 4 years ago

pradumnk-mahanta commented 4 years ago

Hi All, I am having issues in specific to content type application/x-www-form-urlencoded. In general this should take in HttpParms in the body of the request, which is basically converted to something like,

grant_type=password&username=USERNAME&password=Pass@123

However, when I use this with the plugin is produces bad Request Error in iOS. So just to try it out I changed it to JSON Format,

{"grant_type" : "password", "username" : "ROBINT", "password" : "Pass@123"}

This works like a charm in iOS. The request is successful, and produces the correct login results. The issue is this produces bad request on the Android Side and If HttpParams is passed in Android, it would produce form the server.

{ "error" : "unsupported_grant_type" }

which I identified is due to the body format not being sent in the correct way in Android.

in https.ios.js, line 339, handles it for iOS. var dict = null; if (opts.body) { dict = bodyToNative(opts.body); }

but for Android

if (type.startsWith("multipart/form-data")) {
     var builder_1 = new okhttp3.MultipartBody.Builder();
     builder_1.setType(MEDIA_TYPE);
     opts.body.forEach(function (param) {
         if (param.fileName && param.contentType) {
             var MEDIA_TYPE_1 = okhttp3.MediaType.parse(param.contentType);
             builder_1.addFormDataPart(param.parameterName, param.fileName, okhttp3.RequestBody.create(MEDIA_TYPE_1, param.data));
         }
         else {
             builder_1.addFormDataPart(param.parameterName, param.data);
         }
     });
     okHttpBody = builder_1.build();
 }
 else {
     var body = void 0;
     if (opts.body) {
         try {
             body = JSON.stringify(opts.body);
         }
         catch (ignore) { }
     }
     else if (opts.content) {
         body = opts.content;
     }
     okHttpBody = okhttp3.RequestBody.create(okhttp3.MediaType.parse(type), body);
 }

The line body = JSON.stringify(opts.body); just converts the grant_type=password&username=USERNAME&password=Pass@123 back to JSON, and the server provides { "error" : "unsupported_grant_type" }.

The way I see it, is to modify the plugin a bit to handle the application/x-www-form-urlencoded but I may be missing something, or there may be another way I haven't thought of. So, if anyone would have a look at this and let me know if there is another way this plugin have been built to handle such requests.

Any feedback would be appreciated.

Thanks

pradumnk-mahanta commented 4 years ago

I just realized that, I also have the option pass the string data in the content section of the request. I just had to use this for non JSON requests.

https.request({
      url: req.url,
      content: <-------------------------------- **Pass the urlencoded data as string.,**
      method,
      headers,
      allowLargeResponse: true,
      cachePolicy: "noCache"
});

My bad. I will be closing this issue now.

Peace \/