Why do my heroku logs show infinite repetitions of the same request?

Viewed 225

First time posting on StackOverflow after many happy years reading it so apologies if this isn't written correctly. We recently pushed our React / NextJS app to production, hosted by Heroku. We have a separate GraphQL Yoga server to manipulate and send the right data, also hosted by Heroku. You can visit the app at https://www.sayplants.com. My database (Prisma) is reporting 10,000s of requests to our database despite the fact that I am the only person using the site . I checked our Heroku logs and am seeing a very strange pattern. First, a GET request:

2020-05-27T13:40:18.883461+00:00 heroku[router]: at=info method=GET path="/" host=www.sayplants.com request_id=36c364a0-012b-4927-813d-314bd3674657 fwd="176.249.98.203" dyno=web.1 connect=1ms service=150ms status=200 bytes=4252 protocol=https

Then, a POST request with the same request_id, but a proxy added to the "fwd" field:

2020-05-27T13:40:18.975987+00:00 heroku[router]: at=info method=POST path="/" host=www.sayplants.com request_id=36c364a0-012b-4927-813d-314bd3674657 fwd="176.249.98.203,54.216.239.50" dyno=web.1 connect=0ms service=89ms status=200 bytes=4251 protocol=https

Then, the POST request repeats itself again and again, adding (the same) proxy to the "fwd" (Heroku's shorthand for X-Forwarded-For) each time, so we have fwd="176.249.98.203, 54.216.239.50", and in the next log we have fwd="176.249.98.203, 54.216.239.50, 54.216.239.50", and then fwd="176.249.98.203, 54.216.239.50, 54.216.239.50, 54.216.239.50", and so on until there are hundreds of the same IP address repeated over and over.

On closer inspection we were able to remove this behaviour in production, by removing our User information requests from the NextJS app - removing the following:

const User = props => (
  <Query {...props} query={CURRENT_USER_QUERY}>
    {payload => props.children(payload)}
  </Query>
);

User.propTypes = {
  children: PropTypes.func.isRequired,
};

export default User;

Where:

const CURRENT_USER_QUERY = gql`
  query {
    me {
      id
      email
      name
    }
  }
`;

But obviously we need user functionality! So we have isolated the issue but don't know how to solve it.

If you're still with me, for fullness' sake this is our backend Query resolver:

    async me(parent, args, ctx, info) {
        if(!ctx.request.userId) {
            return null;
        }
        const user = await ctx.db.query.user({
            where: { id: ctx.request.userId }
        }, info);
        return user
    },

Where the request.userId is set by some Express middleware

server.express.use(cookieParser());

server.express.use((req, res, next) => {
  const { token } = req.cookies;
  if (token) {
    const { userId } = jwt.verify(token, process.env.APP_SECRET)
    req.userId = userId
  }
  next();
});

Any help would be massively appreciated. Banging my head against the wall for days on this one.

0 Answers
Related