Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The request in Parse.Object.saveAll() does not have a reverse proxy #1945

Open
4 tasks done
roger28200901 opened this issue Jun 14, 2023 · 10 comments
Open
4 tasks done

Comments

@roger28200901
Copy link

roger28200901 commented Jun 14, 2023

New Issue Checklist

Issue Description

I was wondering about the practical method behind Parse.Object.saveAll, If my Parse Server I want to redirect through Proxy
ex: 192.168.1.1/api -> 192.168.1.1:4000/parse then, here is the problem.

on the parse/lib/node/ParseObject.js line:2388

return RESTController.request('POST', 'batch', {
              requests: batch.map(obj => {
                const params = obj._getSaveParams();
                params.path = getServerUrlPath() + params.path;
                return params;
              })
            }, options);

And here is the problem, After the above code, my input data format will be like this:

{
  "requests": [
    {
      "method": "PUT",
      "path": "/api/classes/{{className}}/{{ objectId }}",
      "body": {
         {{ Here is the object body}}
       }
    }
  ]
}

and then, as you can see the RESTController will send a axios POST for url -> 192.168.1.1/api/batch and then proxy server (nginx), will let the request send to the 192.168.1.1:4000/parse/batch, but in my requests body, the path only show it to /api/classes/{{className}}/{{objectId}}
, it wont through the nginx setting to let the redirect change to /parse/classes/{{className}}/{{objectId}}

Steps to reproduce

//config.js
const parseUrl = process.env.PARSE_URL || 'http://192.168.1.1/api'; // the nginx will let the 192.168.1.1/api turn into 192.168.1.1:4000/parse
const appId = 'test';
const masterKey = 'test-key';
const initParse = () => {
  Parse.initialize(appId, null, masterKey);
  Parse.serverURL = parseUrl;
  Parse.User.enableUnsafeCurrentUser();
};
const query = new Parse.Query(Tests);
const tests = await query.findAll()
tests.forEach((test) => {
 test.set('name', 'something');
})
await Parse.Object.saveAll(tests); // And then show the error code 206

Actual Outcome

format : Parse Error: cannot route batch path: /api/classes/{{className}}/{{objectId}} { code: 111 }

real outcome: ParseError: cannot route batch path /api/classes/tests/6ab89f70-addf-11ed-b17e-f98dadf7fe5c at C:\Users.......\node_modules\parse\lib\node\ParseObject.js:3047:34 at processTicksAndRejections (node:internal/process/task_queues:96:5) { code: 111 },
.
.
.

Expected Outcome

Expected it can saveAll and the response won't fail

Environment

Nginx

location /api/ {
    #proxy_redirect off;
    #proxy_set_header Host $host;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS';
    add_header Access-Control-Allow-Headers 'Content-Type, X-DP-Token, X-DP-Application-Id';
    #proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://192.168.1.1:4000/parse/;
    client_max_body_size 16M;
  }

Server

  • Parse Server version: 6.2.0
  • Operating system: linux

Database

  • MongoDB

Client

  • Parse JS SDK version: 4.1.0
@parse-github-assistant
Copy link

parse-github-assistant bot commented Jun 14, 2023

Thanks for opening this issue!

  • 🚀 You can help us to fix this issue faster by opening a pull request with a failing test. See our Contribution Guide for how to make a pull request, or read our New Contributor's Guide if this is your first time contributing.

@mtrezza
Copy link
Member

mtrezza commented Jun 14, 2023

Could you please complete the issue template (I've re-added the headlines) and ensure that you follow the checklist at the top?

@roger28200901
Copy link
Author

Could you please complete the issue template (I've re-added the headlines) and ensure that you follow the checklist at the top?

I already fix it, and very sorry about didn't follow the issue template, cause this is the first time I try to send the issue.

@mtrezza
Copy link
Member

mtrezza commented Jun 14, 2023

No worries, thanks for reporting the issue. The template just helps others to easier understand the issue.

In the steps to reproduce you are first querying tests and then saving all users. How are tests and users related?

@roger28200901
Copy link
Author

sorry, it was tests not users. I already edited it. and also add setting code about the nginx setting. and you can check it.

@mtrezza
Copy link
Member

mtrezza commented Jun 15, 2023

Could you please correct the code and make sure it's complete?

@roger28200901
Copy link
Author

Could you please correct the code and make sure it's complete?

I corrected it. Here are some additions, where my parse server is set on port :4000/parse on docker, so you can see above that I use an nginx as a reverse proxy to /api -> :4000/parse

@mtrezza
Copy link
Member

mtrezza commented Jun 15, 2023

Could you post the line from ParseObject.js:3047:34?

@roger28200901
Copy link
Author

 (0, _promiseUtils.when)(batchReady).then(() => {
            // Kick off the batch request
            return RESTController.request('POST', 'batch', {
              requests: batch.map(obj => {
                const params = obj._getSaveParams();
                params.path = getServerUrlPath() + params.path;
                return params;
              })
            }, options);
          }).then(batchReturned.resolve, error => {
            batchReturned.reject(new _ParseError.default(_ParseError.default.INCORRECT_TYPE, error.message));
          });

The error show up on the batchReturned ... this line
and then I see the function getServerUrlPath() how it works,

function getServerUrlPath() {
  let serverUrl = _CoreManager.default.get('SERVER_URL');
  if (serverUrl[serverUrl.length - 1] !== '/') {
    serverUrl += '/';
  }
  const url = serverUrl.replace(/https?:\/\//, '');
  return url.substr(url.indexOf('/'));
}

so as you can see, if my parseUrl is 'http://192.168.1.1/api' and I use a reverse proxy to make this url to redirect on the Parse Server (this is setup on the docker url: '192.168.1.1:4000/parse'), and I can see the request is sending to the url 'http://192.168.1.1/api' and then turn into the 'https://192.168.1.1:4000/parse', but the getServerUrlPath() didn't know I was trying to use reverse proxy skill, so params.path = getServerUrlPath() + params.path; it will show up like /api/classes/{className}/{objectId} and not like this /parse/classes/{className}/{objectId},

for example:

{
        "requests": [
          {
            "method": "POST",
            "path": "/api/classes/GameScore",
            "body": {
              "score": 1337,
              "playerName": "Sean Plott"
            }
          },
          {
            "method": "POST",
            "path": "/api/classes/GameScore",
            "body": {
              "score": 1338,
              "playerName": "ZeroCool"
            }
          }
        ]
      }' 
  request url : https://192.168.1.1/api/ -> and then proxy will send into https://192.168.1.1:4000/parse
  request method: post
  but the every request object's attribute 'path' won't change to /parse/....

Sorry for my english is not very good so please forgive me :( if i didn't explain clearly

@mtrezza
Copy link
Member

mtrezza commented Jun 16, 2023

Thanks for providing more details, let's see if someone in the community has an idea...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants