##// END OF EJS Templates
Rewrote git middleware with the same pattern as recent fix for #176...
marcink -
r1496:f4fed0b3 beta
parent child Browse files
Show More
@@ -51,9 +51,6 b' def make_app(global_conf, full_stack=Tru'
51 from rhodecode.lib.profiler import ProfilingMiddleware
51 from rhodecode.lib.profiler import ProfilingMiddleware
52 app = ProfilingMiddleware(app)
52 app = ProfilingMiddleware(app)
53
53
54 app = SimpleHg(app, config)
55 app = SimpleGit(app, config)
56
57 if asbool(full_stack):
54 if asbool(full_stack):
58 # Handle Python exceptions
55 # Handle Python exceptions
59 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
56 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
@@ -77,6 +74,11 b' def make_app(global_conf, full_stack=Tru'
77 app = Cascade([static_app, app])
74 app = Cascade([static_app, app])
78 app = make_gzip_middleware(app, global_conf, compress_level=1)
75 app = make_gzip_middleware(app, global_conf, compress_level=1)
79
76
77 # we want our low level middleware to get to the request ASAP. We don't
78 # need any pylons stack middleware in them
79 app = SimpleHg(app, config)
80 app = SimpleGit(app, config)
81
80 app.config = config
82 app.config = config
81
83
82 return app
84 return app
@@ -44,11 +44,11 b' class SimpleGitUploadPackHandler(dulserv'
44 get_tagged=self.get_tagged)
44 get_tagged=self.get_tagged)
45
45
46 # Do they want any objects?
46 # Do they want any objects?
47 if len(objects_iter) == 0:
47 if objects_iter is None or len(objects_iter) == 0:
48 return
48 return
49
49
50 self.progress("counting objects: %d, done.\n" % len(objects_iter))
50 self.progress("counting objects: %d, done.\n" % len(objects_iter))
51 dulserver.write_pack_data(dulserver.ProtocolFile(None, write),
51 dulserver.write_pack_objects(dulserver.ProtocolFile(None, write),
52 objects_iter, len(objects_iter))
52 objects_iter, len(objects_iter))
53 messages = []
53 messages = []
54 messages.append('thank you for using rhodecode')
54 messages.append('thank you for using rhodecode')
@@ -96,12 +96,10 b' class SimpleGit(object):'
96 def __init__(self, application, config):
96 def __init__(self, application, config):
97 self.application = application
97 self.application = application
98 self.config = config
98 self.config = config
99 #authenticate this git request using
99 # base path of repo locations
100 self.basepath = self.config['base_path']
101 #authenticate this mercurial request using authfunc
100 self.authenticate = AuthBasicAuthenticator('', authfunc)
102 self.authenticate = AuthBasicAuthenticator('', authfunc)
101 self.ipaddr = '0.0.0.0'
102 self.repo_name = None
103 self.username = None
104 self.action = None
105
103
106 def __call__(self, environ, start_response):
104 def __call__(self, environ, start_response):
107 if not is_git(environ):
105 if not is_git(environ):
@@ -109,31 +107,34 b' class SimpleGit(object):'
109
107
110 proxy_key = 'HTTP_X_REAL_IP'
108 proxy_key = 'HTTP_X_REAL_IP'
111 def_key = 'REMOTE_ADDR'
109 def_key = 'REMOTE_ADDR'
112 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
110 ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
111 username = None
113 # skip passing error to error controller
112 # skip passing error to error controller
114 environ['pylons.status_code_redirect'] = True
113 environ['pylons.status_code_redirect'] = True
115
114
116 #======================================================================
115 #======================================================================
116 # EXTRACT REPOSITORY NAME FROM ENV
117 #======================================================================
118 try:
119 repo_name = self.__get_repository(environ)
120 log.debug('Extracted repo name is %s' % repo_name)
121 except:
122 return HTTPInternalServerError()(environ, start_response)
123
124 #======================================================================
117 # GET ACTION PULL or PUSH
125 # GET ACTION PULL or PUSH
118 #======================================================================
126 #======================================================================
119 self.action = self.__get_action(environ)
127 action = self.__get_action(environ)
120 try:
121 #==================================================================
122 # GET REPOSITORY NAME
123 #==================================================================
124 self.repo_name = self.__get_repository(environ)
125 except:
126 return HTTPInternalServerError()(environ, start_response)
127
128
128 #======================================================================
129 #======================================================================
129 # CHECK ANONYMOUS PERMISSION
130 # CHECK ANONYMOUS PERMISSION
130 #======================================================================
131 #======================================================================
131 if self.action in ['pull', 'push']:
132 if action in ['pull', 'push']:
132 anonymous_user = self.__get_user('default')
133 anonymous_user = self.__get_user('default')
133 self.username = anonymous_user.username
134 username = anonymous_user.username
134 anonymous_perm = self.__check_permission(self.action,
135 anonymous_perm = self.__check_permission(action,
135 anonymous_user,
136 anonymous_user,
136 self.repo_name)
137 repo_name)
137
138
138 if anonymous_perm is not True or anonymous_user.active is False:
139 if anonymous_perm is not True or anonymous_user.active is False:
139 if anonymous_perm is not True:
140 if anonymous_perm is not True:
@@ -162,56 +163,66 b' class SimpleGit(object):'
162 # BASIC AUTH
163 # BASIC AUTH
163 #==============================================================
164 #==============================================================
164
165
165 if self.action in ['pull', 'push']:
166 if action in ['pull', 'push']:
166 username = REMOTE_USER(environ)
167 username = REMOTE_USER(environ)
167 try:
168 try:
168 user = self.__get_user(username)
169 user = self.__get_user(username)
169 self.username = user.username
170 username = user.username
170 except:
171 except:
171 log.error(traceback.format_exc())
172 log.error(traceback.format_exc())
172 return HTTPInternalServerError()(environ,
173 return HTTPInternalServerError()(environ,
173 start_response)
174 start_response)
174
175
175 #check permissions for this repository
176 #check permissions for this repository
176 perm = self.__check_permission(self.action, user,
177 perm = self.__check_permission(action, user,
177 self.repo_name)
178 repo_name)
178 if perm is not True:
179 if perm is not True:
179 return HTTPForbidden()(environ, start_response)
180 return HTTPForbidden()(environ, start_response)
180
181
181 self.extras = {'ip': self.ipaddr,
182 extras = {'ip': ipaddr,
182 'username': self.username,
183 'username': username,
183 'action': self.action,
184 'action': action,
184 'repository': self.repo_name}
185 'repository': repo_name}
185
186
186 #===================================================================
187 #===================================================================
187 # GIT REQUEST HANDLING
188 # GIT REQUEST HANDLING
188 #===================================================================
189 #===================================================================
189 self.basepath = self.config['base_path']
190
190 self.repo_path = os.path.join(self.basepath, self.repo_name)
191 repo_path = safe_str(os.path.join(self.basepath, repo_name))
191 #quick check if that dir exists...
192 log.debug('Repository path is %s' % repo_path)
192 if check_repo_fast(self.repo_name, self.basepath):
193
194 # quick check if that dir exists...
195 if check_repo_fast(repo_name, self.basepath):
193 return HTTPNotFound()(environ, start_response)
196 return HTTPNotFound()(environ, start_response)
197
194 try:
198 try:
195 app = self.__make_app()
199 #invalidate cache on push
196 except:
200 if action == 'push':
201 self.__invalidate_cache(repo_name)
202
203 app = self.__make_app(repo_name, repo_path)
204 return app(environ, start_response)
205 except Exception:
197 log.error(traceback.format_exc())
206 log.error(traceback.format_exc())
198 return HTTPInternalServerError()(environ, start_response)
207 return HTTPInternalServerError()(environ, start_response)
199
208
200 #invalidate cache on push
209 def __make_app(self, repo_name, repo_path):
201 if self.action == 'push':
210 """
202 self.__invalidate_cache(self.repo_name)
211 Make an wsgi application using dulserver
212
213 :param repo_name: name of the repository
214 :param repo_path: full path to the repository
215 """
203
216
204 return app(environ, start_response)
217 _d = {'/' + repo_name: Repo(repo_path)}
205
206 def __make_app(self):
207 _d = {'/' + self.repo_name: Repo(self.repo_path)}
208 backend = dulserver.DictBackend(_d)
218 backend = dulserver.DictBackend(_d)
209 gitserve = HTTPGitApplication(backend)
219 gitserve = HTTPGitApplication(backend)
210
220
211 return gitserve
221 return gitserve
212
222
213 def __check_permission(self, action, user, repo_name):
223 def __check_permission(self, action, user, repo_name):
214 """Checks permissions using action (push/pull) user and repository
224 """
225 Checks permissions using action (push/pull) user and repository
215 name
226 name
216
227
217 :param action: push or pull action
228 :param action: push or pull action
@@ -235,7 +246,8 b' class SimpleGit(object):'
235 return True
246 return True
236
247
237 def __get_repository(self, environ):
248 def __get_repository(self, environ):
238 """Get's repository name out of PATH_INFO header
249 """
250 Get's repository name out of PATH_INFO header
239
251
240 :param environ: environ where PATH_INFO is stored
252 :param environ: environ where PATH_INFO is stored
241 """
253 """
@@ -274,3 +286,4 b' class SimpleGit(object):'
274 invalidate the cache to see the changes right away but only for
286 invalidate the cache to see the changes right away but only for
275 push requests"""
287 push requests"""
276 invalidate_cache('get_repo_cached_%s' % repo_name)
288 invalidate_cache('get_repo_cached_%s' % repo_name)
289
General Comments 0
You need to be logged in to leave comments. Login now