From 41990128a33c268f3af2db80f4ac224802ac8b76 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 7 Nov 2016 17:14:34 +0200 Subject: [PATCH] Refactor project routing * split on multiple files * improve routing order Signed-off-by: Dmitriy Zaporozhets --- config/initializers/routing_draw.rb | 7 ++ config/routes.rb | 6 - config/routes/git_http.rb | 37 ++++++ config/routes/project.rb | 183 +--------------------------- config/routes/repository.rb | 110 +++++++++++++++++ config/routes/wiki.rb | 16 +++ 6 files changed, 176 insertions(+), 183 deletions(-) create mode 100644 config/initializers/routing_draw.rb create mode 100644 config/routes/git_http.rb create mode 100644 config/routes/repository.rb create mode 100644 config/routes/wiki.rb diff --git a/config/initializers/routing_draw.rb b/config/initializers/routing_draw.rb new file mode 100644 index 00000000000..25003cf0239 --- /dev/null +++ b/config/initializers/routing_draw.rb @@ -0,0 +1,7 @@ +# Adds draw method into Rails routing +# It allows us to keep routing splitted into files +class ActionDispatch::Routing::Mapper + def draw(routes_name) + instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb"))) + end +end diff --git a/config/routes.rb b/config/routes.rb index 659ea51bc75..7bf6c03e69b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,12 +2,6 @@ require 'sidekiq/web' require 'sidekiq/cron/web' require 'api/api' -class ActionDispatch::Routing::Mapper - def draw(routes_name) - instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb"))) - end -end - Rails.application.routes.draw do concern :access_requestable do post :request_access, on: :collection diff --git a/config/routes/git_http.rb b/config/routes/git_http.rb new file mode 100644 index 00000000000..03adc4815f3 --- /dev/null +++ b/config/routes/git_http.rb @@ -0,0 +1,37 @@ +scope constraints: { id: /.+\.git/, format: nil } do + # Git HTTP clients ('git clone' etc.) + get '/info/refs', to: 'git_http#info_refs' + post '/git-upload-pack', to: 'git_http#git_upload_pack' + post '/git-receive-pack', to: 'git_http#git_receive_pack' + + # Git LFS API (metadata) + post '/info/lfs/objects/batch', to: 'lfs_api#batch' + post '/info/lfs/objects', to: 'lfs_api#deprecated' + get '/info/lfs/objects/*oid', to: 'lfs_api#deprecated' + + # GitLab LFS object storage + scope constraints: { oid: /[a-f0-9]{64}/ } do + get '/gitlab-lfs/objects/*oid', to: 'lfs_storage#download' + + scope constraints: { size: /[0-9]+/ } do + put '/gitlab-lfs/objects/*oid/*size/authorize', to: 'lfs_storage#upload_authorize' + put '/gitlab-lfs/objects/*oid/*size', to: 'lfs_storage#upload_finalize' + end + end +end + +# Allow /info/refs, /info/refs?service=git-upload-pack, and +# /info/refs?service=git-receive-pack, but nothing else. +# +git_http_handshake = lambda do |request| + request.query_string.blank? || + request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/) +end + +ref_redirect = redirect do |params, request| + path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs" + path << "?#{request.query_string}" unless request.query_string.blank? + path +end + +get '/info/refs', constraints: git_http_handshake, to: ref_redirect diff --git a/config/routes/project.rb b/config/routes/project.rb index 8142e231621..2f4a56ae5c9 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -21,149 +21,13 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: end scope module: :projects do - scope constraints: { id: /.+\.git/, format: nil } do - # Git HTTP clients ('git clone' etc.) - get '/info/refs', to: 'git_http#info_refs' - post '/git-upload-pack', to: 'git_http#git_upload_pack' - post '/git-receive-pack', to: 'git_http#git_receive_pack' - - # Git LFS API (metadata) - post '/info/lfs/objects/batch', to: 'lfs_api#batch' - post '/info/lfs/objects', to: 'lfs_api#deprecated' - get '/info/lfs/objects/*oid', to: 'lfs_api#deprecated' - - # GitLab LFS object storage - scope constraints: { oid: /[a-f0-9]{64}/ } do - get '/gitlab-lfs/objects/*oid', to: 'lfs_storage#download' - - scope constraints: { size: /[0-9]+/ } do - put '/gitlab-lfs/objects/*oid/*size/authorize', to: 'lfs_storage#upload_authorize' - put '/gitlab-lfs/objects/*oid/*size', to: 'lfs_storage#upload_finalize' - end - end - end - - # Allow /info/refs, /info/refs?service=git-upload-pack, and - # /info/refs?service=git-receive-pack, but nothing else. - # - git_http_handshake = lambda do |request| - request.query_string.blank? || - request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/) - end - - ref_redirect = redirect do |params, request| - path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs" - path << "?#{request.query_string}" unless request.query_string.blank? - path - end - - get '/info/refs', constraints: git_http_handshake, to: ref_redirect - - # Blob routes: - get '/new/*id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob' - post '/create/*id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob' - get '/edit/*id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob' - put '/update/*id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob' - post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob' + draw :git_http # # Templates # get '/templates/:template_type/:key' => 'templates#show', as: :template - scope do - get( - '/blob/*id/diff', - to: 'blob#diff', - constraints: { id: /.+/, format: false }, - as: :blob_diff - ) - get( - '/blob/*id', - to: 'blob#show', - constraints: { id: /.+/, format: false }, - as: :blob - ) - delete( - '/blob/*id', - to: 'blob#destroy', - constraints: { id: /.+/, format: false } - ) - put( - '/blob/*id', - to: 'blob#update', - constraints: { id: /.+/, format: false } - ) - post( - '/blob/*id', - to: 'blob#create', - constraints: { id: /.+/, format: false } - ) - end - - scope do - get( - '/raw/*id', - to: 'raw#show', - constraints: { id: /.+/, format: /(html|js)/ }, - as: :raw - ) - end - - scope do - get( - '/tree/*id', - to: 'tree#show', - constraints: { id: /.+/, format: /(html|js)/ }, - as: :tree - ) - end - - scope do - get( - '/find_file/*id', - to: 'find_file#show', - constraints: { id: /.+/, format: /html/ }, - as: :find_file - ) - end - - scope do - get( - '/files/*id', - to: 'find_file#list', - constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }, - as: :files - ) - end - - scope do - post( - '/create_dir/*id', - to: 'tree#create_dir', - constraints: { id: /.+/ }, - as: 'create_dir' - ) - end - - scope do - get( - '/blame/*id', - to: 'blame#show', - constraints: { id: /.+/, format: /(html|js)/ }, - as: :blame - ) - end - - scope do - get( - '/commits/*id', - to: 'commits#show', - constraints: { id: /.+/, format: false }, - as: :commits - ) - end - resource :avatar, only: [:show, :destroy] resources :commit, only: [:show], constraints: { id: /\h{7,40}/ } do member do @@ -206,29 +70,6 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: end end - WIKI_SLUG_ID = { id: /\S+/ } unless defined? WIKI_SLUG_ID - - scope do - # Order matters to give priority to these matches - get '/wikis/git_access', to: 'wikis#git_access' - get '/wikis/pages', to: 'wikis#pages', as: 'wiki_pages' - post '/wikis', to: 'wikis#create' - - get '/wikis/*id/history', to: 'wikis#history', as: 'wiki_history', constraints: WIKI_SLUG_ID - get '/wikis/*id/edit', to: 'wikis#edit', as: 'wiki_edit', constraints: WIKI_SLUG_ID - - get '/wikis/*id', to: 'wikis#show', as: 'wiki', constraints: WIKI_SLUG_ID - delete '/wikis/*id', to: 'wikis#destroy', constraints: WIKI_SLUG_ID - put '/wikis/*id', to: 'wikis#update', constraints: WIKI_SLUG_ID - post '/wikis/*id/preview_markdown', to: 'wikis#preview_markdown', constraints: WIKI_SLUG_ID, as: 'wiki_preview_markdown' - end - - resource :repository, only: [:create] do - member do - get 'archive', constraints: { format: Gitlab::Regex.archive_formats_regex } - end - end - resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do member do get :test @@ -245,23 +86,6 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: resources :forks, only: [:index, :new, :create] resource :import, only: [:new, :create, :show] - resources :refs, only: [] do - collection do - get 'switch' - end - - member do - # tree viewer logs - get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex } - # Directories with leading dots erroneously get rejected if git - # ref regex used in constraints. Regex verification now done in controller. - get 'logs_tree/*path' => 'refs#logs_tree', as: :logs_file, constraints: { - id: /.*/, - path: /.*/ - } - end - end - resources :merge_requests, concerns: :awardable, constraints: { id: /\d+/ } do member do get :commits @@ -467,6 +291,11 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: end end end + + # Since both wiki and repository routing contains wildcard characters + # its preferable to keep it below all other project routes + draw :wiki + draw :repository end end end diff --git a/config/routes/repository.rb b/config/routes/repository.rb new file mode 100644 index 00000000000..76dcf113aea --- /dev/null +++ b/config/routes/repository.rb @@ -0,0 +1,110 @@ +# All routing related to repositoty browsing + +resource :repository, only: [:create] do + member do + get 'archive', constraints: { format: Gitlab::Regex.archive_formats_regex } + end +end + +resources :refs, only: [] do + collection do + get 'switch' + end + + member do + # tree viewer logs + get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex } + # Directories with leading dots erroneously get rejected if git + # ref regex used in constraints. Regex verification now done in controller. + get 'logs_tree/*path' => 'refs#logs_tree', as: :logs_file, constraints: { + id: /.*/, + path: /.*/ + } + end +end + +get '/new/*id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob' +post '/create/*id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob' +get '/edit/*id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob' +put '/update/*id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob' +post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob' + +scope do + get( + '/blob/*id/diff', + to: 'blob#diff', + constraints: { id: /.+/, format: false }, + as: :blob_diff + ) + get( + '/blob/*id', + to: 'blob#show', + constraints: { id: /.+/, format: false }, + as: :blob + ) + delete( + '/blob/*id', + to: 'blob#destroy', + constraints: { id: /.+/, format: false } + ) + put( + '/blob/*id', + to: 'blob#update', + constraints: { id: /.+/, format: false } + ) + post( + '/blob/*id', + to: 'blob#create', + constraints: { id: /.+/, format: false } + ) + + get( + '/raw/*id', + to: 'raw#show', + constraints: { id: /.+/, format: /(html|js)/ }, + as: :raw + ) + + get( + '/tree/*id', + to: 'tree#show', + constraints: { id: /.+/, format: /(html|js)/ }, + as: :tree + ) + + get( + '/find_file/*id', + to: 'find_file#show', + constraints: { id: /.+/, format: /html/ }, + as: :find_file + ) + + get( + '/files/*id', + to: 'find_file#list', + constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }, + as: :files + ) + + post( + '/create_dir/*id', + to: 'tree#create_dir', + constraints: { id: /.+/ }, + as: 'create_dir' + ) + + get( + '/blame/*id', + to: 'blame#show', + constraints: { id: /.+/, format: /(html|js)/ }, + as: :blame + ) + + # File/dir history + get( + '/commits/*id', + to: 'commits#show', + constraints: { id: /.+/, format: false }, + as: :commits + ) +end diff --git a/config/routes/wiki.rb b/config/routes/wiki.rb new file mode 100644 index 00000000000..ecd4d395d66 --- /dev/null +++ b/config/routes/wiki.rb @@ -0,0 +1,16 @@ +WIKI_SLUG_ID = { id: /\S+/ } unless defined? WIKI_SLUG_ID + +scope do + # Order matters to give priority to these matches + get '/wikis/git_access', to: 'wikis#git_access' + get '/wikis/pages', to: 'wikis#pages', as: 'wiki_pages' + post '/wikis', to: 'wikis#create' + + get '/wikis/*id/history', to: 'wikis#history', as: 'wiki_history', constraints: WIKI_SLUG_ID + get '/wikis/*id/edit', to: 'wikis#edit', as: 'wiki_edit', constraints: WIKI_SLUG_ID + + get '/wikis/*id', to: 'wikis#show', as: 'wiki', constraints: WIKI_SLUG_ID + delete '/wikis/*id', to: 'wikis#destroy', constraints: WIKI_SLUG_ID + put '/wikis/*id', to: 'wikis#update', constraints: WIKI_SLUG_ID + post '/wikis/*id/preview_markdown', to: 'wikis#preview_markdown', constraints: WIKI_SLUG_ID, as: 'wiki_preview_markdown' +end