ruby-grape / ruby-grape/grape

Using Rails' Mounted route fails if it has a dot in path (at first part)

Open
#1,889 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug?
Dominant language
Ruby
Stars
10k
Forks
1.2k
Avg merge
14h 38m
Merged PRs (30d)
92

Description

Steps to reproduce
  1. Create a rails project.
  2. Add grape as a dependency and install
  3. Open routes.rb and add following:
# frozen_string_literal: true

class DomainConstraint
  def initialize(domain)
    @domain = domain.downcase
  end

  def matches?(request)
    Rails.logger.debug "Request for host: #{request.host}"
    @domain == request.host.downcase
  end
end

Rails.application.routes.draw do
  constraints DomainConstraint.new(domain) do
    mount API => '/' # this is grape API mounted in Rails via '/' path.
  end
end
Expected behavior
GET http://example.com/gencer/test
GET http://example.com/.gencer/test

Those two request should be passed to grape because I've mounted base path to Grape as '/'.

Actual behavior

Only

GET http://example.com/gencer/test

successfully passed to grape.

GET http://example.com/.gencer/test

throws 404 not found error.

No route matches [GET] "/.gencer/test"

Related Grape code to capture path:

get ':path', requirements: { path: /.*/ } do
   ...
end

Even constraint is not executed if I use dot .. I've added a logging to matches? method. If I use dot in path, log is not present.

The thing is, This was working in the past. Now it isn't. Something has changed but whats changed, that I don't know for sure.

System configuration

Rails version: 5.2.3

Ruby version: 2.6.3

Demo

Clone https://github.com/gencer/mount_test

run bundle install && rails s

Go to

GET http://localhost:3000/gencer/demo

It will show you

{ "success": true }

Now go to:

GET http://localhost:3000/.gencer/demo

You will get 404 / No route matched.

Refer: config/routes.rb

Update

This only happens if base path has a dot in it. For example this will success:

GET http://localhost:3000/demo/.gencer/demo
{ "success": true }

So, If path start with dot (first folder) than route does not match with any.

Reference: https://github.com/rails/rails/issues/36491

I am opening this issue here as well, because, it may be coming from grape and not rails. Just want to make sure.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the mounted route and constraint in config/routes.rb, then run the mount_test reproduction with bundle install && rails s and compare the two documented requests. Trace why the constraint is skipped for a dot-prefixed first path segment, determining whether the behavior belongs to Grape or Rails; done means both paths reach the mounted API without the 404.

Written by the indexing model from the issue text.

Assessment

Tech stack
rails, ruby
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.