luckyframework / lucky

A full-featured Crystal web framework that catches bugs for you, runs incredibly fast, and helps you write code that lasts.

Home Page:https://luckyframework.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

redirect_back not work as expected as previous_url

zw963 opened this issue · comments

Describe the bug

Please check following log:

  1. It simple, render a form use GET /universities/788/edit from Index page (/universities)
web          |
web          | GET /universities/788/edit
web          |  ▸ Handled by Universities::Edit
web          | "Print in form"                    # => "Print in form"
web          | context.request.headers["Referer"] # => "http://127.0.0.1:3000/universities"
web          | previous_url(Universities::Index)  # => "http://127.0.0.1:3000/universities"
web          |  ▸ Rendered Universities::EditPage
web          |  ▸ Sent 200 OK (2.07ms)

Then submit the form use PUT action.

web          |
web          | PUT /universities/788
web          |  ▸ Handled by Universities::Update
web          | "Print in update action"   # => "Print in update action"
web          | request.headers["Referer"] # => "http://127.0.0.1:3000/universities/788/edit"
web          |  ▸ Sent 303 See Other (62.6ms)
web          |
web          | GET /universities/788/edit
web          |  ▸ Handled by Universities::Edit
web          | "Print in form"                    # => "Print in form"
web          | context.request.headers["Referer"] # => "http://127.0.0.1:3000/universities/788/edit"
web          | previous_url(Universities::Index)  # => "/universities"
web          |
web          |  ▸ Rendered Universities::EditPage
web          |  ▸ Sent 200 OK (2.29ms)

What i expected is to redirect to original url which is the entry for render the form use following code, But it not work

class Universities::Update < BrowserAction
  include PageHelpers

  put "/universities/:university_id" do
    university = UniversityQuery.find(university_id)

    SaveUniversity.update(university, params) do |operation, updated_university|
      if operation.saved?
        pp! "Print in update action", request.headers["Referer"]
        flash.success = "修改成功"
        redirect_back fallback: Index, allow_external: true
      else
        flash.failure = "出错了"
        html EditPage, operation: operation, university: updated_university
      end
    end
  end
end

But, it not work as expected, as you can see the in above pp! log, the output of request.headers["Referer"] in the Update action output the /universities/788/edit instead of expected universities(which print by the previous_url).

Thanks

Expected behavior

Use redirect_back fallback: Index, allow_external: true to redirect back to /universities

Versions (please complete the following information):

  • Lucky version (check in shard.lock): 1.2.0
  • Crystal version (crystal --version): 1.12.1
  • OS: Arch Linux

Additional context
I use htmx, i test with disable it, same issue.

Is there any info that needs to be update for clarify?

redirect_back is working as expected. When you went to the edit page from the universities index page, the index was the referrer. But when you submit the form, the referrer is the get request for the edit page which is why it sent you back to it. I would recommend passing the url you want to send them back to as a field in the form if that's what you really want. Otherwise, just always redirect to the index

(Of course, I could be wrong).

This issue has been going on for some time, please let me try to reexplain it with more details.

  1. When i visit GET /universities/788/edit from the index page ("http://127.0.0.1:3000/universities"), I add some pp! code in the edit page, as following, the output of context.request.headers["Referer"] and previous_url(Universities::Index) in the form page both correct.

both output in the edit form page

web | context.request.headers["Referer"] # => "http://127.0.0.1:3000/universities"
web | previous_url(Universities::Index) # => "http://127.0.0.1:3000/universities"

  1. Let me submit the form

Then submit the form use PUT action, as you said in the reply, action print referer as edit page correctly

output in the action

request.headers["Referer"] # => "http://127.0.0.1:3000/universities/788/edit"

  1. We save the form successfully, the code is jump into the following redirect_back as following.
      if operation.saved?
        pp! "Print in update action", request.headers["Referer"]
        flash.success = "修改成功"
>        redirect_back fallback: Index, allow_external: true
      else
        flash.failure = "出错了"
        html EditPage, operation: operation, university: updated_university
      end
  1. Then the following output is the pp! in the edit page. (redirect_back redirect page back to original edit page in this case)
web          | GET /universities/812/edit
web          |  ▸ Handled by Universities::Edit
web          | "Print in form" # => "Print in form"
web          | context.request.headers["Referer"] # => "http://127.0.0.1:3000/universities/812/edit"
web          | previous_url(Universities::Index) # => "/universities"
web          |  ▸ Rendered Universities::EditPage
web          |  ▸ Sent 200 OK (3.11ms)
  1. so, the issue is, why previous_url(Universities::Index) return "/universities"? as the expected behavior said in your reply of redirect_back, previous_url should return edit page, right?

@matthewmcgarvey Thanks.

My guess is maybe a bug in previous_url ?

I'm not sure what this line is doing

return fallback.path if request.resource == referrer_path