express-http-proxy icon indicating copy to clipboard operation
express-http-proxy copied to clipboard

+ sign in x-www-form-urlencoded not working

Open nickwinger opened this issue 6 years ago • 4 comments

Hello,

when you use the + sign in a FormData of a Post request the proxied destination does not receive the + sign but an empty space character. I use x-www-form-urlencoded to receive a token from an endpoint, my proxy code is very simple: `const functions = require('firebase-functions'); const app = require('express')(); const proxy = require('express-http-proxy'); const nodemailer = require('nodemailer'); const fs = require('fs');

app.use('/', proxy('http://some_destination')); `

when posting FormData like this: grant_type=password&username=nick%40mail.com&password=myPwd%2B&client_id=MyApp

the plus sign (encoded %2B) does not receive the proxied destination. Instead there is just a space character.

Can you please help me as this is very urgent... Users cannot login because they use + sign in the password...

Sidenote: special characters like $ or % are correctly proxied, only the + sign has troubles...

Thanks, Nick

nickwinger avatar Sep 01 '19 08:09 nickwinger

Hi,

had the same problem with + and & chars.

Solved it with simple url encode:

proxyReqBodyDecorator: function(bodyContent, srcReq) {
    bodyContent.password = encodeURIComponent(bodyContent.password);
    return bodyContent;
}

JKnorr91 avatar Sep 02 '19 11:09 JKnorr91

@JKnorr91 Thank you, works perfect for me, but still this issue has to be fixed in the library itself, so i leave the defect open. I mean whatever the library changes, it's weired because the body should be sent like the original, and i already have encodeURIComponent in my Javascript-Frontend-Source-Code

nickwinger avatar Sep 07 '19 10:09 nickwinger

proxyReqBodyDecorator: function(bodyContent, req) {
        return encodeURIallPropertiesByReflection(bodyContent);
},

and somewhere

encodeURIallPropertiesByReflection: (bodyContent) => {
        if(Reflect.ownKeys(bodyContent)){
            const keys = Reflect.ownKeys(bodyContent);
            for (const idx in keys) {
              Reflect.set(bodyContent, keys[idx], encodeURIComponent(bodyContent[keys[idx]]));
            }
          }
        return bodyContent;
    },

eydunn avatar Nov 12 '20 09:11 eydunn

This looks like body parsers were applied to proxied requests. See: https://www.npmjs.com/package/express-http-proxy#middleware-mixing

While not recommended, if you really need to keep the body parsers in place, then you could re-encode the body back into application/x-www-form-urlencoded content:

import {stringify as qsStringify} from 'qs';

proxyReqBodyDecorator(bodyContent, srcReq) {
  if (srcReq.headers['content-type']?.toLowerCase().includes('x-www-form-urlencoded')) {
    return qsStringify(bodyContent);
  }
  return bodyContent;
},

mdmower avatar Feb 24 '24 22:02 mdmower